Howdy, Stranger!

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

Collision and Physics Bodies

edited January 2015 in Questions Posts: 5

Hey everyone, I am a new programmer into a high school intro to programming class and I'm trying to program a basic game that has a little guy who jumps and tries to hit stars; when he hits the stars, he scores. My major issue is that the falling stars are physics bodies and when they reach the bottom they're supposed to go back to the top, but the velocity keeps increasing so after a bit they are too fast to even see, is there a way to reset velocity? Another issue I'm having is making the stars "disappear" by going back to the top after they have collided with the character. Right now, when the character hits a star, they both go back to the top and I don't know how to avoid that. Any help?? Here's my code:


-- Final -- Use this function to perform your initial setup function setup() c1=physics.body(CIRCLE, 50) c1.position=vec2(WIDTH/2,HEIGHT/2) c2=physics.body(CIRCLE,50) c2.x=WIDTH-math.random(WIDTH/8,WIDTH/2+140) c2.y=HEIGHT c2.speed=3 c3=physics.body(CIRCLE,50) c3.x=0+math.random(0,WIDTH) c3.y=HEIGHT+350 float3=physics.body(CIRCLE,50) float3.x=WIDTH float3.y=HEIGHT+700 float4=physics.body(CIRCLE,50) float4.x=0 float4.y=HEIGHT+1400 space1=math.random(WIDTH/8,WIDTH/2+140) space2=math.random(WIDTH/8,WIDTH/2+140) space3=math.random(WIDTH/8,WIDTH/2+140) space4=math.random(WIDTH/8,WIDTH/2+140) timer=0 gravity=8 score=0 end function draw() background(140, 223, 220, 93) sprite("Platformer Art:Water",WIDTH/2,50,WIDTH+100,150) sprite("Planet Cute:Character Horn Girl",c1.x,c1.y,100,200) timer=timer+DeltaTime if timer > 0 then sprite("SpaceCute:Star", c2.x, c2.y,100) end if timer>1 then sprite("SpaceCute:Star",c3.x,c3.y,200) end if timer>2 then sprite("Tyrian Remastered:Evil Head",float3.x, float3.y,50) end if timer>3 then sprite("Tyrian Remastered:Evil Head",float4.x, float4.y,50) end if c2.y<2 then c2.y=HEIGHT c2.x=WIDTH-math.random(0,WIDTH+50) end if c3.y<2 then c3.y=HEIGHT c3.x=math.random(0,WIDTH) end if float3.y<2 then float3Y=HEIGHT float3.x=math.random(0,WIDTH) end if float4.y<2 then float4Y=HEIGHT float4.x=math.random(0,WIDTH) end font("Copperplate-Bold") fontSize(100) fill(180, 0, 255, 255) text(score,WIDTH/2,HEIGHT-100) end function collide(c) if c.state==BEGAN then score=score+1 print(score) c2.y=HEIGHT end if c.state==BEGAN then score=score+1 print(score) c3.y=HEIGHT end end function touched(touch) if CurrentTouch.x>WIDTH/2 and CurrentTouch.y < HEIGHT then c1.linearVelocity=vec2(150,75) else c1.linearVelocity=vec2(-150,75) end end

Comments

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd When you post code, put 3 ~'s on a line before and after your code to format it correctly. I added them for you. As for the stars velocity, when you move them back to the top, you can change their speed by using linearVelocity. You're already using it in the touched() function. Another suggestion is to not use CurrentTouch. Learn how to use the touched function properly.

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd Another suggestion is that when a star is collided, you can destroy it and recreate a new one at the top with a new location and velocity.

  • @dave1707 would that have to involve using a table? This is just a high school intro to programming class so we haven't really gotten that far.

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd You could use a table if you want a lot of stars, but if you just have a few, then you can skip a table. Move your star creations into seperate functions. When a collision happens then destroy that (star) physics object and call the function to recreate it.

  • @dave1707, when you say separate functions, do you mean separate collision functions?

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd You just need 1 collide function, but you need to determine what collided. When a collision happens, then you need to check c.bodyA or c.bodyB and determine if c2 or c3 was in the collision with c1. If c2 or c3 was in the collision, then you could destroy c2 or c3 and then recreate it.

  • @dave1707 how do would I check to see which body it is? In other words, where in my collide function would I put that?

    function collide(c)
    if c.state==c.bodyA then score=score+1 print(score) c3.y=HEIGHT+150 end
    if c.state==c.bodyB then score=score+1 print(score) c2.y=HEIGHT+150 end
    end

    I am fairly clueless.

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd Here's an example of a simple collision. When the collision happens, I print some information that's available. I print the values of c1 and c2 and you can see which one is bodyA or bodyB. There is a lot of other information you can see when a collision happens.


    function setup() c1 = physics.body(CIRCLE,100) -- create body for 1st circle c1.type=STATIC c1.x=WIDTH/2 c1.y=300 c2 = physics.body(CIRCLE,50) -- create body for 2nd circle c2.x=WIDTH/2 c2.y=800 c2.restitution=1 end function draw() background(40,40,50) fill(255) ellipse(c1.x,c1.y,200,200) -- draw the 1st circle ellipse(c2.x,c2.y,100,100) -- draw the 2nd circle end function collide(c) if c.state==BEGAN then print("c1",c1) print("c2",c2) print("bodyA",c.bodyA) print("bodyB",c.bodyB) print("radius of body A ",c.bodyA.radius) print("radius of body B ",c.bodyB.radius) print("x position of body A ",c.bodyA.x) print("y position of body A ",c.bodyA.y) -- see physics.contact and physics.body in the reference manual -- for other info that's available during a collision physics.pause() end end
  • Tables would make this a lot easier. While I do not do a programming class, at my school I am in a programming club and know what it is like to be clueless. My only coding mentors were the nice folks at the Codea forums, and I know how hard that is(even though you guys are AMAZING :D ). Tables were the hardest thing for me to learn...just think of them as storing multiple values. For example, you could declare a table like this:

    --create a table with 4 values in it:
    table={1, 200, 300, 40}
    

    Although tables have no use until you can call values from it. To call the 4th element from the above table, you could use:

    table[4]
    

    But if you want to iterate through an entire table, you should use for loops.

    --The # operator returns the length of a string or table.
    for i=0, #table do
    print(table[i])
    end
    

    Then you can simplify(or complex-ify if you're just starting out) this even further:

    for i, v in pairs(table) do
    print(v)
    end
    

    I know this is hard to understand now, but learning this will make your life a whole lot easier.

  • @TheSolderKing I really don't have the time to figure out how to do the tables. I tried with them for a month and had no luck. Is there any way that I could make one go to the top and the other keep going? @dave1707 's advice didn't really relate to what I was trying to accomplish

  • dave1707dave1707 Mod
    Posts: 6,486

    @emcloyd Here's the fixed collide function.


    function collide(c) if c.state==BEGAN then if c.bodyA==c1 and c.bodyB==c2 or c.bodyA==c2 and c.bodyB==c1 then score=score+1 c2.y=HEIGHT end if c.bodyA==c1 and c.bodyB==c3 or c.bodyA==c3 and c.bodyB==c1 then score=score+1 c3.y=HEIGHT end end end
  • Posts: 136

    @emcloyd tables really aren't that complicated, but in lua they can be of you don't stick to the basics. Here is the simplest use of an array. Also, if you are taking/have taken Algebra 2, think of an array(table) as a matrix.

    function setup()
    array = {}
    -- declare the empty array, really simple in lua
    array[1] = "hello"
    array[2] = "world"
    -- you can use an array just like a variable, just put what slot in the array you are saving to
    print(array[1])
    -- note what is saved in the first slot
    print(array[2])
    -- note what is saved in the second slot
    print(array[1].." "..array[2])
    -- and then you can use them to do as you please. In lua arrays don't have to be declared as a certain size or anything, so just think of them as a variable.
    end
    function draw()
    background(255,255,255,255)
    strokeWidth(5)
    end
    

    So if you wanted three stars, you can think of each slot in the array as a star, like this, and then reset or destroy and create new ones as they hit the ground

    star = {}
    -- an empty array
    star[1] = vec2(math.random(100,WIDTH-100),HEIGHT)
    star[2] = vec2(math.random(100,WIDTH-100),HEIGHT)
    star[3] = vec2(math.random(100,WIDTH-100),HEIGHT)
    -- so make coordinates for each star
    

    Or you can declare the coordinates like this

    star = {vec2(math.random(100,WIDTH-100),HEIGHT),vec2(math.random(100,WIDTH-100),HEIGHT),vec2(math.random(100,WIDTH-100),HEIGHT)}
    
Sign In or Register to comment.