Howdy, Stranger!

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

Please help - Touch

edited August 2012 in General Posts: 9

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

Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 7,805

    @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
  • dave1707dave1707 Mod
    Posts: 7,805

    @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 :D

  • dave1707dave1707 Mod
    Posts: 7,805

    @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!

  • Jmv38Jmv38 Mod
    Posts: 3,295

    @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
    
    
  • dave1707dave1707 Mod
    Posts: 7,805

    @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
  • Jmv38Jmv38 Mod
    Posts: 3,295

    @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 :p
    thanks in advance
    Ilan

  • edited September 2012 Posts: 140

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

Sign In or Register to comment.