What is the best way to remove all spawned coins when the game is over?
Here is the code that spawns the coins:
screenGroup = self.view
coin = {}
coinspawn = function()
i = display.newSprite( imageSheet1, sequenceData1 )
i.x = display.contentWidth
i.y = math.random(0, display.contentHeight-50)
i:play()
i.collided = true
i.name = "coin"
physics.addBody(i, "dynamic",
{density=.1, bounce=0.1, friction=.2, shape= shape2 ,filter=playerCollisionFilter }
)
--player.gravityScale = 0.5
coinIntro = transition.to(i,{time=2500, x=display.contentWidth - display.contentWidth -500 ,onComplete=jetReady , transition=easing.OutExpo } ) --
coin[#coin+1] = i
end
tmrcoin = timer.performWithDelay( 1000, coinspawn, 0 )
First you would remove all coins from the display. Then you would clear the coin table:
for i=1,#coin do
coin[i]:removeSelf()
end
coin = {} -- forget all coins
Assuming coin table is the only other place you store your coins, this will do it.
Note that you can't use coin[i]=nil in the loop after removeSelf: as soon as table has holes, the # operator is basically unusable. You can't use table.remove either, because i gets incremented every time, so you'll miss items (try, you'll see). Same issue with pairs: you can't edit a table while iterating through it. You could however do this:
local numCoins = #coin
for i=1,numCoins do
coin[i]:removeSelf()
coin[i]=nil
end
-- now coin is {}
The only reason I can think of to nil N items instead of letting the gc take care of it with one table = {} statement is if you have more than one reference to your coin table (which I would rename to coins, BTW, for clarity).
Related
I'm trying to create a function that would choose one of four objects from a table that would then create it. Essentially what's meant to happen is if objects 1-3 are chosen they would be considered "regular" and the "player" would have to catch them while the fourth object is "special" and would take points away if caught.
here's the table
local objects = {
"object1",
"object2",
"object3",
"object4"
}
this is the code I'm using in place of what I want currently (mostly to make sure everything else in my code is working)
local function spawnObject()
object = display.newImage("images/object1.png")
object.x = math.random(screenLeft+ 30, screenRight-30)
object.y = screenTop-100
object.width = 100
object.height = 100
object.Number = 1
object.type = "regular"
object.score = 5
object.rotation = math.random(-20,20)
physics.addBody(object, "dynamic", {density =1, friction =1, bounce = .5})
end
Start with this...
local function spawnObject()
local objects = {
"object1",
"object2",
"object3",
"object4"
}
object = display.newImage("images/"..objects[math.random(3)]..".png")
object.x = math.random(screenLeft+ 30, screenRight-30)
object.y = screenTop-100
object.width = 100
object.height = 100
object.Number = 1
object.type = "regular"
object.score = 5
object.rotation = math.random(-20,20)
physics.addBody(object, "dynamic", {density =1, friction =1, bounce = .5})
end
...for choosing 1-3.
If you dont like math.random(3) you can do a table.remove(objects,1) 3 times so it is clear the 4th time is the special one.
But then have to be objects global ( outside function and not local ).
...you have to check for.
Hello I'm am using Marmalde Quick, so lua to create a game.
In my game when a park of the screen in tuched it creates a new note and add that note to physics.
function bgTouched(event)
if (director:getCurrentScene() == gameScene) then
if (gameState == gameStates.playing) then
if event.phase == "began" then
addToRoundScore()
if bodyType == 0 then
-- Create object1
b = director:createSprite(event.x, event.y, "textures/beachball.png")
b.name = "ball"
b.strokeWidth=0
b.xAnchor = 1; b.yAnchor = 0 -- test non-0 anchor point for circle
physics:addNode(b, {radius=40})
elseif bodyType == 1 then
-- Create object2
b = director:createSprite(event.x, event.y, "textures/crate.png")
b.name = "crate"
b.strokeWidth=0
b.xAnchor = 0; b.yAnchor = 0.5 -- test non-0 anchor point for rectangle
b.xScale = 2; b.yScale = 1 -- test different scale
physics:addNode(b, {} )
elseif bodyType == 2 then
-- Create obejct3
b = director:createSprite(event.x, event.y, "textures/triangle.png")
b.name = "tri"
b.xAnchor = 0.5; b.yAnchor = 1 -- test non-0 anchor point for polygon
physics:addNode(b, {shape={0,0, 95,0, 48,81}} )end
b.rotation = 22.5
bodyType = (bodyType + 1) % 3
end
end
end
end
bg:addEventListener ("touch", bgTouched)
when an event happens I want to remove all the notes created, I tried using the following:
physics:removeNode(b)
b:removeFromParent()
but this only removes the last created not I want to remove them all, is there some way to do this.
Thanks
If I understand right that you want to clear the nodes table before the event.phase == "began" processing where you add nodes, you could reset the physics table:
physics = {}
If other parts of code are referencing the physics node and they can't be notified that physics points to a new table, you could loop over all items of table and nil them:
for k,v in pairs(physics)
physics[k] = nil
end
Hi my objects are not removing after leaving the scene, i have tried to purging and removing the scene, but the objects will just keep on spawning in a other scene?
local badclout1 = {}
local bad1Group = display.newGroup()
local function spawnBC1()
local badclouts1 = display.newImage("BCloud1.png")
badclouts1.x = math.random(0, _W)
physics.addBody( badclouts1, "dynamic", { density=.1, bounce=.1, friction=.2, radius=45 } )
badclouts1.name = "BCloud1"
badclouts1.bodyType = "kinematic"
badclouts1.isSensor = true
badclouts1.y = math.random(-100, -50)
badclouts1.index = #badclout1 + 1
bad1Group:insert(badclouts1)
badclouts1.rotation = math.random(-10,10) -- Rotate the object
badclouts1:setLinearVelocity(0, math.random(speeda1, speedb1)) -- Drop down
badclout1[badclouts1.index] = badclouts1
tmrSpawn1 = timer.performWithDelay(math.random(spawna, spawnb), spawnBC1)
return badclouts1
end
tmrSpawn1 = timer.performWithDelay(math.random(1000, 10000), spawnBC1)
local function removeBomb()
for i, v in pairs(badclout1) do
if badclout1[i].y >1000 then
badclout1[i]:removeSelf()
badclout1[i] = nil
end
end
end
Runtime:addEventListener("enterFrame", removeBomb)
is there something in my code that keeps it on the screen ?
You need to cancel your performWithDelay function using timer.cancel(tmrSpawn1). Because you're calling it recursively, it will just keep going until you cancel it.
Using Corona, i would like to move object when i delete it from a table. The problem is that i iterate the table on every frame. When x > WIDTH - 50 i would like for the monkey to stop moving in a sinuswave form and jump into the removeMonkeys function.
My Code:
local function removeMonkeys(obj)
transition.to(obj, {time = 1500, y = 2*HEIGHT/3, onComplete = obj:removeSelf()})
numMonkeys = numMonkeys - 1;
end
function startGame()
timer.performWithDelay(500, spawn, maxNumMonkeys)
local function onEveryFrame( event )
for i = 1, #monkeySet do
if(monkeySet[i] ~= nil) then
monkeySet[i].x = monkeySet[i].x + 2
monkeySet[i].y = monkeySet[i].y + math.sin(monkeySet[i].x/monkeySpeed)*Amplitude/5
if(monkeySet[i].x > WIDTH -50) then
removeMonkeys(monkeySet[i])
table.remove(monkeySet, i)
print(#monkeySet)
end
end
end
end
Runtime:addEventListener( "enterFrame", onEveryFrame )
Is there anything I'm missing here?
Not sure what exactly you're asking here, but if your transition.to doesn't work check that you aren't you killing the only reference to monkeySet[i] when you do
table.remove(monkeySet, i)
I am trying to trigger a hide and a show on my table local starTable = {}
local starTable = {} -- Set up star table
local function showStarTable()
-- some trigger to show the star table
end
timer.performWithDelay( 500, showStarTable, 1 )
local function hideStarTable()
-- some trigger to hide the star table
end
timer.performWithDelay( 1000, hideStarTable, 1 )
Is it possible to achieve this
To go along with the first answer here is an example:
local starTable = {}
local star1 = <display object>
starTable:insert(star1)
local function showStarTable()
starTable.alpha = 1
end
timer.performWithDelay( 500, showStarTable, 1 )
local function hideStarTable()
starTable.alpha = 0
end
timer.performWithDelay( 1000, hideStarTable, 1 )
Or of you wanted to stick with an actual table. and without seeing what actually is inserted into your starTable you could try:
local starTable = {}
local star = <display object>
starTable[1] = star
star = <display object>
starTable[2] = star
star = <display object>
starTable[3] = star
local function showStarTable()
for i=1, #starTable do
starTable[i].star.alpha = 1
end
end
timer.performWithDelay( 500, showStarTable, 1 )
local function hideStarTable()
for i=1, #starTable do
starTable[i].star.alpha = 0
end
end
timer.performWithDelay( 1000, hideStarTable, 1 )
However, the first option is better, if it works with your program.
Your code will execute the function showStarTable() after 1/2 second for 1 time. Then in another 1/2 second, it will execute hideStarTable() once.
Display objects like display.newImageRect() are tables, so if that's the table you are referring to, you can show/hide them by changing either the .alpha property of the object or it's visibility (.isVisible = true or .isVisible = false). However tables by themselves are just containers of information and a generic table isn't displayable. It could contain a single display object ore multiple.
It would be your responsibility in your show/hide functions to show/hide the contents of the table, if the table has displayable content.