Howdy, Stranger!

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

How do I make a touch act like a physics object?

edited July 2013 in Questions Posts: 3

Hi,
I'm new to coding and really enjoying learning, the forum is a great help. I'm trying to make a simple game where you push balls around with your finger and give them momentum. I have tried putting an physics.body on current.touch values but it does not have any velocity to transfer to the ball when there is a collision.
What I want is for the balls to get knocked away as you drag your finger into them.
Thanks,

Tagged:

Comments

  • IgnatzIgnatz Mod
    edited July 2013 Posts: 5,396

    @Iceaxe - It's a little difficult to figure out the exact problem without seeing some code.

    (If you post code, put three of these ~ before AND also after the code, to format it correctly).

  • Posts: 372

    This is not the best method but it should work out. Just set linearVelocity to the body equal to vec2(touch.deltaX,touch.deltaY). It will make the body vibrate if you just hold it but it should work out. Like so:-

    function setup()
        p=physics.body(CIRCLE,30)
        p.mass=1
        p.gravityScale=0
        p.linearDamping=2
        p.sleepingAllowed=false
        p.x,p.y=WIDTH/2,HEIGHT/2
        t={}
    end
    
    function draw()
        background(255, 255, 255, 255)
    
        if p.x>WIDTH then p.x=0
        elseif p.x<0 then p.x=WIDTH end
        if p.y>HEIGHT then p.y=0
        elseif p.y<0 then p.y=HEIGHT end
    
        fill(0, 0, 0, 255)
        ellipse(p.x,p.y,60)
    
        for k,v in pairs(t) do
            fill(255, 0, 0, 255)
            ellipse(v.x,v.y,20)
        end
    end
    
    function touched(touch)
        if touch.state==BEGAN then
            t[#t+1]=physics.body(CIRCLE,10)
            t[#t].info=touch.id
            t[#t].mass=10
            t[#t].gravityScale=0
            t[#t].sleepingAllowed=false
            t[#t].x=touch.x
            t[#t].y=touch.y
        elseif touch.state==MOVING then
            for k,v in pairs(t) do
                if v.info==touch.id then
                    v.linearVelocity=1000*(vec2(touch.deltaX,touch.deltaY):normalize())
                    v.x=touch.x
                    v.y=touch.y
                end
            end
        elseif touch.state==ENDED then
            for k,v in pairs(t) do
                if v.info==touch.id then
                    table.remove(t,k)
                    v:destroy()
                    v=nil
                end
            end
        end
    end
    
  • Jmv38Jmv38 Mod
    Posts: 3,295

    @Iceaxe make sure the body.restitution=1.0 then maybe it will work

  • Posts: 3

    Thanks, will try this.
    Saurabh, this is good. I've already tweaked it a bit. I can understand almost all of it. Can you please explain the line where you set the linearVelocity of v? This'll all new to me. what is the 1000*?, the touch.deltaX?, and the :normalize?
    Why does the vibration occur?
    Thanks again

  • Posts: 372

    I'm not setting the linearVelcoity of v. I've stored all the bodies in a table 't' so when I do a for loop, v stands for the value in the table(which is the physics body). I set its linear velocity to a value which is done by doing thePhysicsBody.linearVelocity= the value(the value has to be a vec2). 1000* means multiply by thousand. touch.deltaX is the value of change in value of the x coordinate of the touch from the x coordinate of the previous touch, similarly touch.deltaY. Normalize a vec2(a vector) is getting the unit vector along that vector. So I'm finding the unit vector along which the person has moved his finger and then multiply by thousand and set the linearVelocity of the body a that value. The vibration occurs since your finger always moves slightly no matter how steady you hold it so the body flies of in that direction until the next time the touch function is called which sets the x and y position of the body back to the touch position. Having a look at the inbuilt reference can be helpful cause I might not be completely clear.

  • Posts: 3

    So is this right,
    Because vectors are scaler the normalise just reduces it to the smallest integer values?
    Is it because touch.state== moving is only called when there is a difference in touch.x and.y values and is not called every frame between touch.state== began and ended?
    Or does delta recall the last movement of touch even if it is from several frames before?

  • edited July 2013 Posts: 372

    Vec2(3,4) is reduced to vec2(3/5,4/5) mod of the vector was 5. Normalized vector has a magnitude of 1 and the direction same as the vector that was normalized. Normalizing a vector doesn't give a scalar but a unit vector along that direction. The touch function is called every time the screen is touched and yes the x or y coordinate changes(maybe I'm not sure). The first time the function touched is called the state is began the second is moving and it stays moving as long as as you lift the finger and that time it's ended. Try this code you'll understand it better

    function setup()
        vector=vec2(3,4) --choose any vector
        print("vector")
        print(vector)
        print("normalized vector")
        print(vector:normalize())
        print("TOUCH")
    end
    
    function touched(touch)
        if touch.state==BEGAN then
            print("Began")
        elseif touch.state==MOVING then
            print("moving")
        elseif touch.state==ENDED then
            print("Ended")
        end
    end
    
Sign In or Register to comment.