如何使用 Corona SDK 有效处理对象的对象移除

发布于 2024-12-09 02:12:42 字数 1464 浏览 2 评论 0原文

刚刚开始使用很棒的 Corona sdk。

我开始构建一个简单的射击游戏。

我有以下代码:

-- Global Variables
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
            -- Destroy Offstage Bullets

            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
-- Initialisation functions
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

-- Main routine
function Main ()
    Init()
    bg:addEventListener('tap', shoot)
    Runtime:addEventListener('enterFrame', update)
end

Main()

现在它“有效”;但是当子弹从屏幕上射出时,整个“游戏”就会变慢,我可以清楚地看到每颗子弹都被移除,从而减慢了游戏速度。

也许我做得不对;还尝试了 :removeSelf() 函数;相同的结果。

just starting to play around with the awesome corona sdk.

I started building a simple shooter game.

I have the following code :

-- Global Variables
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
            -- Destroy Offstage Bullets

            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
-- Initialisation functions
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

-- Main routine
function Main ()
    Init()
    bg:addEventListener('tap', shoot)
    Runtime:addEventListener('enterFrame', update)
end

Main()

For now it 'works'; but when the bullet comes of the screen the whole 'game' slows down and I can clearly see that each bullet is removed which slows down the game.

Maybe i'm not doing it right; also tried the :removeSelf() function; same results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白馒头 2024-12-16 02:12:42

我面临着同样的问题......并得到了解决方案:

您正在使用 for 循环删除对象:
如果您在 for 循环中删除对象,则说:您删除了索引 1 处的对象,然后对象 2 移动到对象 1...所以当它循环到对象时,它不会检查对象 2(因为它移动到对象 1 的位置,并且您正在检查对象 3)

for j = 1, buttonGroup.numChildren do   
    buttonGroup[1]:removeSelf();        --this removes all childrens
end


for j = 1, buttonGroup.numChildren do   
    buttonGroup[j]:removeSelf();        --this removes alternative childrens
end

我希望它有用

I was facing the same problem...And got the soln for this:

you are removing objects using for loop:
if you remove objects in for loop say: you deleted object at index 1, then object 2 moves to object 1...so when it loops to object to it wont check object 2(bcoz its moved to object 1's place and you are checking object 3)

for j = 1, buttonGroup.numChildren do   
    buttonGroup[1]:removeSelf();        --this removes all childrens
end


for j = 1, buttonGroup.numChildren do   
    buttonGroup[j]:removeSelf();        --this removes alternative childrens
end

I hope its useful

三生路 2024-12-16 02:12:42

我为我的游戏(使用大量选项卡式视图)的对象移除问题奋斗了很长一段时间。我找到的解决方案是对所有需要删除的对象使用“= nil”、“:removeSelf()”和“.alpha = 0”。如果它们都被添加到同一个组中,并且其中没有其他内容,那么也可以使用它,但由于各种原因,关于如何在幕后设置组,并不总是有效。

看起来你所做的就是删除“项目符号”的内容,但这只是一个引用,所以当你说每个项目符号被删除时,它实际上只是从数组中删除 - 对象本身仍然存在并且需要为了防止内存泄漏和应用程序变慢(您可能会发现每个项目符号都会使应用程序变慢,对吧?)

在删除后添加此条件,您应该设置:

if(not(bullet == nil)) then
    bullet.alpha = 0;
    bullet:removeSelf();
    bullet = nil;
end

I fought for a long long time with object removal for my game which uses a lot of tabbed views. The solution I found was to use "= nil", ":removeSelf()" and ".alpha = 0" on all objects which need removing. If they are all added to the same group, and nothing else is in it, that could be used too, but doesn't always work for various reasons as to how groups are set up behind the scenes.

It would seem what you've done there is remove the contents of "bullets" but that's just a reference, so where you say each bullet is being removed, it's actually only being dropped from the array - the object itself still exists and needs to be nil'd in order to prevent a memory leak and a slowing of the app (you will probably have found that each bullet slows the app more, right?)

Add this condition after your removes and you should be set:

if(not(bullet == nil)) then
    bullet.alpha = 0;
    bullet:removeSelf();
    bullet = nil;
end
故笙诉离歌 2024-12-16 02:12:42

简单地创建一个像这样的表

local bulletCache = {}

然后在您的项目符号创建代码中添加

table.insert(bulletCache, myBulletObject)

然后在您的退出代码和/或您的销毁代码中说

for i = 1, #bulletCache do

--[[
--Below is not needed but just to keep your code consitant
    pcall(function()
        bullet.alpha = 0
    end)
--]]

    pcall(function()
        bullet:removeSelf()
    end)
    pcall(function()
        bullet = nil
    end)
end

its easier to simply create a table like this

local bulletCache = {}

Then in your bullet creation code add

table.insert(bulletCache, myBulletObject)

then in your exit code and/or your destroy code say

for i = 1, #bulletCache do

--[[
--Below is not needed but just to keep your code consitant
    pcall(function()
        bullet.alpha = 0
    end)
--]]

    pcall(function()
        bullet:removeSelf()
    end)
    pcall(function()
        bullet = nil
    end)
end
苄①跕圉湢 2024-12-16 02:12:42

首先,永远不要尝试在 GameLoop 中执行任何类型的循环。它确实会降低游戏的 fps,因为它通常需要更多内存。

现在,看起来你只是想在从屏幕上消失后摧毁子弹,而且你也在使用物理,那么为什么你不利用这一点呢?

以下是您应该遵循的步骤。 (如果您发现任何疑问或困难,请询问我)

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.碰撞时销毁子弹

那就这么简单:)

如果您仍然有这方面的问题,请告诉我。

First of all, never try to execute any kind of loop in GameLoop. It does drop fps of game, because it takes usually more memory.

Now, it seems that you just want to destroy bullets after disappearing from the screen and you are using physics too, so why you are not taking advantage of that?

Here are the steps you should follow. (If you find any query or difficulty about it then ask me)

1.Draw a Static Physical Line little bit above the screen. Let say y is -20.

    local _yLimit = -20
    local _limitLine = display.newLine(0,_yLimit,display.contentWidth,_yLimit)
    _limitLine.anchorX = 0
    _limitLine.anchorY = 0

2.Add all bullets as a physical object.

3.Apply force at the Bottom Center of bullet, rather then transforming it. [Assuming that bullet have rectangular physical shape, otherwise decide the equilibrium point of the shape].

4.Check for collisions with "collision" event listener.

5.Destroy bullets on collision

Thats so simple :)

Let me know if you still have problems regarding this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文