Solar2d Lua开发:气球点击无响应及表格对象移除问题求助
戳气球游戏点击无响应及Table移除问题
我正在跟着Solar2d教程做戳气球游戏,想把气球存在table里,点击让气球消失,但加了事件监听器后点击没反应。有两个问题:
- 怎么实现点击移除气球图像?
- 该在哪里加代码从table里移除被点击的气球?需要在gameLoop里用for循环吗?
之前尝试把事件监听器放在气球创建函数外,出现了“nil value”错误,附上代码:
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- --prep the physics local physics = require("physics") physics.start() physics.setGravity(0, -20) --seed the random number generator math.randomseed( os.time() ) --prep the graphic groups local backGroup = display.newGroup() local mainGroup = display.newGroup() local uiGroup = display.newGroup() --prep variables local newBalloon local tappedBalloon local balloonTable = {} --load background local background = display.newImageRect(backGroup, "pictures/mainGroup/background.png", 360, 570) background.x = display.contentCenterX background.y = display.contentCenterY --load boundaries local border = display.newImageRect(mainGroup, "pictures/mainGroup/border.png", 281, 35) border.x = display.contentCenterX border.y = display.contentHeight-440 physics.addBody( border, "static" ) local function popBalloon( event ) local tappedBalloon = event.target if event.phase == "began" then display.remove(tappedBalloon) --removing balloon from table? end end --creating and storing balloons local function createBalloon () local newBalloon = display.newImageRect(mainGroup, "pictures/mainGroup/balloon2.png", 118, 118) if newBalloon then table.insert(balloonTable, newBalloon) physics.addBody( newBalloon, "dynamic", { radius=50, bounce=0.2 } ) --newBalloon.isBullet = true newBalloon.alpha = 0.8 newBalloon.myName = "balloon" newBalloon:addEventListener("tap", popBalloon) end local placement = math.random(3) if (placement == 1) then newBalloon.x = math.random( display.contentWidth ) newBalloon.y = math.random( 250,500 ) elseif ( placement == 2 ) then newBalloon.x = math.random( display.contentWidth ) newBalloon.y = math.random( 250,500 ) elseif ( placement == 3 ) then newBalloon.x = math.random( display.contentWidth ) newBalloon.y = math.random( 250,500 ) end end local function gameLoop() createBalloon() end gameLoopTimer = timer.performWithDelay( 500, gameLoop)
问题1:实现点击移除气球图像
你的核心错误是给tap事件加了event.phase == "began"判断——tap事件没有phase属性,只有touch事件才会返回阶段信息。直接去掉这个判断,或者把事件换成touch并保留阶段判断即可。
另外,调用display.remove()后,建议把对象设为nil,避免内存泄漏。
问题2:从Table中移除被点击的气球
不需要在gameLoop里做循环,直接在点击事件处理函数里遍历table找到对应气球移除就行。因为每个气球对象是唯一的,用ipairs或倒序遍历table,找到和event.target匹配的元素后用table.remove()删除即可。
修改后的完整代码
----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- --prep the physics local physics = require("physics") physics.start() physics.setGravity(0, -20) --seed the random number generator math.randomseed( os.time() ) --prep the graphic groups local backGroup = display.newGroup() local mainGroup = display.newGroup() local uiGroup = display.newGroup() --prep variables local balloonTable = {} --load background local background = display.newImageRect(backGroup, "pictures/mainGroup/background.png", 360, 570) background.x = display.contentCenterX background.y = display.contentCenterY --load boundaries local border = display.newImageRect(mainGroup, "pictures/mainGroup/border.png", 281, 35) border.x = display.contentCenterX border.y = display.contentHeight-440 physics.addBody( border, "static" ) local function popBalloon( event ) local tappedBalloon = event.target -- 移除显示对象 display.remove(tappedBalloon) -- 倒序遍历table,避免删除元素后索引混乱 for i = #balloonTable, 1, -1 do if balloonTable[i] == tappedBalloon then table.remove(balloonTable, i) break end end tappedBalloon = nil end --creating and storing balloons local function createBalloon () local newBalloon = display.newImageRect(mainGroup, "pictures/mainGroup/balloon2.png", 118, 118) if newBalloon then table.insert(balloonTable, newBalloon) physics.addBody( newBalloon, "dynamic", { radius=50, bounce=0.2 } ) newBalloon.alpha = 0.8 newBalloon.myName = "balloon" -- 使用tap事件,无需phase判断 newBalloon:addEventListener("tap", popBalloon) end -- 三个分支逻辑完全重复,直接简化 newBalloon.x = math.random( display.contentWidth ) newBalloon.y = math.random( 250,500 ) end local function gameLoop() createBalloon() end gameLoopTimer = timer.performWithDelay( 500, gameLoop)
额外优化点
- 移除了冗余的全局变量
newBalloon和tappedBalloon,改用函数内局部变量,避免全局污染。 - 简化了气球随机位置的代码,三个分支逻辑完全一致,无需多做判断。
内容的提问来源于stack exchange,提问作者laatto
相关产品推荐
相关产品推荐

