I have an item coming from the top and going down and it collides with some objects (no collision detections) and at the beginning, when the speed is low, the item stops however the speed increases as the game goes and after a while the item starts going through the other objects.
The first item is dynamic and the colliding objects are static.
I read a little bit about it:
Objects are going through walls
A relatively common problem I’m seeing people have is that at times, their dynamic objects are passing through static walls, particularly when the object is traveling at a high speed.
There are several factors that play into this, so I’ll list all of the different things that you may want to play with, also in conjunction with the other items, to overcome your problem:
body.isBullet – This property will cause a body to be subject to continuous collisions, so it reduces the chances of missing a collision when traveling at a high speed.
Play around with the density property, which affects how “heavy” an object is. While changing this probably wouldn’t fix your problem outright, it could be a factor that plays a big part.
I’ve ran into a case where a static body was just too thin, and making it a little larger fixed the problem of dynamic objects passing through it. Of course, this meant I also had to make my image resource larger, which may not be an option for your project.
The physics.setScale() property greatly affects how physical bodies react to the environment, and with eachother. Try playing around with this, as well as in conjunction with the other properties, to see if it fixes your problem.
physics.setVelocityIterations() and physics.setPositionIterations() determine how often position and velocity calculations are computed. The higher the value, the more computational overhead it takes, however, setting this to just the right threshold could potentially give you the solution you’ve been looking for.
I tried to set the items and the colliding objects to isBullet = true, I tried to change the setVelovityIterations etc. but none of them seems to stop the item going through the colliding items. I see that they change some parameters (for example the items drop much faster etc.) but that’s it.
The colliding items have an thickness of 20 pixels and the item 16 * 16.
The item can’t move in the simulator but it’s supposed to be moved by the gyroscope but right now the item just goes straight down and sometimes a little bit to the right and left if it hits a corner of the colliding item.
Can anybody help me so the item doesn’t go through the colliding items?
I tried to set physics.setContinuous to false but with no change. It was set to 30 FPS but I changed it to 60 to try it out but unfortunately it didn’t change anything either.
Isn’t there a setting so I can set the bodyType to “superstatic” (or "mounteverest) or something so nothing except the ball (I called it the item in the orignal post) will be affected by the collision and the “superstatic” will just be rock, solid hard?
Then I create an rectangle, which is an colliding item which the ball can bounce on (and should not go through):
if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRect(xGenerator[1], 600, lengthGenerator[1], 20) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "static") row[rowCounter + MAX\_ROWS].gravityScale = 0 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack()
And at the top I have set the physics like this (And I have also tried several parts which are commented):
local physics = require "physics" physics.start() physics.setContinuous( false ) -- physics.setScale(200) --physics.setVelocityIterations( 30 ) -- 3 --physics.setPositionIterations( 80 ) -- 8 -- 10 - 100 Hz (i.e. 10 - 100 checks per seconds, keep it low if possible, drains the battery) system.setAccelerometerInterval(100)
Here is a video how it acts (It’s a little bit laggy but you can still see sometimes when the ball go through the rectangles):
Just quickly scanning your code, I don’t see anything obviously wrong. But even more helpful would be a completely standalone example that Brent or I could run ourselves – otherwise it’s a bit hard to debug.
The video is helpful. How did you implement the vertical scrolling? Depending on how you’ve implemented it, that could be the source of the issue.
The ball is affected by gravity so it goes down through that, the rows doesn’t have any gravity and it’s y variable is called by moveRows which is called by moveScreen which is called by a listener:
Maybe that might be something? Maybe the force between those two items is to strong or maybe when both the ball and row collides the collision body from the ball and the row crosses over and therefore the balls go through?
Here is all the code if it might help you see something:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local isSimulator = "simulator" == system.getInfo("environment") -- Your code here local physics = require "physics" physics.start() physics.setContinuous( false ) -- physics.setScale(200) --physics.setVelocityIterations( 30 ) -- 3 --physics.setPositionIterations( 80 ) -- 8 -- 10 - 100 Hz (i.e. 10 - 100 checks per seconds, keep it low if possible, drains the battery) system.setAccelerometerInterval(100) local row -- Each row can contain several rectangle local ball local frameCounter local rowCounter local MAX\_ROWS = 11 local BASE\_SPEED = 15 local scoreRectangle local score local scoreText local floor local roof local leftwall local rightwall local centerX = display.contentWidth / 2 local centerY = display.contentHeight / 2 local WIDTH = display.contentWidth local HEIGHT = display.contentHeight -- Variables to control the game flow local ROW\_SPACE = 25 local MIN\_LENGTH = 35 local MAX\_LENGTH = 75 local MAX\_RECTANGLES = 2 local scoreTable -- Makes sure the game parameters (if score \> 1000) will only be runned once -- Help variables local xGenerator local lengthGenerator function main() startGame() end function startGame() Runtime:addEventListener("enterFrame", moveScreen) scoreRectangle = display.newRect(0,0, WIDTH, 25) scoreRectangle:setFillColor(205,92,92) scoreRectangle.alpha = 0.8 print("Start Game") frameCounter = 0 rowCounter = 1 -- How many rows have passed? score = 0 scoreTable = {} scoreText = display.newText("0", 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) ball = display.newImage("ball.png") ball.x = 20 ball.y = 25 physics.addBody(ball, "dynamic", {shape = circle, radius = 8}) ball.isBullet = true floor = display.newRect(0, HEIGHT, WIDTH, 0) floor.strokeWidth = 3 floor:setFillColor(140, 140, 140) floor:setStrokeColor(180, 180, 180) physics.addBody(floor, "static") roof = display.newRect(0, -1, WIDTH, 0) roof.strokeWidth = 3 roof:setFillColor(140, 140, 140) roof:setStrokeColor(180, 180, 180) physics.addBody(roof, "static") roof:addEventListener("collision", roofOnCollision) leftwall = display.newRect(0, 0, 1, HEIGHT) leftwall.strokeWidth = 3 leftwall:setFillColor(140, 140, 140) leftwall:setStrokeColor(180, 180, 180) physics.addBody(leftwall, "static") rightwall = display.newRect(WIDTH, 0, 1, HEIGHT) rightwall.strokeWidth = 3 rightwall:setFillColor(140, 140, 140) rightwall:setStrokeColor(180, 180, 180) physics.addBody(rightwall, "static") drawStartRows() end function removeListeners() Runtime:removeEventListener ("accelerometer", onAccelerate); Runtime:removeEventListener("enterFrame", moveScreen) end function moveScreen() frameCounter = frameCounter + 1 moveRows() BASE\_SPEED = BASE\_SPEED + 0.001 score = score + BASE\_SPEED -- Update Score scoreText:removeSelf() scoreText = nil scoreText = display.newText(math.floor(score), 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) -- Verify if the row contains several rectangles local isMultiRect if row[rowCounter].multiRect == true then isMultiRect = true else isMultiRect = false end -- Verify if the row is after screen local isAfterScreen if isMultiRect then if row[rowCounter][1].y \< 0 then isAfterScreen = true else isAfterScreen = false end else if row[rowCounter].y \< 0 then isAfterScreen = true else isAfterScreen = false end end -- Add a new rectangle if isAfterScreen then -- Remove old rectangle if isMultiRect then for i = 1, #row[rowCounter] do row[rowCounter][i]:removeSelf() row[rowCounter][i] = nil end else row[rowCounter]:removeSelf() row[rowCounter] = nil end local numberOfRectangles = math.random(1,MAX\_RECTANGLES) if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRect(xGenerator[1], 600, lengthGenerator[1], 20) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "static") row[rowCounter + MAX\_ROWS].gravityScale = 0 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack() elseif numberOfRectangles \> 1 then row[rowCounter + MAX\_ROWS] = {} generatePositions(tonumber(numberOfRectangles)) for i = 1, numberOfRectangles do -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values row[rowCounter + MAX\_ROWS][i] = display.newRect(xGenerator[i], 600, lengthGenerator[i], 20) row[rowCounter + MAX\_ROWS][i].strokeWidth = 3 row[rowCounter + MAX\_ROWS][i]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS][i]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS][i], "static") row[rowCounter + MAX\_ROWS][i].isBullet = true row[rowCounter + MAX\_ROWS][i].gravityScale = 0 row[rowCounter + MAX\_ROWS][i].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = true row[rowCounter + MAX\_ROWS].noOfRectangles = numberOfRectangles row[rowCounter + MAX\_ROWS][i]:toBack() end end rowCounter = rowCounter + 1 end end function roofOnCollision(event) print("Collision") removeOldData() roof:removeEventListener("collision", roofOnCollision) removeListeners() timer.performWithDelay(50, startGame) end function removeOldData() print("removeOldData") print(BASE\_SPEED) ball:removeSelf() ball = nil scoreText:removeSelf() scoreText = nil floor:removeSelf() floor = nil leftwall:removeSelf() leftwall = nil rightwall:removeSelf() rightwall = nil scoreRectangle:removeSelf() scoreRectangle = nil -- When the first value becomes nil in a table the #row count will be zero therefore I need to delete the different rows like this -- http://lua-users.org/wiki/StoringNilsInTables for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == true then for j = 0, row[i].noOfRectangles do if row[i][j] ~= nil then row[i][j]:removeSelf() row[i][j] = nil end end elseif row[i].multiRect == false then row[i]:removeSelf() row[i] = nil end end end row = nil end function drawStartRows() row = {} -- Contains a total of 15 rectangles (lines) row[1] = display.newRect(50, 100, 150, 20) row[1].strokeWidth = 3 row[1]:setFillColor(140, 140, 140) row[1]:setStrokeColor(180, 180, 180) physics.addBody(row[1], "static") row[1].gravityScale = 0 row[1].isFixedRotation = true row[1].multiRect = false row[2] = display.newRect(50, 150, 150, 20) row[2].strokeWidth = 3 row[2]:setFillColor(140, 140, 140) row[2]:setStrokeColor(180, 180, 180) physics.addBody(row[2], "static") row[2].gravityScale = 0 row[2].isFixedRotation = true row[2].multiRect = false row[3] = display.newRect(50, 200, 150, 20) row[3].strokeWidth = 3 row[3]:setFillColor(140, 140, 140) row[3]:setStrokeColor(180, 180, 180) physics.addBody(row[3], "static") row[3].gravityScale = 0 row[3].isFixedRotation = true row[3].multiRect = false row[4] = display.newRect(50, 250, 150, 20) row[4].strokeWidth = 3 row[4]:setFillColor(140, 140, 140) row[4]:setStrokeColor(180, 180, 180) physics.addBody(row[4], "static") row[4].gravityScale = 0 row[4].isFixedRotation = true row[4].multiRect = false row[5] = display.newRect(50, 300, 150, 20) row[5].strokeWidth = 3 row[5]:setFillColor(140, 140, 140) row[5]:setStrokeColor(180, 180, 180) physics.addBody(row[5], "static") row[5].gravityScale = 0 row[5].isFixedRotation = true row[5].multiRect = false row[6] = display.newRect(50, 350, 150, 20) row[6].strokeWidth = 3 row[6]:setFillColor(140, 140, 140) row[6]:setStrokeColor(180, 180, 180) physics.addBody(row[6], "static") row[6].gravityScale = 0 row[6].isFixedRotation = true row[6].multiRect = false row[7] = display.newRect(50, 400, 150, 20) row[7].strokeWidth = 3 row[7]:setFillColor(140, 140, 140) row[7]:setStrokeColor(180, 180, 180) physics.addBody(row[7], "static") row[7].gravityScale = 0 row[7].isFixedRotation = true row[7].multiRect = false row[8] = display.newRect(50, 450, 150, 20) row[8].strokeWidth = 3 row[8]:setFillColor(140, 140, 140) row[8]:setStrokeColor(180, 180, 180) physics.addBody(row[8], "static") row[8].gravityScale = 0 row[8].isFixedRotation = true row[8].multiRect = false row[9] = display.newRect(50, 500, 150, 20) row[9].strokeWidth = 3 row[9]:setFillColor(140, 140, 140) row[9]:setStrokeColor(180, 180, 180) physics.addBody(row[9], "static") row[9].gravityScale = 0 row[9].isFixedRotation = true row[9].multiRect = false row[10] = display.newRect(50, 550, 150, 20) row[10].strokeWidth = 3 row[10]:setFillColor(140, 140, 140) row[10]:setStrokeColor(180, 180, 180) physics.addBody(row[10], "static") row[10].gravityScale = 0 row[10].isFixedRotation = true row[10].multiRect = false row[11] = display.newRect(50, 600, 150, 20) row[11].strokeWidth = 3 row[11]:setFillColor(140, 140, 140) row[11]:setStrokeColor(180, 180, 180) physics.addBody(row[11], "static") row[11].gravityScale = 0 row[11].isFixedRotation = true row[11].multiRect = false end function moveRows() local intCounter = 0 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end end -- Game logic methods -- Start position function generatePositions(numberOfRectangles) xGenerator = {} lengthGenerator = {} if numberOfRectangles \> 1 then xGenerator[1] = math.random(-150, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH, MAX\_LENGTH) for i = 2, numberOfRectangles do local value = xGenerator[i-1] + lengthGenerator[i-1] + ROW\_SPACE xGenerator[i] = math.random(value, value + math.random(MIN\_LENGTH,MAX\_LENGTH)) lengthGenerator[i] = math.random(MIN\_LENGTH,MAX\_LENGTH) end elseif numberOfRectangles == 1 then xGenerator[1] = math.random(0, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH,MAX\_LENGTH) end -- Change Game Parameters if score \> 1000 and scoreTable[1] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[1] = 1 elseif score \> 2000 and scoreTable[2] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[2] = 1 elseif score \> 3000 and scoreTable[3] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[3] = 1 elseif score \> 4000 and scoreTable[4] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[4] = 1 elseif score \> 5000 and scoreTable[5] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[5] = 1 end end -- Gyroscope event local function onAccelerate( event ) ball.x = display.contentCenterX - (display.contentCenterX \* (event.yGravity \* 3)) if((ball.x - ball.width \* 0.5) \< 0) then ball.x = ball.width \* 0.5 elseif((ball.x + paddle.width \* 0.5) \> display.contentWidth) then ball.x = display.contentWidth - ball.width \* 0.5 end end -- Add runtime listeners -- Runtime:addEventListener ("accelerometer", onAccelerate); main()
OK, I was able to run it. Note that I had to replace ball.png with display.newCircle.
Your issue is that you’re moving the rectangles by directly modifying their y-coordinates. That’s not going to work with physics and collision detection. The rectangles will instantly “jump” from one position to another, and they won’t trigger a collision with the ball. (This is what I had in mind when I said above that it depends on how you’ve implemented it.)
With physics objects, you shouldn’t directly modify their coordinates unless you’re placing them in their initial position or you truly want them to jump from one position to another. If you want to move them, you should modify their physical properties like velocity, or apply forces to them, or use a touch joint. In your case, probably the best solution is to make your rectangles kinematic, give them an upward velocity, and set their gravity scale to zero to they don’t fall.
(As a side suggestion about your coding, your moveRows function could be simplified a lot if you just put it into a loop.)
Now it looks like this, I removed the “moveRows” method (where the y value was changed) and now the rows are going up based on this: row[rowCounter + MAX_ROWS]:setLinearVelocity(0, BASE_SPEED)
if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRect(xGenerator[1], 600, lengthGenerator[1], 20) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "kinematic", {bounce = ROW\_BOUNCE}) row[rowCounter + MAX\_ROWS].gravityScale = 0 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack() row[rowCounter + MAX\_ROWS]:setLinearVelocity(0, BASE\_SPEED)
Thanks a lot for your help, I’m sure other people have had or will have this “problem” and I’m sure this forum post will help them thanks to your help!
Yeah, I already changed that! The thing was that at the beginning I just added one or two rectangles and then I added two more just to test a little bit more and at the end I had 11 of them but that how it goes sometimes!
for i = 1, MAX\_ROWS do row[i] = display.newRect(325, 50 + (i \* 50), 150, 20) row[i].strokeWidth = 3 row[i]:setFillColor(140, 140, 140) row[i]:setStrokeColor(180, 180, 180) physics.addBody(row[i], "kinematic") row[i].gravityScale = 0 row[i].isFixedRotation = true row[i].multiRect = false row[i]:setLinearVelocity(0, BASE\_SPEED) end
It has some features such as that you can collect two items (“time stopper” and “go through walls”) and also if you shake the phone, all the existing rows on the screen will disappear (you only have three of these bas boys).
Here is the source code if anyone is interested (you only need to create your own images). The code is not well written, even though I tried, but my primary goal was to get it to work, which it does, but it might be helpful to someone:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local isSimulator = "simulator" == system.getInfo("environment") -- Your code here local physics = require "physics" physics.setContinuous( false ) -- Gravity local GRAVITY = 35 physics.setScale(GRAVITY) --physics.setVelocityIterations( 30 ) -- 3 --physics.setPositionIterations( 80 ) -- 8 -- 10 - 100 Hz (i.e. 10 - 100 checks per seconds, keep it low if possible, drains the battery) system.setAccelerometerInterval(100) local row -- Each row can contain several rectangle local ball local frameCounter local rowCounter local MAX\_ROWS = 11 local scoreRectangle local score local scoreText local floor local roof local leftwall local rightwall local centerX = display.contentWidth / 2 local centerY = display.contentHeight / 2 local WIDTH = display.contentWidth local HEIGHT = display.contentHeight -- Variables to control the game flow -- Rows local ROW\_SPACE = 25 local MIN\_LENGTH = 35 local MAX\_LENGTH = 75 local MAX\_RECTANGLES = 2 local ROW\_BOUNCE = 0.05 -- 0.2 = Default however force (from the velocity applies) -- Speed local BASE\_SPEED\_ORG = -100 local BASE\_SPEED local OLD\_SPEED local SPEED\_ADJUSTER = -0.03 -- Color local BASE\_COLOR = 140 -- Lifes local SHAKE\_LIFES local LIFE\_BAR local SHAKE\_IS\_RUNNING -- Items local items local itemCounter local scoreTable -- Makes sure the game parameters (if score \> 100) will only be runned once -- Help variables local xGenerator local lengthGenerator function main() startGame() end function startGame() Runtime:addEventListener("enterFrame", drawRows) physics.start() BASE\_SPEED = BASE\_SPEED\_ORG scoreRectangle = display.newRect(0,0, WIDTH, 25) scoreRectangle:setFillColor(205,92,92) scoreRectangle.alpha = 0.8 SHAKE\_LIFES = 3 SHAKE\_IS\_RUNNING = false LIFE\_BAR = {} for i = 1, SHAKE\_LIFES do LIFE\_BAR[i] = display.newImage("slow.png", WIDTH - (25 \* i), 0) LIFE\_BAR[i]:toFront() end frameCounter = 0 itemCounter = 0 rowCounter = 1 -- How many rows have passed? score = 0 scoreTable = {} scoreText = display.newText("0", 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) items = {} ball = display.newImage("ball.png") ball.x = centerX ball.y = 35 ball.name = "ball" physics.addBody(ball, "dynamic", {shape = circle, radius = 8}) ball.isBullet = true ball:addEventListener("collision", onCollision) floor = display.newRect(0, HEIGHT, WIDTH, 0) floor.strokeWidth = 3 floor:setFillColor(140, 140, 140) floor:setStrokeColor(180, 180, 180) physics.addBody(floor, "kinematic") roof = display.newRect(0, -1, WIDTH, 0) roof.strokeWidth = 3 roof:setFillColor(140, 140, 140) roof:setStrokeColor(180, 180, 180) physics.addBody(roof, "static") roof:addEventListener("collision", roofOnCollision) leftwall = display.newRect(0, 0, 1, HEIGHT) leftwall.strokeWidth = 3 leftwall:setFillColor(140, 140, 140) leftwall:setStrokeColor(180, 180, 180) physics.addBody(leftwall, "kinematic") rightwall = display.newRect(WIDTH, 0, 1, HEIGHT) rightwall.strokeWidth = 3 rightwall:setFillColor(140, 140, 140) rightwall:setStrokeColor(180, 180, 180) rightwall:setStrokeColor(180, 180, 180) physics.addBody(rightwall, "kinematic") local rect = display.newRect(0, HEIGHT + 2, WIDTH, 50) rect:setFillColor(0,0,0) rect:toFront() drawStartRows() end function removeListeners() -- Runtime:removeEventListener ("accelerometer", onAccelerate); Runtime:removeEventListener("enterFrame", drawRows) roof:removeEventListener("collision", roofOnCollision) ball:removeEventListener("collision", onCollision) end function drawRows() frameCounter = frameCounter + 1 BASE\_SPEED = BASE\_SPEED + SPEED\_ADJUSTER score = score + ((BASE\_SPEED/ 1000)\* -1) -- Update Score scoreText:removeSelf() scoreText = nil scoreText = display.newText(math.floor(score), 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) -- Verify if the row contains several rectangles local isMultiRect if row[rowCounter].multiRect == true then isMultiRect = true else isMultiRect = false end -- Verify if the row is after screen local isAfterScreen if isMultiRect then if row[rowCounter][1].y \< 0 then isAfterScreen = true else isAfterScreen = false end else if row[rowCounter].y \< 0 then isAfterScreen = true else isAfterScreen = false end end -- Add a new rectangle if isAfterScreen then -- Remove old rectangle if isMultiRect then for i = 1, #row[rowCounter] do row[rowCounter][i]:removeSelf() row[rowCounter][i] = nil end else row[rowCounter]:removeSelf() row[rowCounter] = nil end local numberOfRectangles = math.random(1,MAX\_RECTANGLES) if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRoundedRect(xGenerator[1], 600, lengthGenerator[1], 20, 5) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(generateColor(), generateColor(), generateColor()) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "kinematic", {bounce = ROW\_BOUNCE}) row[rowCounter + MAX\_ROWS].gravityScale = 100 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack() row[rowCounter + MAX\_ROWS]:setLinearVelocity(0, BASE\_SPEED) timer.performWithDelay(10, drawItem(row[rowCounter + MAX\_ROWS].x, row[rowCounter + MAX\_ROWS].y)) elseif numberOfRectangles \> 1 then row[rowCounter + MAX\_ROWS] = {} generatePositions(tonumber(numberOfRectangles)) for i = 1, numberOfRectangles do -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values row[rowCounter + MAX\_ROWS][i] = display.newRoundedRect(xGenerator[i], 600, lengthGenerator[i], 20, 5) row[rowCounter + MAX\_ROWS][i].strokeWidth = 3 row[rowCounter + MAX\_ROWS][i]:setFillColor(generateColor(), generateColor(), generateColor()) row[rowCounter + MAX\_ROWS][i]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS][i], "kinematic", {bounce = ROW\_BOUNCE}) row[rowCounter + MAX\_ROWS][i].isBullet = true row[rowCounter + MAX\_ROWS][i].gravityScale = 0 row[rowCounter + MAX\_ROWS][i].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = true row[rowCounter + MAX\_ROWS].noOfRectangles = numberOfRectangles row[rowCounter + MAX\_ROWS][i]:toBack() row[rowCounter + MAX\_ROWS][i]:setLinearVelocity(0, BASE\_SPEED) timer.performWithDelay(10, drawItem(row[rowCounter + MAX\_ROWS][i].x, row[rowCounter + MAX\_ROWS][i].y)) end end rowCounter = rowCounter + 1 end end function roofOnCollision(event) if event.other.name == "ball" then physics.pause() print("itemCounter2: "..itemCounter) removeOldData() timer.performWithDelay(500, startGame) elseif event.other.itemtype == "item" then if items[event.other.i] ~= nil then items[event.other.i]:removeSelf() items[event.other.i] = nil end end end function removeOldData() removeListeners() print("removeOldData") ball:removeSelf() ball = nil floor:removeSelf() floor = nil leftwall:removeSelf() leftwall = nil rightwall:removeSelf() rightwall = nil scoreRectangle:removeSelf() scoreRectangle = nil scoreText:removeSelf() scoreText = nil removeItems() -- When the first value becomes nil in a table the #row count will be zero therefore I need to delete the different rows like this -- http://lua-users.org/wiki/StoringNilsInTables for i = 1, #LIFE\_BAR do LIFE\_BAR[i]:removeSelf() LIFE\_BAR[i] = nil end for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == true then for j = 0, row[i].noOfRectangles do if row[i][j] ~= nil then row[i][j]:removeSelf() row[i][j] = nil end end elseif row[i].multiRect == false then row[i]:removeSelf() row[i] = nil end end end row = nil end function removeItems() print("itemCounter: "..itemCounter) for i = 1, itemCounter do if items[i] == nil then -- Do nothing elseif items[i] ~= nil then items[i]:removeSelf() items[i] = nil end end end function drawStartRows() row = {} -- Contains a total of 15 rectangles (lines) -- Will not be used in the game, just to start the game of so the table gets filled out -- and row[1] passes the roof for i = 1, MAX\_ROWS do row[i] = display.newRect(325, 50 + (i \* 50), 150, 20) row[i].strokeWidth = 3 row[i]:setFillColor(140, 140, 140) row[i]:setStrokeColor(180, 180, 180) physics.addBody(row[i], "kinematic") row[i].gravityScale = 0 row[i].isFixedRotation = true row[i].multiRect = false row[i]:setLinearVelocity(0, BASE\_SPEED) end end function generateColor() return math.random(1,254) end -- Game logic methods -- Start position function generatePositions(numberOfRectangles) xGenerator = {} lengthGenerator = {} if numberOfRectangles \> 1 then xGenerator[1] = math.random(-150, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH, MAX\_LENGTH) for i = 2, numberOfRectangles do local value = xGenerator[i-1] + lengthGenerator[i-1] + ROW\_SPACE xGenerator[i] = math.random(value, value + math.random(MIN\_LENGTH,MAX\_LENGTH)) lengthGenerator[i] = math.random(MIN\_LENGTH,MAX\_LENGTH) end elseif numberOfRectangles == 1 then xGenerator[1] = math.random(0, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH,MAX\_LENGTH) end -- Change Game Parameters if score \> 100 and scoreTable[1] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[1] = 1 elseif score \> 200 and scoreTable[2] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[2] = 1 elseif score \> 300 and scoreTable[3] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[3] = 1 elseif score \> 400 and scoreTable[4] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[4] = 1 elseif score \> 500 and scoreTable[5] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[5] = 1 end end -- Gyroscope event local function onAccelerate( event ) physics.setGravity( ( GRAVITY \* event.xGravity ), ( -GRAVITY \* event.yGravity ) ) if event.isShake == true and SHAKE\_LIFES \> 0 then if SHAKE\_IS\_RUNNING == false then SHAKE\_IS\_RUNNING = true LIFE\_BAR[SHAKE\_LIFES]:removeSelf() LIFE\_BAR[SHAKE\_LIFES] = nil SHAKE\_LIFES = SHAKE\_LIFES - 1 shakeAwayItems() end end end -- Ball Collision event function onCollision(event) if event.other.itemtype == "item" then if event.other.itemname == "sensor" then startSensor() elseif event.other.itemname == "clock" then startTimeStopper() end items[event.other.i]:removeSelf() items[event.other.i] = nil end end function drawItem(x, y) local gen = math.random(1,20) if gen == 1 then itemCounter = itemCounter + 1 items[itemCounter] = display.newImage("itemslow.png", x, y-16) physics.addBody(items[itemCounter], "dynamic", {bounce = 0, density = 10}) items[itemCounter].itemname = "sensor" -- Here different items will be set - Gold ball, isSensor etc. items[itemCounter].itemtype = "item" items[itemCounter].i = itemCounter items[itemCounter].isFixedRotation = true items[itemCounter].gravityScale = 0 items[itemCounter]:toBack() items[itemCounter].isBullet = 0 elseif gen == 2 then itemCounter = itemCounter + 1 items[itemCounter] = display.newImage("itemclock.png", x, y-16) physics.addBody(items[itemCounter], "dynamic", {bounce = 0, density = 10}) items[itemCounter].itemname = "clock" -- Here different items will be set - Gold ball, isSensor etc. items[itemCounter].itemtype = "item" items[itemCounter].i = itemCounter items[itemCounter].isFixedRotation = true items[itemCounter].gravityScale = 0 items[itemCounter]:toBack() items[itemCounter].isBullet = 0 end end -- Items Methods - How they work! function startTimeStopper() OLD\_SPEED = BASE\_SPEED BASE\_SPEED = -25 for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == false then row[i]:setLinearVelocity(0, BASE\_SPEED) elseif row[i].multiRect == true then for j = 1, #row[i] do row[i][j]:setLinearVelocity(0, BASE\_SPEED) end end end end timer.performWithDelay(1500, endTimeStopper) end function endTimeStopper(oldSpeed) BASE\_SPEED = OLD\_SPEED for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == false then row[i]:setLinearVelocity(0, BASE\_SPEED) elseif row[i].multiRect == true then for j = 1, #row[i] do row[i][j]:setLinearVelocity(0, BASE\_SPEED) end end end end end function startSensor() for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == false then row[i].isSensor = true row[i].alpha = 0.5 elseif row[i].multiRect == true then for j = 1, #row[i] do row[i][j].isSensor = true row[i][j].alpha = 0.5 end end end end end function shakeAwayItems() for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == false then row[i].isSensor = true transition.to(row[i], {time = 500, alpha = 0.0}) elseif row[i].multiRect == true then for j = 1, #row[i] do row[i][j].isSensor = true transition.to(row[i][j], {time = 500, alpha = 0.0}) end end end end SHAKE\_IS\_RUNNING = false end -- Add runtime listeners -- Runtime:addEventListener ("accelerometer", onAccelerate) main()
I tried to set physics.setContinuous to false but with no change. It was set to 30 FPS but I changed it to 60 to try it out but unfortunately it didn’t change anything either.
Isn’t there a setting so I can set the bodyType to “superstatic” (or "mounteverest) or something so nothing except the ball (I called it the item in the orignal post) will be affected by the collision and the “superstatic” will just be rock, solid hard?
Then I create an rectangle, which is an colliding item which the ball can bounce on (and should not go through):
if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRect(xGenerator[1], 600, lengthGenerator[1], 20) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "static") row[rowCounter + MAX\_ROWS].gravityScale = 0 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack()
And at the top I have set the physics like this (And I have also tried several parts which are commented):
local physics = require "physics" physics.start() physics.setContinuous( false ) -- physics.setScale(200) --physics.setVelocityIterations( 30 ) -- 3 --physics.setPositionIterations( 80 ) -- 8 -- 10 - 100 Hz (i.e. 10 - 100 checks per seconds, keep it low if possible, drains the battery) system.setAccelerometerInterval(100)
Here is a video how it acts (It’s a little bit laggy but you can still see sometimes when the ball go through the rectangles):
Just quickly scanning your code, I don’t see anything obviously wrong. But even more helpful would be a completely standalone example that Brent or I could run ourselves – otherwise it’s a bit hard to debug.
The video is helpful. How did you implement the vertical scrolling? Depending on how you’ve implemented it, that could be the source of the issue.
The ball is affected by gravity so it goes down through that, the rows doesn’t have any gravity and it’s y variable is called by moveRows which is called by moveScreen which is called by a listener:
Maybe that might be something? Maybe the force between those two items is to strong or maybe when both the ball and row collides the collision body from the ball and the row crosses over and therefore the balls go through?
Here is all the code if it might help you see something:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- local isSimulator = "simulator" == system.getInfo("environment") -- Your code here local physics = require "physics" physics.start() physics.setContinuous( false ) -- physics.setScale(200) --physics.setVelocityIterations( 30 ) -- 3 --physics.setPositionIterations( 80 ) -- 8 -- 10 - 100 Hz (i.e. 10 - 100 checks per seconds, keep it low if possible, drains the battery) system.setAccelerometerInterval(100) local row -- Each row can contain several rectangle local ball local frameCounter local rowCounter local MAX\_ROWS = 11 local BASE\_SPEED = 15 local scoreRectangle local score local scoreText local floor local roof local leftwall local rightwall local centerX = display.contentWidth / 2 local centerY = display.contentHeight / 2 local WIDTH = display.contentWidth local HEIGHT = display.contentHeight -- Variables to control the game flow local ROW\_SPACE = 25 local MIN\_LENGTH = 35 local MAX\_LENGTH = 75 local MAX\_RECTANGLES = 2 local scoreTable -- Makes sure the game parameters (if score \> 1000) will only be runned once -- Help variables local xGenerator local lengthGenerator function main() startGame() end function startGame() Runtime:addEventListener("enterFrame", moveScreen) scoreRectangle = display.newRect(0,0, WIDTH, 25) scoreRectangle:setFillColor(205,92,92) scoreRectangle.alpha = 0.8 print("Start Game") frameCounter = 0 rowCounter = 1 -- How many rows have passed? score = 0 scoreTable = {} scoreText = display.newText("0", 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) ball = display.newImage("ball.png") ball.x = 20 ball.y = 25 physics.addBody(ball, "dynamic", {shape = circle, radius = 8}) ball.isBullet = true floor = display.newRect(0, HEIGHT, WIDTH, 0) floor.strokeWidth = 3 floor:setFillColor(140, 140, 140) floor:setStrokeColor(180, 180, 180) physics.addBody(floor, "static") roof = display.newRect(0, -1, WIDTH, 0) roof.strokeWidth = 3 roof:setFillColor(140, 140, 140) roof:setStrokeColor(180, 180, 180) physics.addBody(roof, "static") roof:addEventListener("collision", roofOnCollision) leftwall = display.newRect(0, 0, 1, HEIGHT) leftwall.strokeWidth = 3 leftwall:setFillColor(140, 140, 140) leftwall:setStrokeColor(180, 180, 180) physics.addBody(leftwall, "static") rightwall = display.newRect(WIDTH, 0, 1, HEIGHT) rightwall.strokeWidth = 3 rightwall:setFillColor(140, 140, 140) rightwall:setStrokeColor(180, 180, 180) physics.addBody(rightwall, "static") drawStartRows() end function removeListeners() Runtime:removeEventListener ("accelerometer", onAccelerate); Runtime:removeEventListener("enterFrame", moveScreen) end function moveScreen() frameCounter = frameCounter + 1 moveRows() BASE\_SPEED = BASE\_SPEED + 0.001 score = score + BASE\_SPEED -- Update Score scoreText:removeSelf() scoreText = nil scoreText = display.newText(math.floor(score), 5, 3, native.systemFont, 18) scoreText:setTextColor(255, 255, 255) -- Verify if the row contains several rectangles local isMultiRect if row[rowCounter].multiRect == true then isMultiRect = true else isMultiRect = false end -- Verify if the row is after screen local isAfterScreen if isMultiRect then if row[rowCounter][1].y \< 0 then isAfterScreen = true else isAfterScreen = false end else if row[rowCounter].y \< 0 then isAfterScreen = true else isAfterScreen = false end end -- Add a new rectangle if isAfterScreen then -- Remove old rectangle if isMultiRect then for i = 1, #row[rowCounter] do row[rowCounter][i]:removeSelf() row[rowCounter][i] = nil end else row[rowCounter]:removeSelf() row[rowCounter] = nil end local numberOfRectangles = math.random(1,MAX\_RECTANGLES) if numberOfRectangles == 1 then -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values generatePositions(1) row[rowCounter + MAX\_ROWS] = display.newRect(xGenerator[1], 600, lengthGenerator[1], 20) row[rowCounter + MAX\_ROWS].strokeWidth = 3 row[rowCounter + MAX\_ROWS]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS], "static") row[rowCounter + MAX\_ROWS].gravityScale = 0 row[rowCounter + MAX\_ROWS].isBullet = true row[rowCounter + MAX\_ROWS].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = false row[rowCounter + MAX\_ROWS]:toBack() elseif numberOfRectangles \> 1 then row[rowCounter + MAX\_ROWS] = {} generatePositions(tonumber(numberOfRectangles)) for i = 1, numberOfRectangles do -- Add a new rectangle. Will create based on the rowCounter + MAX\_ROWS -- If MAX\_ROWS = 15 then we need to create 15 rows during startGame() so there will be no nil values row[rowCounter + MAX\_ROWS][i] = display.newRect(xGenerator[i], 600, lengthGenerator[i], 20) row[rowCounter + MAX\_ROWS][i].strokeWidth = 3 row[rowCounter + MAX\_ROWS][i]:setFillColor(140, 140, 140) row[rowCounter + MAX\_ROWS][i]:setStrokeColor(180, 180, 180) physics.addBody(row[rowCounter + MAX\_ROWS][i], "static") row[rowCounter + MAX\_ROWS][i].isBullet = true row[rowCounter + MAX\_ROWS][i].gravityScale = 0 row[rowCounter + MAX\_ROWS][i].isFixedRotation = true row[rowCounter + MAX\_ROWS].multiRect = true row[rowCounter + MAX\_ROWS].noOfRectangles = numberOfRectangles row[rowCounter + MAX\_ROWS][i]:toBack() end end rowCounter = rowCounter + 1 end end function roofOnCollision(event) print("Collision") removeOldData() roof:removeEventListener("collision", roofOnCollision) removeListeners() timer.performWithDelay(50, startGame) end function removeOldData() print("removeOldData") print(BASE\_SPEED) ball:removeSelf() ball = nil scoreText:removeSelf() scoreText = nil floor:removeSelf() floor = nil leftwall:removeSelf() leftwall = nil rightwall:removeSelf() rightwall = nil scoreRectangle:removeSelf() scoreRectangle = nil -- When the first value becomes nil in a table the #row count will be zero therefore I need to delete the different rows like this -- http://lua-users.org/wiki/StoringNilsInTables for i = 1, rowCounter + MAX\_ROWS do if row[i] ~= nil then if row[i].multiRect == true then for j = 0, row[i].noOfRectangles do if row[i][j] ~= nil then row[i][j]:removeSelf() row[i][j] = nil end end elseif row[i].multiRect == false then row[i]:removeSelf() row[i] = nil end end end row = nil end function drawStartRows() row = {} -- Contains a total of 15 rectangles (lines) row[1] = display.newRect(50, 100, 150, 20) row[1].strokeWidth = 3 row[1]:setFillColor(140, 140, 140) row[1]:setStrokeColor(180, 180, 180) physics.addBody(row[1], "static") row[1].gravityScale = 0 row[1].isFixedRotation = true row[1].multiRect = false row[2] = display.newRect(50, 150, 150, 20) row[2].strokeWidth = 3 row[2]:setFillColor(140, 140, 140) row[2]:setStrokeColor(180, 180, 180) physics.addBody(row[2], "static") row[2].gravityScale = 0 row[2].isFixedRotation = true row[2].multiRect = false row[3] = display.newRect(50, 200, 150, 20) row[3].strokeWidth = 3 row[3]:setFillColor(140, 140, 140) row[3]:setStrokeColor(180, 180, 180) physics.addBody(row[3], "static") row[3].gravityScale = 0 row[3].isFixedRotation = true row[3].multiRect = false row[4] = display.newRect(50, 250, 150, 20) row[4].strokeWidth = 3 row[4]:setFillColor(140, 140, 140) row[4]:setStrokeColor(180, 180, 180) physics.addBody(row[4], "static") row[4].gravityScale = 0 row[4].isFixedRotation = true row[4].multiRect = false row[5] = display.newRect(50, 300, 150, 20) row[5].strokeWidth = 3 row[5]:setFillColor(140, 140, 140) row[5]:setStrokeColor(180, 180, 180) physics.addBody(row[5], "static") row[5].gravityScale = 0 row[5].isFixedRotation = true row[5].multiRect = false row[6] = display.newRect(50, 350, 150, 20) row[6].strokeWidth = 3 row[6]:setFillColor(140, 140, 140) row[6]:setStrokeColor(180, 180, 180) physics.addBody(row[6], "static") row[6].gravityScale = 0 row[6].isFixedRotation = true row[6].multiRect = false row[7] = display.newRect(50, 400, 150, 20) row[7].strokeWidth = 3 row[7]:setFillColor(140, 140, 140) row[7]:setStrokeColor(180, 180, 180) physics.addBody(row[7], "static") row[7].gravityScale = 0 row[7].isFixedRotation = true row[7].multiRect = false row[8] = display.newRect(50, 450, 150, 20) row[8].strokeWidth = 3 row[8]:setFillColor(140, 140, 140) row[8]:setStrokeColor(180, 180, 180) physics.addBody(row[8], "static") row[8].gravityScale = 0 row[8].isFixedRotation = true row[8].multiRect = false row[9] = display.newRect(50, 500, 150, 20) row[9].strokeWidth = 3 row[9]:setFillColor(140, 140, 140) row[9]:setStrokeColor(180, 180, 180) physics.addBody(row[9], "static") row[9].gravityScale = 0 row[9].isFixedRotation = true row[9].multiRect = false row[10] = display.newRect(50, 550, 150, 20) row[10].strokeWidth = 3 row[10]:setFillColor(140, 140, 140) row[10]:setStrokeColor(180, 180, 180) physics.addBody(row[10], "static") row[10].gravityScale = 0 row[10].isFixedRotation = true row[10].multiRect = false row[11] = display.newRect(50, 600, 150, 20) row[11].strokeWidth = 3 row[11]:setFillColor(140, 140, 140) row[11]:setStrokeColor(180, 180, 180) physics.addBody(row[11], "static") row[11].gravityScale = 0 row[11].isFixedRotation = true row[11].multiRect = false end function moveRows() local intCounter = 0 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end intCounter = intCounter + 1 if row[rowCounter + intCounter].multiRect == true then for i = 1, row[rowCounter + intCounter].noOfRectangles do row[rowCounter + intCounter][i].y = row[rowCounter + intCounter][i].y - BASE\_SPEED end else row[rowCounter + intCounter].y = row[rowCounter + intCounter].y - BASE\_SPEED end end -- Game logic methods -- Start position function generatePositions(numberOfRectangles) xGenerator = {} lengthGenerator = {} if numberOfRectangles \> 1 then xGenerator[1] = math.random(-150, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH, MAX\_LENGTH) for i = 2, numberOfRectangles do local value = xGenerator[i-1] + lengthGenerator[i-1] + ROW\_SPACE xGenerator[i] = math.random(value, value + math.random(MIN\_LENGTH,MAX\_LENGTH)) lengthGenerator[i] = math.random(MIN\_LENGTH,MAX\_LENGTH) end elseif numberOfRectangles == 1 then xGenerator[1] = math.random(0, WIDTH) lengthGenerator[1] = math.random(MIN\_LENGTH,MAX\_LENGTH) end -- Change Game Parameters if score \> 1000 and scoreTable[1] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[1] = 1 elseif score \> 2000 and scoreTable[2] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[2] = 1 elseif score \> 3000 and scoreTable[3] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[3] = 1 elseif score \> 4000 and scoreTable[4] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[4] = 1 elseif score \> 5000 and scoreTable[5] == nil then MIN\_LENGTH = MIN\_LENGTH + 5 MAX\_LENGTH = MAX\_LENGTH + 5 scoreTable[5] = 1 end end -- Gyroscope event local function onAccelerate( event ) ball.x = display.contentCenterX - (display.contentCenterX \* (event.yGravity \* 3)) if((ball.x - ball.width \* 0.5) \< 0) then ball.x = ball.width \* 0.5 elseif((ball.x + paddle.width \* 0.5) \> display.contentWidth) then ball.x = display.contentWidth - ball.width \* 0.5 end end -- Add runtime listeners -- Runtime:addEventListener ("accelerometer", onAccelerate); main()
OK, I was able to run it. Note that I had to replace ball.png with display.newCircle.
Your issue is that you’re moving the rectangles by directly modifying their y-coordinates. That’s not going to work with physics and collision detection. The rectangles will instantly “jump” from one position to another, and they won’t trigger a collision with the ball. (This is what I had in mind when I said above that it depends on how you’ve implemented it.)
With physics objects, you shouldn’t directly modify their coordinates unless you’re placing them in their initial position or you truly want them to jump from one position to another. If you want to move them, you should modify their physical properties like velocity, or apply forces to them, or use a touch joint. In your case, probably the best solution is to make your rectangles kinematic, give them an upward velocity, and set their gravity scale to zero to they don’t fall.
(As a side suggestion about your coding, your moveRows function could be simplified a lot if you just put it into a loop.)