Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Another multi touch related issue

edited July 2014 in Questions Posts: 127

Hello guys,

I think I have a Lua coding issue here, but I seem to be unable to handle multi touch so that a Joystick appears when touching the right side of the stage, and button(s) on the left ( or viceversa ) at very same time.
This is what my Main currently looks like, and with regards to the buttons I've placed over my classes all worked fine so far. However I need to handle multi touch so that One_Player_Game will display virtual joy plus button.
Just to let you have a clearer scenario, with single touch I've no issues displaying virtual joy or button, thou I can't make them showing up meantime. How would touch function look like in my One_Player_Game class?


function setup()
    touches = {}
    Intro = Intro()
    Menu = Menu(WIDTH/2,HEIGHT/2)
    BattleConfig = BattleConfig()
    OnePlayerGame = One_Player_Game()


function draw()
    if Intro_Status == 0 then
        if Menu_Status == 0 then        
            if BattleConfig_Status == 0 then
                if OnePlayerGame_Status == 0 then

function touched(touch)



If anyone could help, he would make me a happy lad :)
Thanks a lot


  • Posts: 134

    Can I see your full code and make some modifications to make it function properly?

  • Posts: 82

    If you need an example of how to handle multiple touches properly, there's an excellent one under 'Example Projects' in Codea.

  • Posts: 127

    Hi @Invad3rZIM, thanks for your availability.
    The code I'm posting here does not strictly relate to the game I originally asked help for, but it pretty sums up the same issue in a bunch only of classes.

    I'd need to make the VirtualButton sprite to show up when the virtual stick is in movement.
    If there's better approach ( and I'm sure there is ) please give me some guide lines :)
    Any help will be appreciated

    function setup() print("This example tracks multiple touches and colors them based on their ID") -- keep track of our touches in this table touches = {} pos = vec2(WIDTH/2, 300) steer = vec2(0,0) speed = 400 controller = VirtualStick { moved = function(v) steer = v end, released = function(v) steer = vec2(0,0) end } end -- This function gets called whenever a touch -- begins or changes state function touched(touch) if touch.state == ENDED then -- When any touch ends, remove it from -- our table touches[] = nil else -- If the touch is in any other state -- (such as BEGAN) we add it to our -- table touches[] = touch controller:activate() end end function draw() background(0, 0, 0, 255) for k,touch in pairs(touches) do controller:draw() end end -- Base class for controllers -- -- Controllers translate touch events into callbacks to functions -- that do something in the app. (Model/View/Controller style). -- -- Controllers can draw a representation of their current state on -- the screen, but you can choose not to. -- -- A controller can be installed as the global handler for touch -- events by calling its activate() method Controller = class() function Controller:activate() touched = function(t) self:touched(t) end end function Controller:draw() -- nothing end -- Utility functions function touchPos(t) return vec2(t.x, t.y) end function clamp(x, min, max) return math.max(min, math.min(max, x)) end function clampAbs(x, maxAbs) return clamp(x, -maxAbs, maxAbs) end function clampLen(vec, maxLen) if vec == vec2(0,0) then return vec else return vec:normalize() * math.min(vec:len(), maxLen) end end -- projects v onto the direction represented by the given unit vector function project(v, unit) return v:dot(unit) end function sign(x) if x == 0 then return 0 elseif x < 0 then return -1 elseif x > 0 then return 1 else return x -- x is NaN end end function doNothing() end -- A virtual analogue joystick with a dead-zone at the center, -- which activates wherever the user touches their finger -- -- Arguments: -- radius - radius of the stick (default = 100) -- deadZoneRadius - radius of the stick's dead zone (default = 25) -- moved(v) - Called when the stick is moved -- v : vec2 - in the range vec2(-1,-1) and vec2(1,1) -- pressed() - Called when the user starts using the stick (optional) -- released() - Called when the user releases the stick (optional) VirtualStick = class(Controller) function VirtualStick:init(args) self.radius = args.radius or 100 self.deadZoneRadius = args.deadZoneRadius or 25 self.releasedCallback = args.released or doNothing self.steerCallback = args.moved or doNothing self.pressedCallback = args.pressed or doNothing end function VirtualStick:touched(t) local pos = touchPos(t) if t.state == BEGAN and self.touchId == nil then self.touchId = self.touchStart = pos self.stickOffset = vec2(0, 0) self.pressedCallback() elseif == self.touchId then if t.state == MOVING then self.stickOffset = clampLen(pos - self.touchStart, self.radius) self.steerCallback(self:vector()) elseif t.state == ENDED or t.state == CANCELLED then self:reset() self.releasedCallback() end end end function VirtualStick:vector() local stickRange = self.radius - self.deadZoneRadius local stickAmount = math.max(self.stickOffset:len() - self.deadZoneRadius, 0) local stickDirection = self.stickOffset:normalize() return stickDirection * (stickAmount/stickRange) end function VirtualStick:reset() self.touchId = nil self.touchStart = nil self.stickOffset = nil end function VirtualStick:draw() if self.touchId ~= nil then pushStyle() ellipseMode(RADIUS) strokeWidth(1) stroke(255, 255, 255, 255) noFill() pushMatrix() translate(self.touchStart.x, self.touchStart.y) ellipse(0, 0, self.radius, self.radius) ellipse(0, 0, self.deadZoneRadius, self.deadZoneRadius) translate(self.stickOffset.x, self.stickOffset.y) --ellipse(0, 0, 25, 25) tint(255,255,255,180) sprite("Cargo Bot:Star Filled",0,0,130) popMatrix() popStyle() end end VirtualButton = class() function VirtualButton:init(x,y) self.x = x self.y = y end function VirtualButton:draw() pushStyle() pushMatrix() sprite("Cargo Bot:Star", self.x,self.y) popStyle() popMatrix() end
  • edited July 2014 Posts: 134

    Lemme see what I can do ^.^ gimme a good hour and I'll get back to you mr deactive

    Edit: finished first part let me now just make a sprite show up where you press the left part of the screen

  • edited July 2014 Posts: 134


    Okay here's some sample code I made up to demonstrate:

    1) controlling both parts of the screen
    2) implementing multiple touches
    3) a simple virtual joystick I like to use that gets the job done and is much less effort ^.^

    I used a physics ball as a medium to demonstrate touch control

    function setup() touches = {} -- table of touches, used to store touch id and their coords ball = physics.body(CIRCLE, 45) ball.gravityScale = 0 ball.x, ball.y = WIDTH/2, HEIGHT/2 r = 100 g = 100 b = 100 end -- This function gets called whenever a touch -- begins or changes state function touched(t) if t.state == BEGAN then aa = 0 for a,b in pairs(touches) do --every time a touch is ended, its id is reset to 0 if == 0 then --this cycles through, looking for a table value with = --an id of 0. if found, it uses that one because the = t.x --table slot isnt currently being used. if all slots = t.x --are in use, it creates a new table slot using 'aa' = t.y --as the boolean control for that condition. = t.y --s stands for start; c stands for current --example: = b.start x b.side = 0 if > WIDTH/2 then --side can be used to track which side of the b.side = 1 --screen the touch is from like so end if < WIDTH/2 then --every time a touch is began on the left side, --rgb values of the ball are randomised r = math.random(255) g = math.random(255) b = math.random(255) end aa = 1 end end if aa == 0 then --see above for explanation on aa table.insert(touches, NewTouch(,t.x,t.y)) end end if t.state == MOVING or t.state == ENDED then for a,b in pairs(touches) do b:touched(t) end end end function draw() background(0, 0, 0, 255) for a,b in pairs(touches) do b:draw() end fill(color(r,g,b)) noStroke() ellipse(ball.x,ball.y,ball.radius*2) end NewTouch = class() function NewTouch:init(id,x,y) --initialises values = id, = x,x, = y,y end function NewTouch:touched(t) if == then if t.state == MOVING then if > WIDTH/2 then --how to control things on the right of the screen..., = t.x,t.y if < WIDTH/2 then = WIDTH/2 end -- ellipse(,,5) local dist = math.sqrt(math.pow(( -,2) + math.pow( -,2)) while dist > 100 do --binds the controller to the outer ring of the joystick if > 0 then = * .99 end if < 0 then = * 1.01 end if > 0 then = * .99 end if < 0 then = * 1.01 end dist = math.sqrt(math.pow(( -,2) + math.pow( -,2)) end ball:applyForce(vec2((*1/2, (*1/2)) end end if t.state == ENDED then --resets id to 0 = 0 end end end function NewTouch:draw() if > 0 then --draws image of Cat girl if the start value of the touch is if < WIDTH/2 then --on the left of the screen sprite("Planet Cute:Character Cat Girl",, end if > WIDTH/2 then --draws joystick if startX is on the right noFill() strokeWidth(5) stroke(51, 255, 0, 255) ellipse(,,200) sprite("Cargo Bot:Star Filled",, end end end

    Tried to use meaningful variable names and support them with good, detailed explanations. Let me know if you have any further questions.

  • Posts: 127

    Hi @Invad3rZIM, thank to your effort I clearly got how multi touch works.
    However I eventually used the classes at this URL

Sign In or Register to comment.