Ссылка на размер рисования и рендеринг рисования рядом друг с другом
Я работаю над игрой, которая использует 2D карту тайлов. Карта отображается с помощью пользовательского метода doDraw() в SurfaceView. Это простой двойной цикл for, который получает тип плитки из 2D-массива, определяет соответствующее растровое изображение для этого типа, а затем рисует плитку на холсте в указанных координатах.
Ранее в моей папке для рисования были заполнители.pngs. Эти заполнители были простыми 100x100 .png файлами сплошных цветов, которые я создал в ms paint. Казалось, что все работало нормально, пока я не поменял местами заполнители с хорошими текстурированными объектами. Затем я понял, что способ, которым я ссылался на координаты для рисования тайлов, был неправильным и фактически заставлял их перекрываться. Это не было очевидно, когда плитки были сплошными цветами, но с текстурами стало довольно очевидно, что две стороны плиток были покрыты смежными плитками.
Я считаю, что проблема на самом деле не в моем методе doDraw(), а, скорее всего, в том, как я ссылаюсь на размеры листов. Файлы.png имеют размер 100x100, но они, вероятно, преобразуются в другой размер в зависимости от плотности пикселей моего устройства. Я думаю, что это то, что происходит, и я читал, как с этим справиться, но все, что я там обнаружу, обычно будет говорить об одном растровом изображении, в отличие от множества маленьких растровых изображений, которые нужно нарисовать относительно друг с другом.
Вот соответствующий код из моего SurfaceView:
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);
}
}
}
}
}
Как вы можете видеть выше, я жестко запрограммировал высоту и ширину плитки. Средство для абстрагирования было бы неплохо, но сначала я хотел бы понять, какие правильные числа использовать. Если я установлю высоту и ширину для плиток на 100, я получу пробелы между плитками. Если установить их на 50, я получаю перекрытие. Это говорит мне, что правильный размер для ссылки - это нечто среднее. Я мог бы продолжать догадываться, пока не получу правильное определение, но я хотел бы понять, как определить, к какому размеру масштабируются мои рисунки для какой плотности пикселей.
В настоящее время мои drawables находятся в моей папке drawable-hdpi, и больше нигде. Мне интересно, если я положу их в общую папку "drawable", смогу ли я ссылаться на tile_height и tile_width как 100x100? Я прочитал о получении собственной высоты и ширины, но это не помогает, когда растровые изображения масштабируются для представления или устройства. Даже если можно как-то ссылаться на размеры плитки на основе исходного размера рисунка, я думаю, что должен быть лучший способ, чем ссылаться на них по какому-либо конкретному номеру. Разве я не смогу узнать, каков масштабированный размер в моем методе рисования? И затем используйте это, чтобы определить, к каким координатам рисовать плитки? Еще лучше, есть ли способ принудительно указать, какой размер я хочу, чтобы растровое изображение масштабировалось до того, как я нарисую его на холсте?
Я читал о плотности пикселей, точках на дюйм, папках для рисования и т. Д. По адресу http://developer.android.com/guide/practices/screens_support.html но это не очень помогает, когда я рисую плитки относительно друг с другом и поэтому нуждаются в координатах.
Я также рассмотрел использование Rectangles для рисования на холст, поскольку метод Canvas drawbitmap(), который принимает Rectangles в качестве входных данных, не зависит от плотности пикселей. Но я не уверен, насколько практичным будет использование прямоугольников, когда у меня есть набор плиток 12x6 для рисования. Нужен ли мне один прямоугольник на местоположение плитки?
Любые объяснения, касающиеся работы с масштабированными растровыми изображениями и / или лучшего способа рисования того, что я рисую, были бы наиболее полезными.
1 ответ
Ответил на мой собственный вопрос после сна. Чтобы получить высоту растрового изображения после того, как Android автоматически его масштабировал, используйте getWidth() и getHeight() в растровом изображении. Чтобы заставить растровое изображение масштабироваться до определенного размера, используйте scaleBitmap()