Please help - Touch

Hello,
I’m very new to codea and at the moment I’m trying to understand how the touch verbs work.
For the most part I’ve been using currentTouch and I was wondering if there was another way of doing it.
I was wondering if someone could please explain to me how I could make the algorithm know if the user was to touch an ellipse for example.
Thanks, Ilan

@ilankess

Using CurrentTouch, you would use CurrentTouch.x and CurrentTouch.y to determine the x,y coordinates where the screen was touched. To determine if an ellipse was touched, you would have to calculate if the returned x,y value was within the bounds of the ellipse. That can be done, but beyond what I want to get into right now. An easier use would be to determine if a square or rectangle was touched. For example, if CurrentTouch.x was greater than the left value and less than the right value, and CurrentTouch.y was greater than the bottom value and less than the top value of the rectangle, then the rectangle was touched. Here is a small example. Touch the rectangle, then touch elsewhere.


function setup()
end

function draw()
    background(40, 40, 50)
    
    fill(255)
    rect(100,400,200,50)
    
    if CurrentTouch.x > 100 and CurrentTouch.x < 300
        and CurrentTouch.y > 400 and CurrentTouch.y < 450 then
            fill(255,0,0)
            text("rectangle touched",200,425)
    end
end

@ilankess

Here is an example for the ellipse. Touch inside then outside the ellipse.


function setup()
end

function draw()
    background(40, 40, 50)
    
    fill(255)
    ellipse(200,400, 200,100)
    
    x=CurrentTouch.x
    y=CurrentTouch.y
    
    if (y-400)^2/50^2+(x-200)^2/100^2 <= 1 then
        fill(255,0,0)
        text("inside",200,400)
    end
end

Thanks @dave1708
Really helpful
But why does this work, (y-400)^2/50^2+(x-200)^2/100^2 <=???
(why does it represent that areas coordinates?)
Thanks :smiley:

@ilankess

That’s derived from the formula for an ellipse (x/a)^2+(y/b)^2=1. Any x,y value that results in a value of 1 will be on the edge of the ellipse. Any x,y value less that 1 will be inside the ellipse. Any x,y value greater than 1 will be outside the ellipse.

Here is the previous program, but it allows you to change the size and position of the ellipse. Change the a and b values to create different size ellipses. Change the xc and yc values to move the center of the ellipse.


function setup()
end

function draw()
    background(40, 40, 50)
    
    a=200     -- length along x axis, center to edge  
    b=100     -- length along y axis, center to edge
    
    xc=250    -- center of ellipse x axis
    yc=400    -- center of ellipse y axis
    
    fill(255)
    ellipse(xc,yc,a*2,b*2)    -- draw ellipse
    
    x=CurrentTouch.x    -- touched x value
    y=CurrentTouch.y    -- touched y value
    
    -- determine if touched value is inside ellipse
    if (y-yc)^2/b^2+(x-xc)^2/a^2 <= 1 then
        fill(255,0,0)
        text("inside",xc,yc)
    end
end

Pure brilliance. Thank you so much!

@ilankess

I don’t like all the coordinate calculations: this will be very tedious specially if there are many objects you want to touch

I would rather use the physics API that manages the contact events. I wrote the following exemple for you. It seems long but it is mainly because i have put a lot of comments. Try it and let me know what you think.

-- easy touch management

function setup() 

    -- create object 1 : this will track your finger position
    -- create this object first, then all the others (simpler for collision management)
    c1 = physics.body(CIRCLE,50)    -- a circle of radius 50 is your (big) finger 
    c1.type=DYNAMIC -- needed otherwise will no collide with objects
    c1.x=-100 -- initial position: out of the image (hidden)
    c1.y=-100
    c1.sensor = true -- say this object will be just a sensor, not a real object
    c1.gravityScale = 0 -- otherwise the object will fall in the image!

    -- now create the objects you want to detect with your touch
    c2 = physics.body(CIRCLE,50)    -- for example a circle
    c2.type=STATIC    -- define it static if it will not move
    c2.x=WIDTH/3    -- put it where you want in the image
    c2.y=HEIGHT/2
    c2.info = {}    -- info a is table for the user; first initialize it to {}
    c2.info.name = "object 1" -- then store whatever you want in it
    
    -- now let's create a second object
    c3 = physics.body(CIRCLE,50)   
    c3.type=STATIC
    c3.x=WIDTH/3*2
    c3.y=HEIGHT/2
    c3.info = {}
    c3.info.name = "object 2"

end

-- this function capture the touch events
function touched(touch)
    if touch.state == BEGAN then
        -- when a touch start put the object c1 (the touch sensor) there
        c1.x = touch.x
        c1.y = touch.y
    end
    if touch.state == ENDED then
        -- when the touch stops, hide the sensor away
        c1.x = -100
        c1.y = -100
    end   
end

-- this function detects when an object is touched by the touch sensor
function collide(contact)
    if contact.state == BEGAN then
        sound(SOUND_HIT, 2652) -- the sound is just for fun
        -- here we detect the touched object name
        myObjectName = contact.bodyB.info.name
        -- the object will always be bodyB, 
        -- because the touch sensor was declared before all others

        -- i print its name but you can do whatever you want with it
        print(myObjectName) 
    end   
end

function draw()
 
    background(30, 30, 30, 25)
    
    -- all the objects defined exist but are invisible: draw something on them to see them!
    
    stroke(255)
    strokeWidth(1)
    -- draw the sensor
    fill(255, 0, 7, 255)
    ellipse(c1.x,c1.y,100,100)    -- draw a circle that coencides with the sensor
    
    fill(0, 72, 255, 145)
    ellipse(c2.x,c2.y,100,100)    -- draw the 1st circle
    fill(255)
    fontSize(20)
    text(c2.info.name,c2.x,c2.y)   -- write its name in the circle
    
    fill(255, 222, 0, 143)
    ellipse(c3.x,c3.y,100,100)    -- draw the 2nd circle    
    fill(0)
    text(c3.info.name,c3.x,c3.y)   -- write its name in the circle
end

@Jmv38

If all you’re after is to detect if an object is touched, here is an example that displays 50 white balls. When you touch them, they’ll turn red. The amount of code needed to check if 1 or 50 of the balls is touched is the same. There could be 500 balls and the only thing that needs to change is the count value.


function setup()
    displayMode(FULLSCREEN)
    count=50
    
    circ={}  -- table for x,y coordinates
    colr={}  -- table for color
    
    for x=1,count do
        circ[x]=vec2(math.random(50,WIDTH-50),math.random(50,HEIGHT-50))
        colr[x]=vec3(255,255,255)
    end
end

function draw()
    background(40, 40, 50)
    
    x=CurrentTouch.x    -- touched x value
    y=CurrentTouch.y    -- touched y value 
    
    for x1=1,count do
        xc=circ[x1].x  -- get x,y coordinates
        yc=circ[x1].y
        
        c=colr[x1]  -- get color
        c=fill(color(c.x,c.y,c.z))

        ellipse(xc,yc,40,40)
        
        -- check if object is touched
        if (y-yc)^2/20^2+(x-xc)^2/20^2 <= 1 then
            colr[x1]=vec3(255,0,0)  -- change color to red
        end  
    end
end

@dave1707 you are right if all the objects are identical. But if they have different size and shapes, it can become complex. Wait, hummm… on the other hand, it should be easy to design a class for each object that include a self check function. Deuce. I guess i simply don’t like the idea to check all the objects in lua, cause i expect it to consume computing power and FPS. If the Objectve C of the physics API does the job, it should be faster?

By the way, there is a flaw in my program above: woks fine whens there are just touches, but if i press and slide my finger, then the touch or collide seems blocked until i touch another object (touches on the same object are not printed)…

@Jmv38, sorry for the late reply but looking at it now I am quite interested by your post.
I am very new to lua and have only written 2 small apps in codea with the knowledge i have.
If you wouldnt mind answering a couple of my questions that would be greatly appreciated… (sorry if i sound like an idiot)

  1. what is physics.body?
  2. i am not familiar with this type of assignment c1.type = DYNAMIC, c1.gravityScale = 0 (are they different aspects of c1? what do they do/mean?)
    3)what does touch.state, BEGAN and ENDED refer to
    looks like ive got alot of studying to do :stuck_out_tongue:
    thanks in advance
    Ilan

@ilankess, If you want to learn more about Codea’s physics classes, my suggestion whould be to review the Codea Reference. It’s available from inside Codea when you select the Getting Started icon. There’s a complete Physics section, which explains the functions and constants you’re asking about.


@jmv38, Thanks for sharing your touch detection solution with us noobs. Your well-commented code was easy for me to follow. I really like the collision-detection method and will try to incorporate it in my projects.