【问题标题】:Object Pooling not returning objects correctly对象池未正确返回对象
【发布时间】:2014-06-11 18:54:57
【问题描述】:

Iv 使用对象池设置程序生成游戏。第一个区域总是可以正常加载,有时下一个或 2 个区域也可以正常加载。然后它会中断,并且我编码抛出的错误被抛出,告诉我我的池中没有足够的对象,考虑到它应该在尝试加载下一个区域之前返回它使用的所有对象,这很奇怪。

一个游戏链接,看看它在做什么 http://www.fastswf.com/pu06z-A

我什至在我的精灵池类中添加了一个 countSprites 函数来返回计数器所在的位置,然后让 generateTile() 函数等到池回到 192,但它似乎仍然不起作用:/

在做了一堆跟踪和 if 测试后,iv 得出结论,它返回的对象很好,问题是它实际上绘制了从地图开始到现在的区域的所有内容。

这是在屏幕上生成我的图块的函数。

    public function generateTile()
    {
        for (var i:int = X/GlobalCode.MAP_SCALE; i < (X + (800/TILE_SIZE)/GlobalCode.MAP_SCALE); i++)
        {
            for (var j:int = Y/GlobalCode.MAP_SCALE; j < Y + (600/TILE_SIZE)/GlobalCode.MAP_SCALE; j++)
            {
                hm = heightmap[i][j];
                if (hm >= 0.84)
                {
                    tile = waterPool.getSprite(); //this is where the tiles are taken from the sprite pool
                }
                else if (hm >= 0.8 && hm < 0.84)
                {
                    tile = shallowPool.getSprite();//this is where the tiles are taken from the sprite pool
                }
                else if (hm >= 0.7 && hm < 0.8)
                {
                    tile = sandPool.getSprite();//this is where the tiles are taken from the sprite pool
                }
                else if (hm >= 0.2 && hm < 0.7)
                {
                    tile = tilePool.getSprite();
                }
                else
                {
                    tile = stonePool.getSprite();//this is where the tiles are taken from the sprite pool
                }
                tile.width = TILE_SIZE;
                tile.height = TILE_SIZE;
                worldTiles.x = 0;
                worldTiles.y = 0;
                tile.x = TILE_SIZE * (i % 800);
                tile.y = TILE_SIZE * (j % 600);
                tilesInWorld.push(tile);
                worldTiles.addChild(tile);
            }
        }
    }

这是删除它们的函数。

    public function deleteTiles()
    {
        if (tilesInWorld.length > 0)
        {
            for (var i:int = tilesInWorld.length-1; i >= 0; i--)
            {
                if(tilesInWorld[i].Name == "water"){
                    waterPool.returnSprite(tilesInWorld[i]);//this is the specific line of code that is returning the objects to the pool
                    trace("water returned");
                }else if(tilesInWorld[i].Name == "shallow"){
                    shallowPool.returnSprite(tilesInWorld[i]);//this is the specific line of code that is returning the objects to the pool
                    trace("shallow returned");
                }else if(tilesInWorld[i].Name == "sand"){
                    sandPool.returnSprite(tilesInWorld[i]);//this is the specific line of code that is returning the objects to the pool
                    trace("sane returned");
                }else if(tilesInWorld[i].Name == "grass"){
                    tilePool.returnSprite(tilesInWorld[i]);
                    trace("grass returned");
                }else{
                    stonePool.returnSprite(tilesInWorld[i]);//this is the specific line of code that is returning the objects to the pool
                    trace("stone returned");
                }
                worldTiles.removeChild(tilesInWorld[i]);//this is the specific line of code that is returning the objects to the pool
            }
            tilesInWorld.length = 0;//empty array
                        if(tilePool.countSprites == 192){
            generateTile();
                        }
        }
    }

这是第一次创建对象池的地方

        tilePool = new SpritePool(Tile, 192);
        sandPool = new SpritePool(Sand, 192);
        shallowPool = new SpritePool(Shallow, 192);
        waterPool = new SpritePool(Water, 192);
        stonePool = new SpritePool(Stone, 192);

不认为有必要展示这一点,但只是以防这是我的 SpritePool 类

  package  {
    import flash.display.MovieClip;

    public class SpritePool {

    private var pool:Array;
    private var counter:int;

    public function SpritePool(type:Class, len:int) {
        pool = new Array();
        counter = len;

        var i:int = len;
        while(--i > -1){
            pool[i] = new type();
        }
    }

    public function getSprite():MovieClip
    {
        if(counter > 0){
            return pool[--counter];
        }
        else{
            throw new Error("You exhausted the pool!");
        }
    }
    public function returnSprite(s:MovieClip):void
    {
        pool[counter++] = s;
    }

    public function countSprites():int
    {
        return counter;
    }

}

}

【问题讨论】:

  • 如果您没有提供完整的代码,就很难得到错误。目前尚不清楚删除的调用位置以及地图的生成方式 - 您已经提供了该功能,但没有从哪里执行它并且很热。你不能简单地问“出了什么问题”——这是关于你和你的代码设计的。我们无法读取您的所有代码并找到错误 - 这取决于您。做一些跟踪,什么时候添加什么时候删除。始终检查剩余精灵的数量。如果用完了,就不要退货了。
  • 看,我真的不明白这些:for (var i:int = X/GlobalCode.MAP_SCALE; i &lt; (X + 800/TILE_SIZE)/GlobalCode.MAP_SCALE); i++).. 将您的问题缩小到更具体的问题。请记住,预定义数组的值是一种很好的做法,因为现在,在每次迭代中,循环都会强制计算这些变量(因此会浪费时间)。人们甚至避免迭代到array.length 而是使用var total:uint = array.length .. 而你做这样的计算.. 这很浪费
  • 您的回复比您想象的更有帮助。 :) 实际上我只是把你说的那条线改了var i:int = X; i &lt; (X + (800/TILE_SIZE)/GlobalCode.MAP_SCALE); i++) 我想我只是数学计算错误
  • 我也会听从你的建议,从数组中取出数学计算
  • 您可以自己回答您的问题,也可以关闭它,这样就不会留下任何未解决的问题 - 人们会继续回来帮助您,实际上会浪费他们的时间你自己修好了 :) 干杯!

标签: actionscript-3 flash


【解决方案1】:

改变

    for (var i:int = X/GlobalCode.MAP_SCALE; i < (X + (800/TILE_SIZE)/GlobalCode.MAP_SCALE); i++)
    {
        for (var j:int = Y/GlobalCode.MAP_SCALE; j < Y + (600/TILE_SIZE)/GlobalCode.MAP_SCALE; j++)
        {

var Xcalc = (X + (800/TILE_SIZE)/GlobalCode.MAP_SCALE);
var Ycalc = (Y + (600/TILE_SIZE)/GlobalCode.MAP_SCALE);

    for (var i:int = X; i < Xcalc; i++)
    {
        for (var j:int = Y; j < Ycalc; j++)
        {

【讨论】:

    猜你喜欢
    • 2017-10-24
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2021-11-11
    • 2021-07-04
    • 2013-09-08
    • 1970-01-01
    相关资源
    最近更新 更多