Howdy, Stranger!

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

In this Discussion

checking touched area using physics.body

edited April 2012 in Questions Posts: 15

Hi,

im new to this forum, and have played with Codea for only a few days now. Im trying to make a simple touch-controller class to decide the direction of movement in a game.

My approach is to divied the whole screen into four triangles. when the touch position is within the upper triangle, i set a variable "up" to true, similar for left, right and down..

To determine which triangle has been touched i decided to go with the physics api because of the nice collision checks.

However, the check works only when the game is freshly started. After a few seconds the collision checks start failing. Im already printing the triangles to check if they somehow move automagically, but everything seems ok.

It would be nice if someone can give any hint, thanks in advance.

here's the code of the controller class:

Controller = class()

function Controller:init()
    
    self.ptTopLeft = vec2(0, HEIGHT)
    self.ptTopRight = vec2(WIDTH, HEIGHT)
    self.ptBtLeft = vec2(0,0)
    self.ptBtRight = vec2(WIDTH, 0)
    self.ptCenter = vec2(WIDTH/2, HEIGHT/2)
    
    self.areaTop = physics.body(POLYGON, unpack({self.ptTopLeft, self.ptTopRight, self.ptCenter}))
    self.areaBottom = physics.body(POLYGON, unpack({self.ptBtLeft, self.ptBtRight, self.ptCenter}))
    self.areaLeft = physics.body(POLYGON, unpack({self.ptBtLeft, self.ptTopLeft, self.ptCenter}))
    self.areaRight = physics.body(POLYGON, unpack({self.ptBtRight, self.ptTopRight, self.ptCenter}))
    
    self.left = false
    self.right = false
    self.up = false
    self.down = false
    
    --local poly = physics.body(POLYGON, unpack(points))
    
end

function Controller:touched(touch)
    local touchVec
    touchVec = vec2(touch.x, touch.y)
    print(touch.state)
    if(touch.state == ENDED) then 
        self.up = false
        self.down = false
        self.left = false
        self.right = false
    elseif (self.areaTop:testPoint(touchVec) == true) then
        self.up = true
    elseif (self.areaBottom:testPoint(touchVec) == true) then
        self.down = true
    elseif (self.areaLeft:testPoint(touchVec) == true) then
        self.left = true
    elseif (self.areaRight:testPoint(touchVec) == true) then
        self.right = true
    end
end 

function Controller:draw()
    drawBody(self.areaRight)
    drawBody(self.areaLeft)
end

function drawBody(body)
    pushStyle()
    stroke(255, 0, 0, 255)
    strokeWidth(7)
    local points = body.points
        for j = 1,#points do
            a = points[j]
            b = points[(j % #points)+1]
            line(a.x, a.y, b.x, b.y)
        end
    popStyle()
end
Tagged:

Comments

  • Posts: 15

    after testing more and more, its getting obvious that my areas are moving down. Why is that, and why does'nt my drawBody function show that? i copied it from the debugDraw function in the physics example...

    any help is still welcome

  • edited April 2012 Posts: 15

    nevermind .. setting zero gravity in my setup () fixed it.

    physics.gravity(vec2(0,0))
    

    But it would still be nice to know whats wrong with my drawBody function..

  • JohnJohn Admin Mod
    Posts: 575

    When you draw a body you need to transform your coordinates by the body's position and rotation. There's an example in the Physics Lab example (PhysicsDebugDraw class), which will draw a list of bodies.

    pushMatrix()
    translate(body.x, body.y)
    rotate(body.angle)
    --draw code
    popMatrix()
    

    Also if you want them not to move you can do this just after you create a body:

    self.areaTop.type = STATIC
    

    This will make the body unmovable and not influenced by gravity / forces.

    Hope that helps.

  • edited May 2012 Posts: 15

    thanks very much John. Using STATIC type is much better, so the areas aren't affected by physics at all, and my Controller class does not depend on any surrounding configurations.

    And.. just for the case that anyone cares, here's the final code:

    Controller = class()
    
    function Controller:init()
        local ptTopLeft = vec2(0, HEIGHT)
        local ptTopRight = vec2(WIDTH, HEIGHT)
        local ptBtLeft = vec2(0,0)
        local ptBtRight = vec2(WIDTH, 0)
        local ptCenter = vec2(WIDTH/2, HEIGHT/2)
        
        self.areaTop = physics.body(POLYGON, unpack({ptTopLeft, ptTopRight, ptCenter}))
        self.areaBottom = physics.body(POLYGON, unpack({ptBtLeft, ptBtRight, ptCenter}))
        self.areaLeft = physics.body(POLYGON, unpack({ptBtLeft, ptTopLeft, ptCenter}))
        self.areaRight = physics.body(POLYGON, unpack({ptBtRight, ptTopRight, ptCenter}))
        
        self.areaTop.type = STATIC
        self.areaBottom.type = STATIC
        self.areaLeft.type = STATIC
        self.areaRight.type = STATIC
        
        self.left = false
        self.right = false
        self.up = false
        self.down = false
        
        currentTouches = {}
    end
    
    function Controller:touched(touch)
        if touch.state == ENDED then
            currentTouches[touch.id] = nil
        else
            currentTouches[touch.id] = touch
        end
        
        self:clear()
        for id, currentTouch in pairs(currentTouches) do 
            local touchVec = vec2(currentTouch.x, currentTouch.y)
            if (self.areaTop:testPoint(touchVec) == true) then
                self.up = true
            end 
            if (self.areaBottom:testPoint(touchVec) == true) then
                self.down = true
            end 
            if (self.areaLeft:testPoint(touchVec) == true) then
                self.left = true
            end 
            if (self.areaRight:testPoint(touchVec) == true) then
                self.right = true
            end
        end
    end 
    
    function Controller:clear()
        self.up = false
        self.down = false
        self.left = false
        self.right = false
    end
    
Sign In or Register to comment.