我有一个使用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;
}
}
答案 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();