Представление Темницы
Эта статья была первоначально написана для Darren Hebden's RLNews
Содержание |
Вопрос
Одна из наиболее важных вещей в написании компьютерной игры любой категории является способ представления вселенной, в которой действует игра. В roguelike, вам понадобится представлять несколько вещей:
- Темница
- Гадкие Вещи в Темнице
- Заостренные Вещи с которыми игрок убивает Гадкие Вещи
- Игрок, который держит Заостренные Вещи
Эта статья опишет 1: Темница.
Темница
Хорошо, нам нужен способ представления коридоров и самих комнат Темницы. Наиболее легчайший и наиболее гибкий метод - это создать двумерный массив ячеек. Каждая ячейка будет стеной, полом, дверью, скрытой ямой смерти, или любым количеством других вещей, которые мы можем захотеть представить, как один тайл (секцию):
class Tile
{
public:
int Type; // 0-Стена 1-Пол 2-Вода 3-Открытая 4-Закрытая Дверь...
unsigned int Flags; // смотри ниже...
}
Битовые флаги
Один из наболее важных и экономичных методов хранения информации - это использование битовых флагов. Как Вы знаете, число в компьютере представлено в двоичном виде, которое является серией единиц и нулей... Например, число 14 представлено как: 00001110
Теперь, скажем нам нужно отслеживать множество вещей о тайлах... Он освещен? Он изучен? - Всегда темен? Непостижим?
Мы можем использовать каждый индивидуальный бит в числе, чтобы отслеживать истинность/ложность ответов на подобные вопросы. Так, как получить единственный индивидуальный бит? С помощью поразрядных операторов.
Мы можем получать индивидуальный бит числа, используя & оператора (поразрядный И). Каждый бит представляет степень двойки... Так что первый бит - 1, второй - 2 третий 4 четвертый 8 и так далее... &-оператор берет два целых числа и возвращает целое, которое имеет биты только в тех позициях, где два оригинальных числа ОБА имели эти биты... Так мы берем переменную, содержащую флаги и & это с числом-маской, имеющей только те биты, которые нам нужно проверить. Если возвращенное число не является нулем, флаг установлен, если он нуль - флаг не установлен...
Это немного запутывает, я не сомневаюсь, так что вот некоторые примеры:
Пример 1: (Мы будем использовать 16-битовые целые, чтобы сохранить пространство)
Flags : 0101000010010100
проверяем бит - ^
Это пятый бит, так что 2^4 = 16.
16 это 0000000000010000... так
Flags & 16 = ?
Flags:0101000010010100
&&&&&&&&&&&&&&&&
16:0000000000010000
================
0000000000010000;
Который больше, чем 0, так что флаг установлен...
Пример 2:
Flags : 0101000010010100
проверяем бит - ^
Это четвертый бит, так что 2^3 = 8.
8 это 0000000000001000... так
Flags & 8 = ?
Flags:0000000010010100
&&&&&&&&&&&&&&&&
8:0000000000001000
================
0000000000000000;
Который 0, так что флаг не установлен...
Возврат к темнице...
Итак, мы определили свой основной класс Тайла. Все что нам нужно сделать теперь - это создать массив этих тайлов:
Tile Map[256][256];
Теперь, приложите ваш любимый метод генерации темницы к этому массиву тайлов и вуаля! У вас есть темница.
Позиционное Представление
Все в Темнице будет иметь позицию в ее пределах. Эта позиция просто определена как x и y координаты в пределах 2D массива тайлов. Если игрок в 16,19, мы могли бы найти тайл, который он использует, строкой: Map[16][19], Если игрок в 31,53, мы могли бы использовать Map[31][53]... Итак, мы можем обобщить и сказать, что если игрок имел позицию, занимающую X и Y, мы могли бы использовать строку: Map[Player.X][Player.Y].
Мы могли бы также захотеть расширить определение позиции давая ему направление...
8 1 2 \ | / \|/ 7--*--3 /|\ / | \ 6 5 4
Так...
class Position
{
public:
int X,Y; // Координаты
int Facing; // Направление этого объекта.
}
Все в вашей темнице должно иметь позицию. Каждое чудовище, каждый предмет, который лежит на земле, и игрок. Это позволит Вам отслеживать каждую вещи и их отношения.
Автор: Brian Bucklew.
Источник: Representing the Dungeon.
Перевел: Сергей В. Ждановских [Alchemist], 16.06.2005.