#### Howdy, Stranger!

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

# Brick Breaker with physics

Posts: 6

I am in the beginning stages of creating a brick breaker style game and am running into an issue when removing physics objects from my table. I give all my physics objects an attribute called index and when a collision occurs I access that index to remove the correct object. I assumed this would work but I receive an error in my for loop that iterates through my table of objects. Any input on this would be appreciated.

-- Brick Breaker

-- Use this function to perform your initial setup
function setup()
--displayMode(FULLSCREEN)
rectMode(CENTER)
print("Hello World!")
bricks = {}
floor = physics.body(EDGE, vec2(0,0), vec2(WIDTH, 0))
rightWall = physics.body(EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
leftWall = physics.body(EDGE, vec2(0,0), vec2(0, HEIGHT))
TopScreen = physics.body(EDGE, vec2(0, HEIGHT), vec2(WIDTH, HEIGHT))
floor.restitution = 1
rightWall.restitution = 1
TopScreen.restitution = 1
leftWall.restitution = 1

)

ball = physics.body(CIRCLE, 25)
ball.x = WIDTH/2
ball.y = HEIGHT/2-200
ball.restition = 1
ball.gravityScale = 0
ball:applyForce(vec2(0, -3000))
index = 0
for i = 0, 6 do
spawnBrick(100*i, HEIGHT-(100), i)
end

end

-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)

-- This sets the line thickness
strokeWidth(5)

ellipse(ball.x, ball.y, 50)

pushMatrix()
popMatrix()
for i, brick in ipairs(bricks) do
rect(brick.x, brick.y, brickWidth, brickHeight)
end
end

function spawnBrick(x, y, i)
brickWidth = 100
brickHeight = 50
brick = physics.body(POLYGON,
vec2(-brickWidth/2, -brickHeight/2), --bottom left
vec2(-brickWidth/2, brickHeight/2),
vec2(brickWidth/2, brickHeight/2),
vec2(brickWidth/2, -brickHeight/2)

)
brick.x = x
brick.y = y
brick.type = STATIC
brick.restitution = 1
brick.info = "brick"
brick.index = i
table.insert(bricks, brick)
end

function collide(contact)

if contact.state == ENDED then
if contact.bodyA ~= nil then
if contact.bodyA.info == "brick" then
print(contact.bodyA.index)
table.remove(bricks, contact.bodyA.index)
contact.bodyA:destroy()
end
end
end
end
Tagged:

• Mod
Posts: 6,828

@dkharley That's usually caused because you're in the middle of a loop and something is removed from the table the loop is doing. You should set a flag on the item being deleted and then remove that item by going thru the table in reverse order.

• Mod
edited April 2015 Posts: 6,828

I added this to the end of the draw function.

for i=#bricks,1,-1 do if bricks[i].info=="delete" then bricks[i]:destroy() table.remove(bricks,i) end end

I changed the collide function to this.

function collide(contact) if contact.state == ENDED then if contact.bodyA ~= nil then if contact.bodyA.info == "brick" then print(contact.bodyA.index) contact.bodyA.info="delete" end end end end
• Posts: 6

Awesome thanks for the help. Should I always use this technique when removing items from a table? For example I have a project in which a cloud creates raindrops that eventually fall off screen. When they are below a certain threshold I remove them from the table, when I do this there is usually a flicker that happens to the other raindrops. I assume this is because I am deleting rain drops in the middle of a loop?

• Mod
Posts: 6,828

@dkharley That usually causes a flicker. When you delete something in the middle of a table, everything else shifts down one position. Then on the next iteration of the table, the first item that got shifted down gets skipped. Sometimes you'll get a flicker, sometimes you'll get an error. it all depends on what you're doing while in the loop. By going in reverse order, you don't have that problem.