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
… @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.