3

不知道如何解决这个问题。

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

然后我想用这个 Map 类来:

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

  • 知道边界在哪里,所以它不会将精灵移动到 之外400x400,从而隐藏它。

  • 碰撞检测,知道瓷砖是否空置。

如何才能做到这一点?在这里专门讨论 x,y->tile 或 tile index->​​x,y 转换(用于适当地绘制精灵)。

4

3 回答 3

4

首先,将仅与表示有关的像素概念拆分为图块,图块是实际的游戏对象,并在游戏中设置了约束。

我找到了一个解决此类问题的好方法,那就是开始勾勒出你想要的粗略 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)..

瓷砖可以在内部表示为二维数组或单个数组,在这种情况下,您将使用某种内部表示方案将您的数组映射到棋盘方格,从而使用 mod 算法。

于 2009-03-08T01:14:36.517 回答
1

简短回答:乘法和模运算。

但是,如果这让您感到难过,我建议您在尝试编写游戏之前进行认真的数学复习。

还有你的说法

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

不适用于任何合理的几何形状。如果“1 块 = 4 像素”的意思是块是 2x2,那么玩家需要 100,而不是 5。如果您的意思是他们是 4x4,那么玩家需要 25,但仍然不是 5。

于 2009-03-08T01:00:46.720 回答
1
/** 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->piece 转换,反之亦然,您可以使用多种方法。选择哪一个取决于确切的要求(速度、游戏大小......)。因此,请确保您隐藏了实现细节,以便以后可以更改它们。

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

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<Long,Piece> pieces = new HashMap<Piece>(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;
    }
}

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

如果没有太多棋子,将棋子保持在一组中的方法应该很有效。只要大多数电路板区域不包含一块,它就应该比 2D 阵列更好。整个事情目前假设没有重叠的部分。如果你需要那些 getPieceOnTile 必须返回一个 Collection of pieces。如果顺序无关紧要,则为 set,如果重要,则为 List。

于 2009-03-08T05:17:10.177 回答