如何在Java中为2D游戏构建Tiled地图?

不知道如何处理这个问题。

基本上,我想要一个400×400窗口的Pixel – > Tile表示。 屏幕上的每个坐标,例如120x300应该是图块的一部分。 我最小的精灵是4个像素,所以我们可以说1个tile = 4个像素。 玩家和敌人的精灵都是20 x 20,所以每个玩家/坏人将占据5个牌。

然后我想使用这个Map类来:

  • 通过提供图块的索引/ id来检索玩家/怪物精灵的x / y坐标。

  • 知道边界的位置,因此它不会将精灵移动到400x400 ,从而隐藏它。

  • 碰撞检测,了解瓷砖是否空置。

如何才能做到这一点? 这里特别谈论x,y-> tile或tile index->​​ x,y转换(适当地绘制精灵)。

首先,将一个与像素有关的像素的概念与一个瓦片分开,瓦片是一个实际的游戏对象,它对游戏施加了约束。

我找到了一个很好的方法来解开这样的事情,就是开始勾勒出你想要的粗略API。 就像是:

 public class Board { public Board (int width, int height){.. } public boolean isOccupied(int x, int y){.. } public void moveTo(Point from, Point to) { .. (maybe throws an exception for outofbounds ) 

电路板的所有内部单元都在瓷砖中,而不是像素。 然后,可以通过一些内部乘法从图块表示中独立地从板上导出像素信息 –

  public Point getPixelPosition(int xTilePos, int yTilePos, int pixelsPerTile).. 

tile可以在内部表示为2d数组或单个数组,在这种情况下,您可以使用某种内部表示方案将数组映射到板方块,从而使用mod算法。

简答:乘法和模运算。

但如果这让你感到困惑,我建议你在尝试编写游戏之前先做一个严肃的数学复习。

还有你的陈述

我最小的精灵是4个像素,所以我们可以说1个tile = 4个像素。 玩家和敌人的精灵都是20 x 20,所以每个玩家/坏人将占据5个牌。

没有任何合理的几何形状。 如果通过“1 tile = 4像素”表示图块是2×2,那么玩家需要100而不是5。 如果你的意思是他们是4×4然后玩家需要25,这仍然不是5。

 /** size of a tile in pixel (for one dimension)*/ int TILE_SIZE_IN_PIXEL = 4; /** size of a piece in tiles (for one dimension)*/ int PIECE_SIZE_IN_TILE = 5; public int tileToPixel(int positionInTiles){ return TILE_SIZE_IN_PIXEL * positionInTiles; } /** returns the tile coordinate to which the given tile coordinate belongs Note: tileToPixel(pixelToTile(x)) only returns x if x is the upper or left edge of a tile */ public int pixelToTile(int positionInPixel){ return positionInPixel / TILE_SIZE_IN_PIXEL; } 

您可能也希望方法在两个参数(x和y at)上运行。

对于ID->件转换,反之亦然,您可以使用各种方法。 选择哪一个取决于具体要求(速度,游戏规模……)。 因此,请确保隐藏实现详细信息,以便稍后进行更改。

我从一个真正简单的解决方案开始:

 public class Piece{ /** x position measured in tiles */ private int x; /** y position measured in tiles */ private int y; /** I don't think you need this, but you asked for it. I'd pass around Piece instances instead */ private final Long id; public void getX(){ return x; } public void getY(){ return y; } public void getID(){ return id; } } public class Board(){ private Set pieces = new HashMap(pieces); public Piece getPieceOnTile(int tileX, int tileY){ for(Piece piece:pieces){ if (isPieceOnTile(piece, tileX, tileY)) return piece; } } private boolean isPieceOnTile(piece, tileX, tileY){ if (piece.getX() < tileX) return false; if (piece.getX() > tileX + PIECE_SIZE_IN_TILE) return false; if (piece.getY() < tileY) return false; if (piece.getY() > tileY + PIECE_SIZE_IN_TILE) return false; return true; } } 

希望能让你开始。 所有代码都是在附近没有编译器的情况下编写的,因此它将包括拼写错误,当然还有错误,这些错误可能会在创意公共许可证下分发。

如果没有很多碎片,那么将碎片保持在一组中的方法应该很好。 只要大多数电路板区域不包含一块,它应该比2Darrays更好。 目前整件事假设没有重叠的部分。 如果你需要那些getPieceOnTile必须返回一个片段集合。 如果订单无关紧要,则为List,如果有的话。