How to build a tile map in Java for a 2D game?

I don’t know how to approach this problem.

Basically, I want the Pixel -> Tile to represent a 400x400 window. Each coordinate on the screen, for example 120x300, should be part of a tile. My little sprite is 4 pixels, so we can say that 1 tile = 4 pixels. Players and enemy sprites are all 20 x 20, so each player / bad guy will take 5 tiles.

Then I want to use this Map class to:

  • Get x / y coordinates for player / monster sprite by requesting tile index / id.

  • Knowing where the borders are, so he does not move the sprite outside 400x400, thereby hiding it.

  • Collision detection, knowing whether tiles are vacant or not.

How can I do that? Speaking specifically about transforming x, y-> tile or tile index-> ​​x, y (for drawing sprites correctly).

+3
source share
3 answers

First, separate the concept of a pixel, which is simply associated with the view, with the tile, which is the actual game object with its associated limitations.

I find a good way to unravel things like this in order to start drawing a crude API of what you want. Sort of:

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 )

where all the internal blocks of the board are in tiles, not pixels. Then the pixel information can be derived from the board regardless of the representation of the tile with a bit of internal multiplication -

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

2d , - , , .

+4

: .

, , .

- 4 , , 1 = 4 . - 20 x 20, / 5 .

- . "1 = 4 " , 2x2, 100, . , 4x4, 25, 5.

+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- > . , (, ...). , , .

:

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;
    }
}

, . , , , , Creative Commons.

The approach to preserving shapes in a set should work well if there aren't many. It should work better than a 2D array if most areas of the panel do not contain a piece. All of this currently assumes that there are no overlapping pieces. If you need to, then getPieceOnTile should return a collection of pieces. Set, if order does not matter, is List, if it does.

+1
source

Source: https://habr.com/ru/post/1704395/


All Articles