2D 게임을 위해 Java에서 타일링 된지도를 구축하는 방법은 무엇입니까?
문제
이 문제에 어떻게 접근 해야할지 잘 모르겠습니다.
기본적으로 400x400 창의 픽셀 -> 타일 표현을 원합니다. 화면의 각 좌표 (예 : 120x300
타일의 일부 여야합니다. 내 가장 작은 스프라이트는 4 픽셀이므로 1 타일 = 4 픽셀이라고 말할 수 있습니다. 플레이어와 적 스프라이트는 모두 20 x 20이므로 각 플레이어/나쁜 사람은 5 개의 타일을 차지합니다.
그런 다음이 맵 클래스를 사용하고 싶습니다.
타일의 인덱스/ID를 공급하여 플레이어/몬스터 스프라이트의 X/Y 좌표를 검색하십시오.
경계가 어디에 있는지 알기 때문에 스프라이트를 넘어서는 것은 아닙니다.
400x400
, 따라서 숨어 있습니다.타일이 비어 있는지 여부를 아는 충돌 감지.
이 작업은 어떻게 할 수 있습니까? x, y-> 타일 또는 타일 색인-> x에 대해 구체적으로 이야기합니다.
해결책
첫째, 타일과 함께 표현과 관련된 픽셀의 개념을 나누어 게임에 배치 한 제약 조건이있는 실제 게임 객체입니다.
이와 같은 것들을 분해하는 좋은 방법은 원하는 것의 거친 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)..
타일은 내부적으로 2D 어레이 또는 단일 배열로 표현 될 수 있으며,이 경우에는 어떤 종류의 내부 표현 체계를 사용하여 배열을 보드 사각형에 매핑하므로 모드 산술이 있습니다.
다른 팁
짧은 답변 : 곱셈 및 모듈로 작동.
그러나 이것이 당신을 그루어지고 있다면, 나는 당신이 게임을 작성하기 전에 심각한 수학 리프레셔를하는 것이 좋습니다.
또한 당신의 진술
내 가장 작은 스프라이트는 4 픽셀이므로 1 타일 = 4 픽셀이라고 말할 수 있습니다. 플레이어와 적 스프라이트는 모두 20 x 20이므로 각 플레이어/나쁜 사람은 5 개의 타일을 차지합니다.
합리적인 지오메트리에 대해서는 해결되지 않습니다. "1 타일 = 4 픽셀"이라면 타일이 2x2 인 경우 플레이어는 5가 아닌 100을 차지합니다. 당신이 그들이 4x4라는 것을 의미한다면 플레이어는 25를 차지합니다.
/** 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;
}
}
당신을 시작하게되기를 바랍니다. 모든 코드는 근처에 컴파일러없이 쓰여져 있으므로 오타와 버그가 포함되며, 이는 크리에이티브 커먼즈 라이센스에 따라 배포 될 수 있습니다.
조각을 세트에 보관하는 접근 방식은 조각이 많지 않으면 잘 작동해야합니다. 대부분의 보드 영역에 조각이 포함되어 있지 않은 한 2D 배열보다 더 잘 작동해야합니다. 모든 것은 현재 겹치는 조각이 없다고 가정합니다. 필요한 경우 getpiceontile은 조각 모음을 반환해야합니다. 순서가 중요하지 않은 경우 세트, 그렇지 않은 경우 목록입니다.