Тайлы - как правильно?
| |
likov | Дата: Пятница, 09 Ноября 2012, 23:46 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Вот, например, 2D игра. У сцены есть слои:
* статичный фон * задний план (облака, гряда гор, городской пейзаж и т.п.) * средний план (здесь блоки с коллизиями - платформы, здания, сталактиты) * предметы * спрайты * передний план (камни, кусты, колючая проволока, облака)
Первая идея сделать примерно так:
Code // псевдокод Map map = new Map("map.xml"); // размеры и картинки определены в карте Camera scene = new Camera(map); // игровая сцена Camera radar = new Camera(map, true); // а это будет окошко радара
scene.SetViewport(100,100, 400, 300); // задаем вьюпорты на экране - x,y,w,h radar.SetViewport(500,500, 100, 100);
// игровой цикл scene.SetArea(x-5, y-5, x+5, y+5); // сцена это часть карты radar.SetArea(0,0,100,100); // а радар - вся карта, но очень мелкая x++; // перемещаем направо
// отрисовка scene.Draw(); // radar.Draw(); //
Суть примерно понятна, да? 1) Создаем карту 2) Камере передаем ссылку на карту 3) Камера запрашивает у карты данные и отображает их
Проблема у меня с отрисовкой спрайтов. Карта тайловая и адресация сделана на уровне блоков. Но спрайты должны двигаться гладко, попиксельно, и я никак не могу решить, как их отображать на карту. Я придумал три корявых способа:
1) Сделать слой в карте с пиксельной адресацией. Мне не нравится, потому что иметь разные системы неудобно. 2) Отдать массив спрайтов камере, чтобы она сама выводила их в нужном слое. Это еще одна жесткая связь между классами. 3) Вызывать методы Draw с указанием слоя: scene.Draw(city), и в нужном месте выводить спрайты: sprites.Draw();
Мне нравится второй способ, несмотря на его избыток связей.
Но может есть варианты грамотнее? Best practices?
Сообщение отредактировал likov - Пятница, 09 Ноября 2012, 23:50 |
|
| |
Julius | Дата: Суббота, 10 Ноября 2012, 08:56 | Сообщение # 2 |
почетный гость
Сейчас нет на сайте
| Я бы использовал все-таки первый способ. Мне он кажется наиболее удобным и простым.
Давай, кусок кириллятины, ставь мне минус!
|
|
| |
likov | Дата: Воскресенье, 11 Ноября 2012, 01:29 | Сообщение # 3 |
был не раз
Сейчас нет на сайте
| А почему он вам кажется наиболее удобным? Поясните пожалуйста.
|
|
| |
Julius | Дата: Воскресенье, 11 Ноября 2012, 08:52 | Сообщение # 4 |
почетный гость
Сейчас нет на сайте
| likov, потому что я ненавижу создавать жесткие связи между классами По сути, это единственная причина.
Давай, кусок кириллятины, ставь мне минус!
|
|
| |
likov | Дата: Воскресенье, 11 Ноября 2012, 15:55 | Сообщение # 5 |
был не раз
Сейчас нет на сайте
| Резонно.
Я пока остановился на таком:
Code // псевдокод
TiledMap tiledMap = new TiledMap("level1"); // все параметры указаны в карте GameArea gameArea = new GameArea(tiledMap); // передаю карту в логику уровня
// gameArea.Update
if (new badass appeared) this.AddSprite(new Badass(x,y,)); if (one sprite hear another) sprite1.KeepAnEye(sprite2); if (weather is rainy) tiledMap.SetLayerVisible('rain'); if (player entered blue door) tiledMap.Load('bluepalace'); if (level is over) ScreenChange('summary');
// gameArea.Draw tiledMap.SetViewport(412,126,800,480); // x,y,w,h - положение и размер вьюпорта. что в него не попадает, то не рисуем foreach (layer in tiledMap.layers) {
layer.Draw(); if (layer.Name=='Sprites') foreach (sprite in sprites) { sprite.Draw(412,126,800,480); }
}
Слой Sprites должен быть пустым, хотя не обязательно. Связи между классами получаются прочными, но тут никуда не деться - GameArea это супервизор уровня.
Это не финальный вариант, потому что, например, как пометить тайл разбитым? Есть не самая безнадежная идея передать часть логики в саму tileMap:
Code // псевдокод public void Hit(x,y) { xtile = x/tilewidth; ytile = y/tileheight; tiles(activeLayer, xtile, ytile).Health--; }
а Draw выводит целый, разбитый или уничтоженный тайл в зависимости от величины Health.
|
|
| |
|