Item going through static item?

Thanks for the help, that helped a lot!

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!

Once again, thanks!

Best regards,

Tomas

No problem, glad you were able to get it to work.

  • Andrew

Glad Auk helped you out, I’ve been through this more times than I can count!

Definitely could use a for loop with the moveRows, that will save you a crap ton of typing :)_ 

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

Here is the current version:

http://www.youtube.com/watch?v=z8BEn8UjTdY

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()