Quick Links: Download Gideros Studio | Gideros Documentation | Ultimate Guide | Gideros Development Center
Virtual onscreen controls/gamepad - does anybody want to share theirs? - Gideros Forum

Virtual onscreen controls/gamepad - does anybody want to share theirs?

snooks Member
edited November 26 in General questions
I am wondering before I start, whether anybody has a nice onscreen controls class in order to minimise wheel-reinvention? :)


  • totebototebo Member
    edited November 26
    In my case I have made five games on mobile, and have five different implementations. I treat it as UI, and how it looks and works depends on the game. I suppose a gamepad could be more generic, I have one of those in Fast Food Rampage. But it's quite specific to that game in that you can fire burgers OR milkshakes on the right hand side. So not very generic either. :(

    Sorry, that's not very helpful! :D

    Aye: antix

    +1 -1 (+1 / -0 )
  • @snooks, what kind of control are you looking for? There are many kinds and not all could be rolled into one class without making that some ugly spaghetti code :bz
    +1 -1
  • Virtual Joypad should be included in the Gideros Source code, we have permission to include it. Perhaps it can be one of the first Lua Plugins @hgy29 ?

    Aye: Apollo14

    +1 -1 (+1 / -0 )
  • @antix - that should be in the Gideros distribution now. Hopefully a Lua 'plugin' soon.

    Aye: Apollo14, antix

    +1 -1 (+2 / -0 )
  • Very good points re them all being different, I was just looking for a fast fix to test with. Good idea including one with Gideros.

    I like the joysticks that appear when you touch the screen, so I've just made one of those....


    Aye: Apollo14

    +1 -1 (+1 / -0 )
  • antixantix Member
    edited November 27
    @snooks, that's pretty cool man. I messed about with it a bit...
    - You set the default options in init and just copy over any specified user options (if any).
    - Limits knob so it never goes past radius of main pad (looks nicer?).
    - Can pass in code that gets run on pressed, dragged, and released.
    - Doesn't add and remove listeners constantly, instead has an "enabled" bool.
    - Can now specify if the joypad should be on left or right side of screen.
    - Can supply colors for joypad.
    -- VirtualRelativeJoystick for Gideros
    -- Onscreen joystick that only appears when lower left quadrant
    -- of screen is touched
    VirtualRelativeJoystick = Core.class(Sprite)
    function VirtualRelativeJoystick:init(options)
    -- default options
    self.x = 100
    self.y = 100
    self.outerRadius = 100
    self.padColor = 0xaaaadd
    self.knobColor = 0xaaddaa
    self.onPressed = nil
    self.onDragged = nil
    self.onReleased = nil
    self.left = false
    self.xpos = 0
    self.ypos = 0
    self.strength = 0
    self.angle = 0
    self.enabled = false
    -- set user supplied options
    if options then
    for key, value in pairs(options) do
    self[key]= value
    self.outerCircle = self:getNewCircle(self.outerRadius, self.padColor, false)
    self.innerNubbin = self:getNewCircle(self.outerRadius * .5, self.knobColor, true)
    self:setPosition(self.x, self.y)
    self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
    self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
    self:addEventListener(Event.TOUCHES_END, self.onTouchesEnd, self)
    function VirtualRelativeJoystick:onTouchesCancel(e)
    function VirtualRelativeJoystick:onTouchesBegin(e)
    local tx, ty = e.touch.x, e.touch.y
    local mx, my = application:getContentWidth() * 0.5, application:getContentHeight() * 0.5
    if self.left then
    if tx > mx or ty < my then return end
    if tx < mx or ty < my then return end
    self.controlTouchId = e.touch.id
    self:setPosition(tx, ty)
    self.enabled = true -- enable control
    if self.onPressed then
    end -- run code
    function VirtualRelativeJoystick:onTouchesMove(e)
    local cos, sin, sqrt, atan2 = math.cos, math.sin, math.sqrt, math.atan2
    if not self.enabled then return end
    if e.touch.id == self.controlTouchId then
    local x, y = self:globalToLocal(e.touch.x, e.touch.y)
    local radius = self.outerRadius
    local distance = sqrt(x * x + y * y) >< radius -- limit distance to outer radius
    -- normalized strength for use with angle
    local strength = (distance >< radius) / radius
    local angle = ^>atan2(y, x) + 90
    local ra = ^< self.angle
    y = -distance * cos(ra)
    x = distance * sin(ra)
    self.innerNubbin:setPosition(x, y)
    self.xpos, self.ypos = x / radius, -y / radius
    if self.onPressed then
    self.onDragged(angle, distance, strength) -- run code
    self.angle, self.distance, self.strength = angle, distance, strength
    function VirtualRelativeJoystick:onTouchesEnd(e)
    if not self.enabled then return end
    if e.touch.id == self.controlTouchId then
    self.innerNubbin:setPosition(0, 0)
    self.xpos, self.ypos = 0, 0
    self.enabled = false
    if self.onReleased then
    self.onReleased() -- run code
    self.controlTouchId = nil
    function VirtualRelativeJoystick:getNewCircle(r, color, fill)
    local p = Path2D.new()
    p:setSvgPath(("M %s 0 a %s %s 0 0 0 %s 0 a %s %s 0 0 0 %s 0 Z"):format(-r, r, r, 2 * r, r, r, -2 * r))
    p:setLineThickness(10) -- Outline width
    p:setFillColor(color, fill and .6 or .0) --Fill color
    p:setLineColor(color, .6) --Line color
    return p

    Aye: snooks

    +1 -1 (+1 / -0 )
  • Nice, thanks for enhancing it! I did have it limited at the radius, but it only works when using angle/strength and I'm using xpos/ypos for my game. But limiting to radius for angle/strength is perfect.

    Aye: antix

    +1 -1 (+1 / -0 )
Sign In or Register to comment.