为什么我不会在我的第一个大块负荷上滞后但是我在最后一次呢?

时间:2014-06-09 19:11:23

标签: actionscript-3 flash adobe

我有一个使用perlin地图的程序生成游戏。我把它放在只加载你所在区域的瓷砖的地方,当你离开那个区域时,它会删除它们并根据你走过的地方重新绘制它们。所以理论上它应该只加载你所在区域的瓷砖。但是看起来你越往我的地图越走越开始。我不知道为什么因为它永远不会加载不同数量的块。

此处是截至目前的游戏链接。 http://www.fastswf.com/nzpBar0

这些是添加和删除图块的功能。

    //deletes the tiles on the world.
    public function deleteTiles()
    {
        if (tilesInWorld.length > 0)
        {
            for (var i:int = 0; i < tilesInWorld.length; i++)
            {
                worldTiles.removeChild(tilesInWorld.pop());
            }
            generateTile();
        }
    }
    //generates the tiles on the world
    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 = new Water();
                }
                else if (hm >= 0.8 && hm < 0.84)
                {
                    tile = new Shallow();
                }
                else if (hm >= 0.7 && hm < 0.8)
                {
                    tile = new Sand();
                }
                else if (hm >= 0.2 && hm < 0.7)
                {
                    tile = new Tile();
                }
                else
                {
                    tile = new Stone();
                }
                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);
            }
        }
    }

这是perlin地图和第一个瓷砖区域的创建地点

    public function World(parentMC:MovieClip)
    {
        TILE_SIZE = GlobalCode.TILE_SIZE;
        map_width = GlobalCode.MAP_WIDTH;
        map_height = GlobalCode.MAP_HEIGHT;
        pmap = new BitmapData(map_width,map_height);
        grid_width = new uint(map_width / TILE_SIZE);
        grid_height = new uint(map_height / TILE_SIZE);
        //map_width = GlobalCode.MAP_WIDTH;
        //map_height = GlobalCode.MAP_HEIGHT;
        pmap.perlinNoise(map_width,map_height, 6, _seed, true, false, 1, true);
        for (var i:uint=0; i < grid_width; i++)
        {
            heightmap[i] = new Array();
            for (var j:uint=0; j < grid_height; j++)
            {
                heightmap[i][j] = new uint();
            }
        }
        //Divide the map in to a 7x7 grid and take data at each interval
        for (i = 0; i < grid_width; i++)
        {
            for (j = 0; j < grid_height; j++)
            {
                pixelPoint.x = Math.round((i/grid_width) * pmap.width)+1;
                pixelPoint.y = Math.round((j/grid_width) * pmap.height)+1;
                heightmap[i][j] = pmap.getPixel(pixelPoint.x,pixelPoint.y);
                heightmap[i][j] /=  0xffffff;

                if (heightmap[i][j] < darkest_pixel)
                {
                    darkest_pixel = heightmap[i][j];
                }
            }
        }
        //Adjust values to a min of 0
        for (i = 0; i < grid_width; i++)
        {
            for (j = 0; j < grid_height; j++)
            {
                heightmap[i][j] -=  darkest_pixel;

                if (heightmap[i][j] > brightest_pixel)
                {
                    brightest_pixel = heightmap[i][j];
                }
            }
        }

        //Adjust values to highest value of 1
        for (i = 0; i < grid_width; i++)
        {
            for (j = 0; j < grid_height; j++)
            {
                heightmap[i][j] /=  brightest_pixel;
            }
        }
        worldTiles = new Sprite();
        parentMC.addChild(worldTiles);
        generateTile();
    }

当你走到屏幕边缘时,这就是创建滚动矩形和X / Y的变化。

    public function update(e:Event)
    {
        world.worldTiles.scrollRect = new Rectangle(X,Y,800,600);
        if (canMove == true)
        {
            MovePlayer();
        }
        player.update();
        PlayerOnTile();
    }

对于咯咯笑,这就是移动我的角色和滚动/矩形

的原因
    protected function MovePlayer()
    {
        if (goin[0] == 1)
        {
            player.y -=  moveSpeed;
            if (player.y <= 0 && (Yloc) > 0)
            {
                world.Y -= int(600/world.TILE_SIZE)/MAP_SCALE;
                world.deleteTiles();
                Y -=  600 / MAP_SCALE;
                Yloc -=  1;
                player.y +=  600;
            }
        }
        if (goin[1] == 1)
        {
            player.y +=  moveSpeed;
            if (player.y >= 600 && (Yloc + 1) < MAP_SCALE)
            {
                world.Y += int(600/world.TILE_SIZE)/MAP_SCALE;
                world.deleteTiles();
                Y +=  600 / MAP_SCALE;
                Yloc +=  1;
                player.y -=  600;
            }
            //world.worldTiles.y -=  moveSpeed;
        }
        if (goin[2] == 1)
        {
            player.x -=  moveSpeed;
            if (player.x <= 0 && (Xloc) > 0 )
            {
                world.X -= int(800/world.TILE_SIZE)/MAP_SCALE;
                world.deleteTiles();
                X -=  800 / MAP_SCALE;
                Xloc -=  1;
                player.x +=  800;
            }
            //world.worldTiles.x +=  moveSpeed;
        }
        if (goin[3] == 1)
        {
            player.x +=  moveSpeed;
            if (player.x >= 800&& (Xloc + 1) < MAP_SCALE)
            {
                world.X += int(800/world.TILE_SIZE)/MAP_SCALE;
                world.deleteTiles();
                X +=  800 / MAP_SCALE;
                Xloc +=  1;
                player.x -= 800;
            }
            //world.worldTiles.x -=  moveSpeed;
        }
    }

2 个答案:

答案 0 :(得分:0)

我不记得Actionscript如何处理它,但它可能是deleteTiles()函数中的for循环。它只会持续到i < tilesInWorld.length,以及for循环的每次迭代,你的i增加1,而你的tilesInWorld减少1。这意味着每次尝试删除所有图块时,您只会删除一半图块。

尝试使用while循环,看看是否修复了它。 e.g。

public function deleteTiles()
{
    if (tilesInWorld.length > 0)
    {
        while (tilesInWorld.length > 0)
        {
            worldTiles.removeChild(tilesInWorld.pop());
        }
        generateTile();
    }
}

答案 1 :(得分:0)

这非常简单和基本。您正在不断创建新对象,一段时间后,您的应用程序无法获得足够的内存来创建新对象,还需要使用大块CPU功率来清理。所有这些都会产生延迟,并且是内存泄漏的一种形式。您需要重用对象而不是创建新对象。此过程称为对象池。一旦不需要图形,而不是丢弃它并在下次创建新图形,您可以保留它并在下次重复使用它。这样你不需要额外的内存,你的应用程序不需要更多,也不需要清理(称为垃圾收集)。

public function deleteTiles()
{
    if (tilesInWorld.length)
    {            
        for (var i:int = 0; i < tilesInWorld.length; i++)
        {
            worldTiles.removeChild(tilesInWorld[i]);//no new object creation when deleting
            //tilesInWorld.pop() create a new array internally
        }
        tilesInWorld.length = 0;//empty array
        generateTile();//this should be improved too
    }
}

如果worldTiles仅包含标题,则worldTiles.removeChildren()将执行以下操作:

worldTiles.removeChildren();
tilesInWorld.length = 0;
generateTile();