2D 타일 맵을 사용하는 게임을하고 있습니다. 지도는 SurfaceView에서 사용자 정의 메소드 doDraw()를 통해 렌더링됩니다. 2D 배열에서 타일 유형을 가져 와서 해당 유형에 해당하는 비트 맵을 결정한 후 해당 타일을 지정된 좌표의 캔버스에 그려주는 간단한 double for 루프입니다.드로어 블 크기를 참조하고 렌더링 드로어 블을 서로 인접 해 있습니다.
이전에는 드로어 블 폴더에 자리 표시 자 .png가있었습니다. 이러한 자리 표시 자 드로어 블은 ms 페인트로 만든 단색의 간단한 100x100 .png 파일이었습니다. 자리 표시 자 drawable을 멋진 질감의 드로어 블로 바꿀 때까지 상황이 잘 작동하는 것처럼 보였습니다. 그런 다음 타일을 그리기 위해 좌표를 참조하는 방식이 올바르지 않고 실제로 겹치는 것을 깨닫게되었습니다. 타일이 단색 일 때 이것은 분명하지 않았지만 텍스처를 사용하면 타일의 두면이 인접한 타일로 덮여 있음을 알게되었습니다.
실제로 문제는 doDraw() 메서드에 실제로있는 것이 아니라 타일 크기를 참조하는 방식에 가장 가능성이 높습니다. .png 파일은 100x100이지만 내 장치의 픽셀 밀도에 따라 다른 크기로 변환 될 가능성이 큽니다. 그 일이 계속되고 있다고 생각합니다. 그 문제를 해결하는 방법을 읽었지만, 일반적으로 단일 비트 맵에 대해 이야기 할 것입니다. 많은 작은 비트 맵과는 대조적으로 많은 비트 맵이 필요합니다. 서로. 위에서 볼 수 있듯이, 나는 타일의 높이와 폭을 하드 코딩 한
public class MapView extends SurfaceView implements SurfaceHolder.Callback {
protected Context context;
public World world;
public Map<Integer,Bitmap> TILE_MAP;
public Bitmap SPRITE;
public Player player;
public Camera camera;
//hardcoded parameters for testing
private int tile_width = 50;
private int tile_height = 50;
public int screen_width = 12; //specifies how many tiles to draw in y direction
public int screen_height = 6; //specifies how many tiles to draw in x direction
public MapThread mapThread;
public MapView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
Log.d("LOGCAT", "MapView created");
//get the tile map
WorldFeatures worldFeatures = new WorldFeatures(context);
TILE_MAP = worldFeatures.TILE_MAP;
SPRITE = worldFeatures.SPRITE;
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
public void doDraw(Canvas canvas) {
/*the draw method looks a little muddled at the moment as my camera is referencing
the center tile instead of the top left tile. I'll be updating that soon*/
int screenX = 0; //reset screenX each loop
for (int worldX = (camera.x - screen_height/2 + 1); worldX < (camera.x + screen_height/2 + 1); worldX += 1, screenX += 1) {
int screenY = 0; //reset screenY each loop
for (int worldY = (camera.y - screen_width/2 + 1); worldY < (camera.y + screen_width/2 + 1); worldY += 1, screenY += 1) {
canvas.drawBitmap(TILE_MAP.get(world.world_map[worldX][worldY]), screenY*tile_height , screenX*tile_width, null);
if (player.x == worldX && player.y == worldY) { //if the player is standing here, draw the sprite
canvas.drawBitmap(SPRITE, screenY*tile_height + tile_height/5, screenX*tile_width + tile_width/5, null);
}
}
}
}
}
:
은 여기 내 서피스 뷰 SurfaceView에서 관련 코드입니다. 이것을 추상화하는 방법은 좋을 수도 있지만, 우선 올바른 번호가 무엇인지 이해하고 싶습니다. 타일의 높이와 너비를 100으로 설정하면 타일 사이에 공간이 생깁니다. 50으로 설정하면 중복됩니다. 이것은 참조 할 정확한 크기가 중간에 있음을 알려줍니다. 내가 맞을 때까지 계속 추측 할 수는 있지만, 어떤 드로잉 크기가 어떤 픽셀 밀도에 맞게 확장되는지 결정하는 방법을 이해하고 싶습니다.
현재 내 drawable은 내 drawable-hdpi 폴더에 있으며 다른 곳은 없습니다. 일반 "드로어 블"폴더에 넣으면 궁금합니다. tile_height 및 tile_width를 100x100으로 참조 할 수 있습니까? 본질적인 높이와 너비를 얻는 것에 대해 읽었지만 비트 맵이 뷰 또는 장치의 크기를 조정할 때 도움이되지 않습니다. 원래 드로어 블 크기를 기반으로 타일 크기를 어떻게 든 참조 할 수 있다고하더라도 특정 숫자로 참조하는 것보다 더 좋은 방법이 있다고 생각합니다. 내 무승부 방법 내에서 크기를 조정 한 것이 무엇인지 알아낼 수 있어야합니까? 그런 다음 그 좌표를 사용하여 타일을 그릴 좌표를 결정하십시오. 더 좋은 점은 비트 맵을 캔버스에 그리기 전에 크기를 조정할 크기를 강제로 설정하는 방법이 있습니까?
픽셀 밀도, dpi, 드로어 블 폴더 등을 http://developer.android.com/guide/practices/screens_support.html에 읽었습니다. 그러나 타일을 서로 그리기 때문에 좌표를 필요로 할 때이 점이 도움이되지 않습니다.
Rectangle를 입력으로 사용하는 Canvas의 drawbitmap() 메서드는 픽셀 밀도에 종속되지 않으므로 캔바스에 그리는 데 Rectangle을 사용하는 방법을 살펴 보았습니다. 하지만 내가 그리는 타일의 12x6 세트를 가지고있을 때 Rectangle을 사용하는 것이 얼마나 실용적인 것인지 확신 할 수 없습니다. 타일 위치 당 하나의 직사각형이 필요합니까?
스케일링 된 비트 맵 처리 및/또는 내가 그리는 것을 그리는 더 좋은 방법이 가장 유용 할 것입니다.