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?

displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)


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

end


function draw()
    supportedOrientations(PORTRAIT)
    background(0,0,0)
    if Intro_Status == 0 then
        Intro:draw()
    else
        if Menu_Status == 0 then        
            Menu:draw()
        else
            if BattleConfig_Status == 0 then
                BattleConfig:draw()
            else
                if OnePlayerGame_Status == 0 then
                    OnePlayerGame:draw()
                end
            end
        end 
    end 
end

function touched(touch)


        Menu:touched(touch)
        BattleConfig:touched(touch)
        Intro:touched(touch)
        OnePlayerGame:touched(touch)           

end

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

Comments

  • 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
    thanks
    A.




    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[touch.id] = nil else -- If the touch is in any other state -- (such as BEGAN) we add it to our -- table touches[touch.id] = 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 = t.id self.touchStart = pos self.stickOffset = vec2(0, 0) self.pressedCallback() elseif t.id == 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

    @deactive

    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 b.id == 0 then --this cycles through, looking for a table value with b.id = t.id --an id of 0. if found, it uses that one because the b.sx = t.x --table slot isnt currently being used. if all slots b.cx = t.x --are in use, it creates a new table slot using 'aa' b.sy = t.y --as the boolean control for that condition. b.cy = t.y --s stands for start; c stands for current --example: b.sx = b.start x b.side = 0 if b.sx > 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 b.sx < 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.id,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 self.id = id self.sx,self.cx = x,x self.sy,self.cy = y,y end function NewTouch:touched(t) if t.id == self.id then if t.state == MOVING then if self.sx > WIDTH/2 then --how to control things on the right of the screen... self.cx, self.cy = t.x,t.y if self.cx < WIDTH/2 then self.cx = WIDTH/2 end -- ellipse(self.cx,self.cy,5) local dist = math.sqrt(math.pow((self.cx - self.sx),2) + math.pow(self.cy - self.sy,2)) while dist > 100 do --binds the controller to the outer ring of the joystick if self.cx-self.sx > 0 then self.cx = self.cx * .99 end if self.cx-self.sx < 0 then self.cx = self.cx * 1.01 end if self.cy-self.sy > 0 then self.cy = self.cy * .99 end if self.cy-self.sy < 0 then self.cy = self.cy * 1.01 end dist = math.sqrt(math.pow((self.cx - self.sx),2) + math.pow(self.cy - self.sy,2)) end ball:applyForce(vec2((self.cx-self.sx)*1/2, (self.cy-self.sy)*1/2)) end end if t.state == ENDED then --resets id to 0 self.id = 0 end end end function NewTouch:draw() if self.id > 0 then --draws image of Cat girl if the start value of the touch is if self.sx < WIDTH/2 then --on the left of the screen sprite("Planet Cute:Character Cat Girl", self.sx,self.sy) end if self.sx > WIDTH/2 then --draws joystick if startX is on the right noFill() strokeWidth(5) stroke(51, 255, 0, 255) ellipse(self.sx,self.sy,200) sprite("Cargo Bot:Star Filled",self.cx,self.cy) 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 https://github.com/npryce/codea-controllers

Sign In or Register to comment.