Подтвердить что ты не робот

Управление текстовыми картами в 2D-массиве для окрашивания на холсте HTML5.

Итак, я делаю RPG для HTML5 только для удовольствия. Карта - это <canvas> (ширина 512 пикселей, высота 352 пикселей - 16 плиток, 11 плиток сверху вниз). Я хочу знать, есть ли более эффективный способ рисовать <canvas>.

Вот как у меня это сейчас:

Как плитки загружаются и окрашиваются на карту

Карту окрашивают плитки (32x32) с помощью фрагмента Image(). Файлы изображений загружаются через простой цикл for и помещаются в массив с именем tiles[], чтобы его можно было использовать PAINTED при использовании drawImage().

Сначала мы загружаем плитки...

enter image description here

и вот как это делается:

// SET UP THE & DRAW THE MAP TILES
tiles = [];
var loadedImagesCount = 0;
for (x = 0; x <= NUM_OF_TILES; x++) {
  var imageObj = new Image(); // new instance for each image
  imageObj.src = "js/tiles/t" + x + ".png";
  imageObj.onload = function () {
    console.log("Added tile ... " + loadedImagesCount);
    loadedImagesCount++;
    if (loadedImagesCount == NUM_OF_TILES) {
      // Onces all tiles are loaded ...
      // We paint the map
      for (y = 0; y <= 15; y++) {
        for (x = 0; x <= 10; x++) {
          theX = x * 32;
          theY = y * 32;
          context.drawImage(tiles[5], theY, theX, 32, 32);
        }
      }
    }
  };
  tiles.push(imageObj);
}

Естественно, когда игрок начинает игру, он загружает карту, на которой они остановились. Но здесь, это все травяная карта.

В настоящее время на картах используются двумерные массивы. Вот пример карты.

[[4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 1, 1, 1], 
[1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 1], 
[1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1]];

Я получаю разные карты, используя простую структуру if. Как только массив 2d выше return, соответствующее число в каждом массиве будет окрашено в соответствии с Image(), сохраненным внутри tile[]. Затем drawImage() произойдет и покрасьте в соответствии с x и y, а затем на 32, чтобы нарисовать правильную координату x-y.

Как происходит множественное переключение карт

В моей игре карты имеют пять вещей, чтобы отслеживать: currentID, leftID, rightID, upID и bottomID.

  • currentID: Текущий идентификатор карты, на которой вы находитесь.
  • leftID: Какой идентификатор currentID для загрузки, когда вы выходите слева от текущей карты.
  • rightID: Какой идентификатор currentID для загрузки, когда вы выходите справа текущая карта.
  • downID: Какой идентификатор currentID для загрузки при выходе из него внизу текущей карты.
  • upID: Какой идентификатор currentID для загрузки, когда вы выходите в верхней части текущей карты.

Что-то примечание: если либо leftID, rightID, upID, либо bottomID НЕ являются конкретными, это означает, что они являются 0. Это означает, что они не могут покинуть эту сторону карты. Это просто невидимая блокада.

Итак, как только человек выходит из карты, в зависимости от того, где они вышли... например, если они вышли в нижней части, bottomID будет загружен номер map и, таким образом, будет нарисован на карту.

Здесь представлен репрезентативный .GIF, который поможет вам лучше визуализировать:

enter image description here

Как вы можете видеть, рано или поздно со многими картами я буду иметь дело со многими идентификаторами. И это может стать немного запутанным и беспокойным.

Очевидными плюсами являются то, что он загружает 176 фрагментов за раз, обновляет небольшой холст размером 512x352 и обрабатывает одну карту во времени. Кон является то, что идентификаторы MAP при работе со многими картами могут иногда запутываться.

Мой вопрос

  • Это эффективный способ хранения карт (учитывая использование плиток) или лучший способ обработки карт?

Я думал вдоль линии гигантской карты. Размер карты большой, и все это одно 2D-массив. Однако в окне просмотра все еще 512x352 пикселей.

Вот еще один .gif, который я сделал (для этого вопроса), чтобы помочь визуализировать:

enter image description here

Извините, если вы не можете понять мой английский. Пожалуйста, спросите все, что у вас есть проблемы с пониманием. Надеюсь, я дал понять. Спасибо.

4b9b3361

Ответ 1

Хорошо, здесь есть несколько вещей, поэтому я буду отвечать им в порядке.


... 521 ОТДЕЛЬНЫЕ ФАЙЛЫ PNG?

enter image description here

Используйте один. Только один. Может, шесть, топы. Подумайте об этом, вы делаете каждый клиент 500 запросов GET только для того, чтобы получить плитки для игры? Эти бредеры.

Почти каждый главный сайт использует spritemaps для сокращения запросов. Например, Youtube использует это одно изображение для всех своих кнопок:

enter image description here

Вы должны сделать то же самое.


Ваша концепция использования холста как видового экрана правильна с точки зрения производительности. Определенно не делайте это больше, чем нужно!


Что касается вопроса о производительности вашей карты, гигантские массивы должны быть прекрасными для начала. Это прекрасный способ справиться с этим, и я бы не стал изучать другие варианты, если ваше слово не очень, очень велико. Если он массивный, у вас могут быть "куски" мира, которые составляют 400x400 (или около того), и когда вы приходите в 400-ю строку, вы начинаете использовать строку 0 следующего массива. Большинство массивов "в использовании" в любое время будут, конечно, четыре, когда ваш герой будет на добром старом в четырех углах.

Местоположение игрока не будет сложным. Если бы он был на плитке 822, 20, это означало бы, что он находится в куске, представленном (2, 0) (если мы начинаем с (0, 0)). В частности, он был бы в плитке 22, 20 из этого куска. Нет сложной математики, нет идентификаторов. Нет необходимости отслеживать идентификаторы. Вам даже не нужно отслеживать, какой кусок - последний кусок. Вы можете просто знать, что общий размер карты (скажем) 1200x1200, и если он попытается перейти на (1201, 50), вам даже не нужно видеть, существует ли кусок (4, 0). Вы сразу знаете, что он не может двигаться туда, карта имеет ширину всего 1200 плиток!

Производительность должна быть хорошей в любом случае и будет зависеть от большого количества других вещей, прежде чем вам придется беспокоиться об этом конкретном массиве. Мой совет - беспокоиться о том, чтобы сделать игру, прежде чем беспокоиться о производительности. Повторите операцию, когда игра будет медленной.

Как только вы достигнете производительности, я буду беспокоиться обо всем, кроме этой проблемы. В игре на холсте его вряд ли станет узким местом. Чтение из массивов происходит быстро. Большие массивы уже в памяти должны быть быстрыми. Не должно быть проблемы, и я не буду тратить время на то, чтобы дождаться, пока он не представится сам.


РЕДАКТИРОВАТЬ: Пример перемещения видового экрана с проигрывателем: http://jsfiddle.net/kmHZt/10/