如何使用Corona SDK有效处理对象的移除
刚开始研究很棒的 Corona SDK。
我开始构建一个简单的射击游戏。
我有以下代码:
- 全局变量
local shot = audio.loadSound('shot.mp3')
local bg = display.newImage('bg.png')
local shoot = {}
local Main = {}
local Init = {}
local bullets = display.newGroup()
function update()
if(bullets.numChildren ~= 0) then
for i = 1, bullets.numChildren do
bullets[i].y = bullets[i].y - 8
- 销毁场景外的子弹
if(bullets[i].y < (-bullets[i].height-5)) then
- bullets[i]:removeSelf()
bullets:remove(bullets[i])
display.remove(bullets[i])
return
end
end
end
end
- 初始化函数
function Init ()
display.setStatusBar(display.HiddenStatusBar)
local movieclip = require('movieclip')
local physics = require('physics')
physics.start()
physics.setGravity(0, 0)
end
function shoot:tap(e)
for i = 1, 15 do
local bullet = display.newImage('bullet.png')
bullet.x = 150
bullet.y = 470
bullet.name = 'bullet'
physics.addBody(bullet)
bullets.insert(bullets, bullet)
end
audio.play(shot)
end
- 主要例程
function Main ()
Init()
bg:addEventListener('tap', shoot)
Runtime:addEventListener('enterFrame', update)
end
Main()
目前它“工作”了;但是当子弹离开屏幕时,整个“游戏”会减慢,并且我可以清楚地看到每个子弹被删除而减慢了游戏。
也许我做错了;也尝试了:removeSelf()函数;结果相同。
原文链接 https://stackoverflow.com/questions/7705439
我在我的游戏中长时间地与对象去除进行斗争,而这个游戏使用了很多分级视图。我找到的解决方法是在所有需要删除的对象上使用 = nil
, :removeSelf()
以及 .alpha = 0
。如果它们都被添加到同一组中,而且该组中没有其他内容,那么也可以使用,但由于组后台设置的各种原因,它并不总是有效。
看起来你已经删除了“子弹”的内容,但那只是一个引用,所以当你说每个子弹都被删除时,实际上它只是从数组中删除了,对象本身仍然存在,需要将其设为 nil
以防止内存泄漏和应用减速(你可能已经发现每个子弹都会减慢应用程序速度,对吗?)
在删除后添加此条件,你就可以解决问题了:
if(not(bullet == nil)) then
bullet.alpha = 0;
bullet:removeSelf();
bullet = nil;
end
更容易的方法是创建一个表格,像这样
local bulletCache = {}
然后在你的子弹创建代码中添加
table.insert(bulletCache, myBulletObject)
然后在你的退出代码和/或销毁代码中,说
for i = 1, #bulletCache do
--[[
--以下不需要但只是为了让你的代码一致
pcall(function()
bullet.alpha = 0
end)
--]]
pcall(function()
bullet:removeSelf()
end)
pcall(function()
bullet = nil
end)
end
首先,永远不要试图在GameLoop中执行任何类型的循环。这会降低游戏的帧率,因为它通常需要更多的内存。
现在,似乎您只想在子弹从屏幕上消失时销毁它们,并且您也正在使用物理,那么为什么不利用这一点呢?
以下是您应该遵循的步骤。 (如果您有任何疑问或困难,请向我提问)
1.在屏幕上方略微绘制一个静态物理线。假定y为-20。
local _yLimit = -20
local _limitLine = display.newLine(0,_yLimit,display.contentWidth,_yLimit)
_limitLine.anchorX = 0
_limitLine.anchorY = 0
2.将所有子弹添加为物理对象。
3.在子弹的底部中心施加力,而不是变换它。[假设子弹具有矩形物理形状,否则决定形状的平衡点]
4.借助“collision”事件侦听器检测碰撞。
5.在碰撞时销毁子弹
这就是简单的方法 :)
如果您仍然存在问题,请告诉我。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我遇到了同样的问题...并且找到了解决办法:
你正在使用 for 循环删除对象: 如果你在循环中删除对象,比如说你删除了 index 为 1 的对象,那么对象 2 就会移动到对象 1 的位置...所以当循环到对象 2 时,它就不会再检查对象 2(因为它已经移动到对象 1 的位置,而你正在检查对象 3)
for j = 1, buttonGroup.numChildren do buttonGroup[1]:removeSelf(); --这将删除所有的子对象 end for j = 1, buttonGroup.numChildren do buttonGroup[j]:removeSelf(); --这将删除交替的子对象 end
希望有用。