0
我一直在製作塔防遊戲。所以基本上我有一個循環,使得一個顯示對象的表格是坦克,並向他們添加物理實體。然後它「給坦克」一個叫做moveTank的功能來實際移動它們。Corona SDK:從表格中刪除顯示對象
但是爲了節省內存,我想刪除物理體並在屏幕外顯示obejct。在234行的星星的代碼。在模擬器中,如果你測試只是刪除物理體,一切正常。但是,如果我刪除顯示對象(也許我做錯了?)它會刪除圖像,但其他一些函數使用它會給出錯誤,說我試圖比較一個數字與零值@第229行。nil的值是被刪除的對象,我設置它的屬性isMoving和isAlive爲false,爲什麼它甚至試圖執行操作?
任何人都可以幫我完成這部分嘗試刪除沒有錯誤的顯示對象嗎?
local storyboard = require("storyboard")
local scene = storyboard.newScene()
local physics = require "physics"
physics.start()
physics.setGravity(0, 0)
physics.setDrawMode("hybrid")
local screenW, screenH, halfW, halfH = display.contentWidth, display.contentHeight, display.contentWidth*0.5, display.contentHeight*0.5
local tanks = {}
local tickCnt = 0
local TOTAL_TANKS = 2
local tankCnt = 1
function AddCommas(number, maxPos)
local s = tostring(number)
local len = string.len(s)
if len > maxPos then
-- Add comma to the string
local s2 = string.sub(s, -maxPos)
local s1 = string.sub(s, 1, len - maxPos)
s = (s1 .. "," .. s2)
end
maxPos = maxPos - 3 -- next comma position
if maxPos > 0 then
return AddCommas(s, maxPos)
else
return s
end
end
function tickCntFunct()
if tickCnt <= 2000 then
tickCnt = tickCnt + 25
print("tick count", tickCnt)
else
tickCnt = 0
end
end
timer.performWithDelay(10, tickCntFunct, 0)
function moveTank(aTank)
local mSpeed = 150
rSpeed = 6
if aTank.isAlive == true and aTank.isKilled == false then
print("aTank.x = ", aTank.x)
print("aTank.y = ", aTank.y)
print("tank rotation = ", aTank.rotation)
local disP1 = math.sqrt((math.abs(aTank.x - pointer1.x))^2 + (math.abs(aTank.y - pointer1.y))^2)
local disP2 = math.sqrt((math.abs(aTank.x - pointer2.x))^2 + (math.abs(aTank.y - pointer2.y))^2)
local disP3 = math.sqrt((math.abs(aTank.x - pointer3.x))^2 + (math.abs(aTank.y - pointer3.y))^2)
local disP4 = math.sqrt((math.abs(aTank.x - pointer4.x))^2 + (math.abs(aTank.y - pointer4.y))^2)
removeTanknumber = 0
if aTank.x < 0 then
aTank.rotation = 90
aTank:setLinearVelocity(mSpeed, 0)
end
if aTank.rotation < 180 and disP1 < 1 then
aTank:setLinearVelocity(0, 0)
aTank.rotation = aTank.rotation + rSpeed
end
if aTank.rotation >= 180 and disP1 < 1 then
aTank.rotation = 180
aTank:setLinearVelocity(0, mSpeed)
end
if aTank.rotation > 90 and disP2 < 1 then
aTank:setLinearVelocity(0, 0)
aTank.rotation = aTank.rotation - rSpeed
end
if aTank.rotation <= 90 and disP2 < 1 then
aTank.rotation = 90
aTank:setLinearVelocity(mSpeed, 0)
end
if aTank.rotation > 0 and disP3 < 1 then
aTank:setLinearVelocity(0, 0)
aTank.rotation = aTank.rotation - rSpeed
end
if aTank.rotation <= 0 and disP3 < 1 then
aTank.rotation = 0
aTank:setLinearVelocity(0, -1*mSpeed)
end
if aTank.rotation < 90 and disP4 < 1 then
aTank:setLinearVelocity(0, 0)
aTank.rotation = aTank.rotation + rSpeed
end
if aTank.rotation >= 90 and disP4 < 1 then
aTank.rotation = 90
aTank:setLinearVelocity(mSpeed, 0)
end
end
end
timer.performWithDelay(1, moveTank, 0)
function scene:createScene(event)
local group = self.view
pointersGroup = display.newGroup()
mapGroup = display.newGroup()
-- create a grey rectangle as the backdrop
map = display.newImage("map1.png")
map:setReferencePoint(display.TopLeftReferencePoint)
map.x = 0
map.y = 0
spawner = display.newImage("pointer.png")
spawner:setReferencePoint(display.CenterReferencePoint)
spawner.y = 210
spawner.x = -40
pointer1 = display.newImage("pointer.png")
pointer1:setReferencePoint(display.CenterReferencePoint)
pointer1.x = 210
pointer1.y = 210
pointer2 = display.newImage("pointer.png")
pointer2:setReferencePoint(display.CenterReferencePoint)
pointer2.x = 210
pointer2.y = 390
pointer3 = display.newImage("pointer.png")
pointer3:setReferencePoint(display.CenterReferencePoint)
pointer3.x = 510
pointer3.y = 390
pointer4 = display.newImage("pointer.png")
pointer4:setReferencePoint(display.CenterReferencePoint)
pointer4.x = 510
pointer4.y = 90
sideBlock = display.newImage("side_block.png")
physics.addBody(sideBlock, "static", { friction=0.5, bounce=0.3 })
sideBlock:setReferencePoint(display.CenterReferencePoint)
sideBlock.x = screenW - 100
sideBlock.y = screenH/2
-- all display objects must be inserted into group
pointersGroup:insert(spawner)
pointersGroup:insert(pointer1)
pointersGroup:insert(pointer2)
pointersGroup:insert(pointer3)
pointersGroup:insert(pointer4)
pointersGroup:insert(sideBlock)
mapGroup:insert(map)
group:insert(pointersGroup)
group:insert(mapGroup)
end
function scene:enterScene(event)
local group = self.view
for i = 1, TOTAL_TANKS do
-- create 5 tanks, place them off screen, set their status to isAlive and not isMoving
table.insert(tanks, display.newImage("tank.png"))
print("memory (all spawned): ", AddCommas(system.getInfo("textureMemoryUsed"), 9) .. " bytes")
tanks[i]:setReferencePoint(display.CenterReferencePoint)
tanks[i]:scale(0.75, 0.75)
tanks[i].x = spawner.x
tanks[i].y = spawner.y
tanks[i].isAlive = true
tanks[i].isMoving = false
tanks[i].isKilled = false
end
local function gameLoop(event)
-- normally should not have loops inside the game loop, because
-- if there is too much going on during each frame call it can cause issues
-- but for moving only 5 tanks, this is how you can do it.
-- each tank will call the same function above (moveTank)
-- have a variable that you would check here, to see if 'so many ticks or seconds'
-- has passed, and if so, set the isMoving to true for the next tank .. will just use
-- a simple incremented variable 'tickCnt'
if tickCnt > 2000 and tankCnt <= TOTAL_TANKS then
physics.addBody(tanks[tankCnt], { density=3.0, friction=0.5, bounce=0.3 })
tanks[tankCnt].isMoving = true
print("tankCnt= ", tankCnt)
tankCnt = tankCnt + 1
print("memory (moving): ", AddCommas(system.getInfo("textureMemoryUsed"), 9) .. " bytes")
end
for i=1, TOTAL_TANKS do
if tanks[i].isMoving == true and tanks[i].isAlive == true and tanks[i].isKilled == false then
moveTank(tanks[i])
end
end
for i = 1, TOTAL_TANKS do
if tanks[i].x >= 40 and tanks[i].isKilled == false then
tanks[i].isKilled = true
tanks[i].isMoving = false
tanks[i].isAlive = false
physics.removeBody(tanks[i])
display.remove(tanks[i])
tanks[i] = nil
end
end
end
Runtime:addEventListener("enterFrame", gameLoop)
physics.start()
end
function scene:exitScene(event)
local group = self.view
physics.stop()
end
function scene:destroyScene(event)
local group = self.view
package.loaded[physics] = nil
physics = nil
end
--------------------------------------------------------------------------------------- --
-- END OF YOUR IMPLEMENTATION
-----------------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener("createScene", scene)
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener("enterScene", scene)
-- "exitScene" event is dispatched whenever before next scene's transition begins
scene:addEventListener("exitScene", scene)
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener("destroyScene", scene)
-----------------------------------------------------------------------------------------
return scene