Assumes that each pad is manipulated by at max a single pointer.
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
core :: Object :: defaultinit
gamnit :: DPad :: defaultinit
gamnit :: RoundControl :: defaultinit
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
core :: Object :: output_class_name
Display class name on stdout (debug only).gamnit :: RoundControl :: radius
Radius in UI units/pixels of the part of this control
# Directional pad with up to 4 buttons
#
# Assumes that each pad is manipulated by at max a single pointer.
class DPad
super RoundControl
# Event names for the keys, in order of top, left, down and right
var names: Array[String]
# Show the up button
var show_up = true is writable
# Show the down button
var show_down = true is writable
# Show the left button
var show_left = true is writable
# Show the right button
var show_right = true is writable
redef fun radius do return 200.0
redef fun contains(ui_pos)
do
if show_down then return super(new Point[Float](ui_pos.x+0.0, ui_pos.y-100.0))
return super
end
redef fun hit(event, ui_pos)
do
var display = app.display
if display == null then return false
var dx = ui_pos.x - center.x
var dy = ui_pos.y - center.y
if show_down then dy -= 100.0
# Angle (with 0.0 on the right) to index in WASD (0 -> W/up)
var indexes = new Set[Int]
var ao = atan2(dy, dx)
ao -= pi/4.0
# Look for 2 angles so 2 buttons can be pressed at the same time
for da in once [-pi/8.0, pi/8.0] do
var a = ao+da
while a < 0.0 do a += pi*2.0
while a > 2.0*pi do a -= pi*2.0
var index = (a * 2.0 / pi).floor.to_i
if index < 0 then index += 4
indexes.add index
end
var shows = [show_up, show_left, show_down, show_right]
var new_down_names = new Set[String]
for index in indexes do
# Don't trigger events for hidden buttons/directions
if not shows[index] then continue
var name = names[index]
# Simulate event
var e = new VirtualGamepadEvent(name)
e.is_down = event.pressed
app.accept_event e
if event.pressed then new_down_names.add name
end
# Depress released directions
for name in down_names do
if not new_down_names.has(name) then
var e = new VirtualGamepadEvent(name)
e.is_down = false
app.accept_event e
end
end
down_names = new_down_names
return true
end
redef fun sprites
do
var dy = 0.0
if show_down then dy = 100.0
var sprites = new Array[Sprite]
# Interactive buttons
if show_up then sprites.add new Sprite(app.gamepad_spritesheet.dpad_up,
center.offset( 0.0, 100.0+dy, 0.0))
if show_left then sprites.add new Sprite(app.gamepad_spritesheet.dpad_left,
center.offset(-100.0, 0.0+dy, 0.0))
if show_right then sprites.add new Sprite(app.gamepad_spritesheet.dpad_right,
center.offset( 100.0, 0.0+dy, 0.0))
if show_down then sprites.add new Sprite(app.gamepad_spritesheet.dpad_down,
center.offset( 0.0,-100.0+dy, 0.0))
# Non-interactive joystick background
var back = new Sprite(app.gamepad_spritesheet.joystick_back,
center.offset(0.0, 0.0+dy, -1.0)) # In the back
back.draw_order = -1
sprites.add back
# Non-interactive handle in the bottom
if not show_down then sprites.add new Sprite(app.gamepad_spritesheet.joystick_down,
center.offset(0.0, -100.0+dy, 0.0))
return sprites
end
end
lib/gamnit/virtual_gamepad/virtual_gamepad.nit:314,1--425,3