Help with collision

Thank you, that works but if you don’t mind, might I ask a couple of questions regarding your tips?

[2] - why? Is there a reason this is better?

[5] - is there a reason for using this apart from being less code? (Not being awkward but I find the other way more understandable)

Also, I cannot understand how defining the bat physics in the setup actually works?l?
Because the bat moves position during play… I look at that and don’t understand how/why it works. I would expect to have to keep updating the physics position for it.

Thank you for helping

[2] - if you wanted a specific height of 50, that’s fine, but if you are wanting the actual width and height of the iPad, it’s better to use WIDTH and HEIGHT which give them to you.

Also, you’ll find it makes your programs much easier to change if you set all your constants at the beginning, rather than sprinkling them through your code. So if in this case you wanted (say) width of 200 and height of 150, I would write

local w, h = 200, 150
--and then use w & h in the code

This is much easier to change later (and also easier to understand when you come back to the code later)

[5] your way is inefficient because it results in two if tests all the time, and makes it seem as though the if tests are unconnected, when in fact they are connected to each other. These may sound like little things, especially as the speed difference is tiny most of the time, but I suggest that writing compactly and neatly is really important when your code begins to get complex. I have no doubt you will see this as your skills improve, and I strongly encourage you to get used to doing it now.

My note [6] shows where the bat position is updated in draw. The variable xpos is updated and then the x value of bat is changed.

By the way, I moved the bat definition out of draw because this was creating an extra bat 60 times a second! You only need one, so I put the bat creation in setup instead.

Thank you ignatz that was really good and now I understand a lot more.

I still don’t understand one thing, maybe I worded it wrong, let me try again.

We define the bat physics in the setup with bat=physics.body(EDGE,vec2(-70,109),vec2(70,109)).

but during the game the bat moves position and we don’t call the setup function again so, I don’t understand how the bat physics still works in the right place? I would have assumed as the bat moves position you need to keep updating the physics of its position.

Sorry if I’m dumb but honestly I don’t understand.

@Paul123 You would do something like this.

setup()
    .....
    bat=physics.body(EDGE,vec2(-70,0),vec2(70,0))
    bat.x= some initial x position
    bat.y= 109

draw()
    .....
    bat.x=CurrentTouch.x   
    sprite("Planet Cute:Plain Block",bat.x,bat.y,140,55) 
    
    

Thank you Dave but what I am trying to understand is the code ignatz posted above works perfectly but I --don’t-- understand how the collision for the bat is working fine when the bat is moving but the physics for the bat is not updated. Maybe it’s something and noting or something so obvious a 4 yr old would see, but I don’t see it and don’t understand but even though it works I really want to know --why-- it works. :slight_smile:

Yeah I failed school and failed maths, I admit I’m not clever but I am trying to learn codea and it helps if I fully understand something rather than just copy/paste someone else’s code.

I don’t mean to be ungrateful I’m not. Thank you all.

@paul123 ignatz declares the physics in the setup, he puts it in a var bat, and then in the draw, when touching, he changes bat.x which is the x-coordinate of the physics body…

Thank you, you know maybe I’m just not understanding the right thing here. Sorry to go on about this :frowning:

I think the line:-

bat=physics.body(EDGE,vec2(-70,109),vec2(70,109))

Defines the bat physics.

I maybe wrong but… I think:-

EDGE - tells it that the physics its a line and not a polygon or circle
And the coordinates -70,109,70,109 set the exact size and position of the physics?

These change as the bat moves…obviously.

But as this is in setup and not the main loop, the information is never changed?

Yet it works, I know it’s silly but it’s really annoying me that I cannot see why. Because I think it shouldn’t. Did I pick too hard a game to make? :smiley:

Have been working on this more now. I’m using the crates sprites as blocks as I think they look nice. Here is my new code. I think it’s looking nice :slight_smile:

I’m now going to try add collision to the crates and try to remove one when hit.
(Note to experts: yes I’m not using a table for the crates, I don’t understand them atm that’s why. Maybe I will in my next game!)

-- Break

-- Use this function to perform your initial setup
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
    xpos=512
    ballx=512
    bally=450
    e1=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
    e2=physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
    e3=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
    ball_diam=30
    p_ball = physics.body(CIRCLE,ball_diam/2) 
    p_ball.gravityScale = 1 
    p_ball.restitution = .8 
    p_ball.friction = 0 
    p_ball.linearVelocity = vec2(math.random(400),math.random(400))  
    p_ball.x = math.random(75,150) 
    p_ball.y = math.random(450,650)
    --add bat
    bat=physics.body(EDGE,vec2(-70,109),vec2(70,109))
    bat.gravityScale = 1 
    bat.restitution = 1.2
    bat.friction = 0 
end

function draw()
      -- define screen space and add collision detection
    strokeWidth(5)
    background(40,40,50)
    color(255)
    line(0,0,0,HEIGHT) -- draw left wall
    line(0,HEIGHT,WIDTH,HEIGHT) -- draw top wall
    line(WIDTH,0,WIDTH,HEIGHT) -- draw right wall

      -- add 'bat' sprite and setup touch movement
          -- set bat screen limits and collision
    xpos=CurrentTouch.x
    if xpos<=77 then xpos=78
    elseif xpos>=948 then xpos=945
    end
    bat.x=xpos  --[6]
    sprite("Planet Cute:Plain Block",xpos,100,150,55)
      -- add ball and move towards bat
    sprite("Tyrian Remastered:Explosion Ball",p_ball.x,p_ball.y,30,30)
    if p_ball.y <= 75 then
        text("Ball Lost",350,350) -- placeholder for lost ball
    end
    for s=1, 10 do
     sprite("Cargo Bot:Crate Green 1",250+s*42,600)
     sprite("Cargo Bot:Crate Blue 1",250+s*42,558)
     sprite("Cargo Bot:Crate Red 1",250+s*42,516)
    end
end

@Paul The code bat=physics.body(EDGE… just describes the “dimensions” of the EDGE physics.body. The code bat.x = some value and bat.y = some value is what places the bat physics.body at some screen position. The code sprite(image,bat.x,bat.y) places an image at the same position as the bat physics.body. The sprite and physics.body are 2 different things. If the sprite and physics.body are at different locations, the ball will go thru the bat sprite, but could react to an invisible physics.body somewhere else on the screen. The important thing is to keep both the sprite and physics.body at the same x,y values.

Thank you Dave, I actually understand that! I just couldn’t figure out how the physics was moving with the bat when the physics line was in the setup and thus out of the main draw loop. Like I said, I failed school so forgive me for being a dumbass. :slight_smile:

@Paul123 - Its very important to understand tables. I wrote an ebook on Lua which explains them, and you can find it in the wiki link above.

Hello, can someone tell me how it’s possible to detect which block has been hit and removing it from the screen? I have been searching and looking for an answer but can’t find one that doesn’t use a table and I can’t do the them. is there another way? I can get collision to work but removing the right one that’s hit is hard, very hard.

Btw I still don’t understand the thing I said above, but have just decided it’s one of those things I will never understand so I’m not borhering about it now.

@Paul123 I don’t think avoiding the use of tables is a wise thing to do. It’s a very important element of programming in Lua, and they’re really not that hard to grasp. As Ignatz said, read the ebook he wrote about Lua. It really helped me in the beginning to! Here’s the link https://www.dropbox.com/s/qh1e7ft4rvhlpt2/Lua%20for%20beginners.pdf

Thanks, I don’t wish to offend ignatz as he’s been really helpful, but I have that guide loaded into my iBooks and read the part on tables 6-7x but still I don’t understand it enough to use it.

I’m not complaining about the guide, pls don’t think that. But it won’t go in my head so I’m looking for another way.

@Paul123 - no offence taken, we all learn in different ways and at different speeds. I have things that I just can’t get into my head.

But if you’re going to get anywhere with Codea, you must try to understand tables. They are very important - especially when you’re managing multiple objects.

Don’t give up, be stubborn. I have spent 2 or 3 days trying to understand one little thing that didn’t work.

You can do it, I’m sure.

I wrote a little example around here, let me say if I can find it.

EDIT: Found it.

As you probably know, a table is basically tons of variables that in a "box"

Lets say we named our box: objects = {} Then we could add stuff to "objects" to ways, we could either put the things in the brackets followed by a comma like this: objects = {vec2(5,5), "easteregg"} . Or you could do: table.insert(objects, vec2(5,5)) and that would insert a vector2 into the table. Now you are probably wondering how to use these variables now. First, you need to find the slot its in, for example, if I have: objects = {"Hi", "bye", "hello"} Then I could get the "hello" string by typing objects[2] Because its in the second slot. Or if its a vec2 you would do: objects[a number].x or objects[a number].y . If you are wanting to use tables for fire bolts or something that has to be created and drawn on the screen, then you would loop through them like this:

for i=1, #objects do sprite("bullet", objects[i].x, objects[i].y end

Let me explain the above code, first we are looping through the table, as you probably know. But you are probably wondering why we have a "#" in-front of the table name, basically when you do this, it gives you the number of things in a table, very useful for things like this. And when we do objects[i].x, we are drawing a sprite on i, which goes through the entire table once every frame.

I hope I explained it well enough and you can understand.

Thanks for that, I am trying to use a table to setup the tiles the ball has to hit.
This is my first try at tables please don’t laugh,

I put this in my setup

   tiles={}
    for box = 1, 10 do
        tiles[box] = sprite("Cargo Bot:Crate Green 1")
    end

That should configure a table that I can use for the first row of tiles? (I’m trying to do this one small step at a time)

That runs without error so I guess it’s okay. Now in the draw loop I am trying to draw the boxes using that table. I tried

    for s=1, 10 do
sprite("tiles{s}",250+s*42,600)
    end

I think that would draw the sprite but no, but also I’m not getting an error.

Am I even remotely close to understanding this?

@Paul If you’re drawing the same sprite, you don’t need to put the sprite name in the table. The x,y coordinates should be put in the table and the coordinates read from the table. I just showed how the code you have above should have been written to work. I’ll leave it up to you to make the suggested changes.


function setup()
    tiles={}
    for box = 1, 10 do
        tiles[box] = readImage("Cargo Bot:Crate Green 1")
    end
end

function draw()    
    for s=1, 10 do
        sprite(tiles[s],10+s*42,600)
    end
end

@paul123 You are close, you can’t make things in tables, like that, though.
I rewrote your example a little bit to make it work

function setup()
tiles = {}
for box = 1, 10 do
table.insert(tiles, "Cargo Bot:Crate Green 1")
end
end
function draw()
for s=1, 10 do
sprite(tiles[s], 250+s*42,600)
end
end

Thank you both, very helpful and I believe I am starting to grasp the very basics of tables. Maybe.

Here is my new code, table now working and it displays the boxes great!!! I have started working on the collision detection using if statements to check the area around each tile. Only done one tile to test it now but it’s not working yet, I figure I’m very close and going to keep working at it.

-- Break

-- Use this function to perform your initial setup
displayMode(FULLSCREEN)
supportedOrientations(LANDSCAPE_ANY)

function setup()
    xpos=512
    ballx=512
    bally=450
    e1=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
    e2=physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT))
    e3=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
    ball_diam=30
    p_ball = physics.body(CIRCLE,ball_diam/2) 
    p_ball.gravityScale = 1 
    p_ball.restitution = .8 
    p_ball.friction = 0 
    p_ball.linearVelocity = vec2(math.random(400),math.random(400))  
    p_ball.x = math.random(75,150) 
    p_ball.y = math.random(450,650)
    --add bat
    bat=physics.body(EDGE,vec2(-70,109),vec2(70,109))
    bat.gravityScale = 1 
    bat.restitution = 1.2
    bat.friction = 0 
    -- configure boxes
    tiles={}
    for box = 1, 10 do
      table.insert(tiles,vec2(250+box*42,600))
    end
end

function draw()
      -- define screen space and add collision detection
    strokeWidth(5)
    background(40,40,50)
    color(255)
    line(0,0,0,HEIGHT) -- draw left wall
    line(0,HEIGHT,WIDTH,HEIGHT) -- draw top wall
    line(WIDTH,0,WIDTH,HEIGHT) -- draw right wall

      -- set bat screen limits and collision
    xpos=CurrentTouch.x
    if xpos<=77 then xpos=78
     elseif xpos>=948 then xpos=945
    end
    bat.x=xpos 
    sprite("Planet Cute:Plain Block",xpos,100,150,55) -- bat
      -- add ball and move towards bat
    sprite("Tyrian Remastered:Explosion Ball",p_ball.x,p_ball.y,30,30) -- ball
    if p_ball.y <= 75 then
        text("Ball Lost",350,350) -- placeholder for lost ball
    end
    for box=1,10 do -- draw first row of boxes
    sprite("Cargo Bot:Crate Green 1",275+box*42,600)
    end
    -- box collision and removal
    if p_ball.x>=317 and p_ball.x<=359 and p_ball.y>=599 and p_ball.y<=641 then -- tile 1 approx bounding box
        table.remove(tiles,1)
    end
end