0

我一直在做一个塔防游戏。所以基本上我有一个循环来制作一个显示对象的表格,这些对象是坦克,并向它们添加物理体。然后它“将坦克”交给一个名为 moveTank 的函数来实际移动它们。

但是,为了节省内存,我想删除物理体并在它离开屏幕后显示对象本身。该代码在第 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
4

1 回答 1

0

尝试从最后一个坦克循环到第一个坦克。

于 2012-05-28T22:00:01.850 回答