Issues with Multi-Touch

So I’ve been playing around with a simple platformer prototype, but I’ve run into a bit of an issue. Using the button class from @Reefwing’s MoveShip example, I’ve created a control pad with an added Jump button. The problem arises when two spots on the screen are pressed at the same time. If I hold a directional button, the character will run, but as soon as I press the jump button, the run command is stopped and the Jump command is executed. The run command is re-initiated if I slide my finger around on the button, but I wonder, is there a way to trigger two buttons at once?

I’ve added a print(“Touch Ended”) command to see if my first touch is being cancelled, but it’s not. It’s like Codea is losing interest in the first touch.

Any advice on handling multiple touches would be greatly appreciated.

And yes, I’ve combed over the Multitouch example in vain.

You have to remember the id of each active touch until it is ended or cancelled. For each touch event, you have to control the id to understand which finger the event is related to. I posted an example on the forum some months ago.

Here is a small example showing a display for multitouch. The problem with this is the ID isn’t saved in the table as the real ID number. It’s saved as scientific notation (6-7 digits) whereas the real ID value is a 9 digit number. Why is the ID number so big. Moving multiple fingers on the screen will show information for the different touch results.


supportedOrientations(PORTRAIT)
displayMode(FULLSCREEN)

function setup()
    mt={}
end

function draw()
    background(40, 40, 50)
    fontSize(12)
    textMode(CORNER)
    text("ID                           STATE                   X            Y",100,1000)    
    fill(255)
    for z=1,#mt do
        text(mt[z].z,60,1000-15*z)    -- touch id
        
        if mt[z].a==0 then
            str="BEGAN"
        elseif mt[z].a==1 then
            str="MOVING"
        elseif mt[z].a==2 then
            str="ENDED"
        else
            str="UNKNOWN"
        end
        text(str,200,1000-15*z)     -- touch state
        
        text(mt[z].x,300,1000-15*z)    -- touch x
        text(mt[z].y,350,1000-15*z)    -- touch y
    end     
end

function touched(t)
    for z=1,#mt do
        if t.id==mt[z].z then    -- id already in table
            mt[z]=vec4(t.x,t.y,t.id,t.state) -- update entries             
            return
        end
    end
    -- no match, add entry to table
    table.insert(mt,vec4(t.x,t.y,t.id,t.state))
end

I figured out how to use the 9 digit ID without the scientific notation. Here is an updated version of the above program. Just drag multiple fingers on the screen to display touch information.


supportedOrientations(PORTRAIT)
displayMode(FULLSCREEN)

function setup()
    mt={}
end

function draw()
    background(40, 40, 50)
    fontSize(16)
    font("Courier")
    textMode(CORNER)
    fill(255)
    text("    ID       STATUS   X    Y",50,1000)
    for z=1,#mt do
        text(mt[z],50,1000-18*z)
    end
end

function touched(t)
    if t.state==BEGAN then
        ts="BEGAN"
    elseif t.state==MOVING then
        ts="MOVING"
    elseif t.state==ENDED then
        ts="ENDED"
    else
        ts="UNKNOWN"
    end
    str=string.format("%10.0f",t.id)
    str1=string.format("%10.0f %8s %4d %4d",t.id,ts,t.x,t.y)               
    for z=1,#mt do
        if string.match(mt[z],str) ~= nil then
            mt[z]=str1
            return
        end
    end
    table.insert(mt,str1)
end

@Dave1707, your code seems to be able to keep track of multiple touches at once, so I think it may be on the right track. I’ll definitely have to comb over it tonight after work to figure out how to implement it. Thank you very much for your help :slight_smile:

I have a general touch handler to keep track of this sort of thing. You can read about it at http://loopspace.mathforge.org/discussion/10/touch-tutorial

@VonClossen This example might make it easier to understand how to keep track of multiple touches. I tried to keep it as simple as possible and still give you a good example. Use one finger and touch (BEGAN) each button to move the ball in that direction. Lift your finger (ENDED) to stop the ball. Drag your finger over each button (MOVING) to move the ball in that direction. Then do the same thing with two fingers to move the ball in multiple directions at the same time.


supportedOrientations(PORTRAIT)
displayMode(FULLSCREEN)

function setup()
    btab={0,0,0,0}    -- 4 buttons 
    
    vtab={}    -- x,y position of oval buttons
    vtab[1]=vec2(250,200)
    vtab[2]=vec2(450,200)  
    vtab[3]=vec2(250,300)
    vtab[4]=vec2(450,300) 
    
    name={"DOWN","RIGHT","UP","LEFT"}  -- names for oval buttons
          
    bx=350; by=700    -- initial ball x,y position
    ox=180; oy=80    -- oval size, x-axis,y-axis  
end

function draw()
    background(40, 40, 50)
    
    fill(255)
    for z=1,4 do    -- draw 4 buttons and thier names
        fill(255)
        ellipse(vtab[z].x,vtab[z].y,ox,oy)
        fill(255,0,0)
        text(name[z],vtab[z].x,vtab[z].y)  
    end
    
    ballMove()    -- get position for ball
    ellipse(bx,by,50,50)    -- draw ball
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING  then
        for z=1,4 do    -- check all 4 buttons
            -- is a button being touched, if yes
            if (t.x-vtab[z].x)^2/(ox/2)^2+(t.y-vtab[z].y)^2/(oy/2)^2 <= 1 then 
                btab[z]=t.id    -- button being touched, set touch id
            end
        end
    end
    
    if t.state==MOVING then
        for z=1,4 do    -- check all 4 buttons
            if btab[z]==t.id then    -- does touch id match button, if yes
                -- is button being touched, if no
                if (t.x-vtab[z].x)^2/(ox/2)^2+(t.y-vtab[z].y)^2/(oy/2)^2 > 1 then 
                    btab[z]=0    -- button isn't being touched, clear id
                end
            end
        end
    end         
            
    if t.state==ENDED then
        for z=1,4 do    -- check all 4 buttons
            if btab[z]==t.id then    -- does touch id match button, if yes
                btab[z]=0    -- set the button id to 0
            end
        end
    end 
end

function ballMove()
    -- move ball depending on which button is being pressed
    if btab[1]>0 then
        by = by - 1
    end
    if btab[2]>0 then
        bx = bx + 1
    end
    if btab[3]>0 then
        by = by + 1
    end
    if btab[4]>0 then
        bx = bx - 1
    end    
end

@Dave1707, I just reviewed your code and it seems so much simpler than I originally thought! It hadn’t even crossed my mind to use tables to register multiple touches.

I feel so foolish :stuck_out_tongue_winking_eye: thank you so much for your help :smiley: