В 2D-игре довольно легко определить, какие плитки попадают в прямоугольник вида, если плитки прямоугольные. По сути, изобразите прямоугольник «области просмотра» внутри большего прямоугольника мира. Разделив смещения вида на размеры плитки, вы можете легко определить начальную плитку, а затем просто отобразить плитки в том виде, в котором они находятся внутри вида.
Во-первых, вы работаете в трех системах координат: вид, мир и карта. Координаты вида - это, по сути, смещения мыши от верхнего левого угла вида. Мировые координаты - это расстояния в пикселях от левого верхнего угла фрагмента 0, 0. Я предполагаю, что ваш мир начинается в верхнем левом углу. И координаты карты - это x, y индексы в массиве карты.
Вам нужно будет выполнить конвертацию между ними, чтобы сделать «причудливые» вещи, такие как прокрутка, выяснение того, какая плитка находится под мышью, и рисование объектов мира с правильными координатами на виде. Итак, вам понадобятся некоторые функции для преобразования между этими системами:
// I haven't touched Java in years, but JavaScript should be easy enough to convey the point
var TileWidth = 40,
TileHeight = 40;
function View() {
this.viewOrigin = [0, 0]; // scroll offset
this.viewSize = [600, 400];
this.map = null;
this.worldSize = [0, 0];
}
View.prototype.viewToWorld = function(v, w) {
w[0] = v[0] + this.viewOrigin[0];
w[1] = v[1] + this.viewOrigin[1];
};
View.prototype.worldToMap = function(w, m) {
m[0] = Math.floor(w[0] / TileWidth);
m[1] = Math.floor(w[1] / TileHeight);
}
View.prototype.mapToWorld = function(m, w) {
w[0] = m[0] * TileWidth;
w[1] = m[1] * TileHeight;
};
View.prototype.worldToView = function(w, v) {
v[0] = w[0] - this.viewOrigin[0];
v[1] = w[1] - this.viewOrigin[1];
}
Вооружившись этими функциями, мы теперь можем визуализировать видимую часть карты ...
View.prototype.draw = function() {
var mapStartPos = [0, 0],
worldStartPos = [0, 0],
viewStartPos = [0, 0];
mx, my, // map coordinates of current tile
vx, vy; // view coordinates of current tile
this.worldToMap(this.viewOrigin, mapStartPos); // which tile is closest to the view origin?
this.mapToWorld(mapStartPos, worldStartPos); // round world position to tile corner...
this.worldToView(worldStartPos, viewStartPos); // ... and then convert to view coordinates. this allows per-pixel scrolling
mx = mapStartPos[0];
my = mapStartPos[y];
for (vy = viewStartPos[1]; vy < this.viewSize[1]; vy += TileHeight) {
for (vx = viewStartPos[0]; vx < this.viewSize[0]; vy += TileWidth) {
var tile = this.map.get(mx++, my);
this.drawTile(tile, vx, vy);
}
mx = mapStartPos[0];
my++;
vy += TileHeight;
}
};
Это должно сработать. У меня не было времени собрать рабочую демонстрационную веб-страницу, но я надеюсь, что вы поняли идею.
Изменяя viewOrigin, вы можете прокручивать. Чтобы получить мир и отобразить координаты под мышью, используйте функции viewToWorld и worldToMap.
Если вы планируете изометрический вид, т. Е. Diablo, то все становится намного сложнее.
Удачи!