netlib.narod.ru< Назад | Оглавление | Далее >

Размещение персонажей на карте

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

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

Список персонажей карты

В ряде глав, например, в главе 10, «Реализация скриптов», я использовал внешние файлы данных, которые хранили набор чисел и текстов. Эти файлы данных загружались и преобразовывались в некую полезную информацию для загружающего данные движка. Например, шаблоны действий, содержат текст действия и данные элементов для каждого действия, и все в одном, простом для чтения и редактирования файле.

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

0  100.0  0.0 450.0  0.0
21   0.0  0.0 -82.0 1.57
18 640.0 10.0   0.0 3.14

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

Теперь, зная что означает каждое число, вы видите, что я определил три персонажа, разместил их на карте в соответствующих местах и обратил в заданном направлении. Эти данные компактны, просты для редактирования, и могут быть быстро загружены и обработаны.

Загрузка списка персонажей карты

Чтобы обработать файл данных, как было только что описано, вам необходимы только две функции (которые вы уже видели в главе 10). Вот эти функции:

long GetNextLong(FILE *fp)
{
    char Buf[1024];
    long Pos = 0;
    int c;

    // Читаем, пока нет EOF или EOL
    while(1) {
        if((c = fgetc(fp)) == EOF)
            break;
        if(c == 0x0a || (c == ' ' && Pos))
            break;
        if((c >= '0' && c <= '9') || c == '.' || c == '-')
            Buf[Pos++] = c;
    }

    if(!Pos)
        return -1;

    Buf[Pos] = 0;

    return atol(Buf);
}

float GetNextFloat(FILE *fp)
{
    char Buf[1024];
    long Pos = 0;
    int c;

    // Читаем, пока нет EOF или EOL
    while(1) {
        if((c = fgetc(fp)) == EOF)
            break;
        if(c == 0x0a || (c == ' ' && Pos))
            break;
        if((c >= '0' && c <= '9') || c == '.' || c == '-')
            Buf[Pos++] = c;
        }

    Buf[Pos] = 0;

    return (float)atof(Buf);
}

Обе функции получают в аргументе указатель на файл (fp) и возвращают следующее число типа long или float, найденное в указанном файле. Вы организуете данные списка персонажей карты таким образом, что первое число (тип персонажа) будет типа long, а все остальные числа будут float.

Используя GetNextLong и GetNextFloat вы можете выполнить разбор всего списка персонажей карты следующим образом:

// fp = указатель на открытый файл с данными персонажей карты
long Type; // Тип загружаемого персонажа
float XPos, YPos, ZPos, Direction;
long NumCharactersLoaded = 0; // Кол-во загруженных персонажей

while(1) {
    // Прерываемся, если больше нет персонажей для обработки
    if((Type = GetNextLong(fp)) = = -1)
        break;

    // Получаем координаты и угол
    XPos = GetNextFloat(fp);
    YPos = GetNextFloat(fp);
    ZPos = GetNextFloat(fp);
    Direction = GetNextFloat(fp);

    // Делаем что-нибудь с данными - вставляем персонаж

    NumCharactersLoaded++; // Увеличиваем кол-во загруженных персонажей
}
// Завершили загрузку, в NumCharactersLoaded кол-во загруженных персонажей

Использование списка персонажей карты в вашей игре

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

Скриптовое размещение

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

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

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

Как вы могли предположить, можно использовать систему Mad Lib Script, представленную в главе 10, создав и включив шаблон действий и обработчик скриптов в ваш проект — тогда обработчик скрипта берет на себя задачу добавления персонажей на карту на основании скриптов, которые вы напишете для вашей игры.

Пример шаблона действий, который добавляет персонажи к карте, может выглядеть так:

"Add character # ~ to map at coordinates ~, ~, ~"
INT 0 65535
FLOAT -5000 5000
FLOAT -5000 5000
FLOAT -5000 5000

Определив это единственное действие вы можете конструировать небольшие скрипты, размещающие персонажи (с уникальным идентификационным номером) на карте, основываясь на предоставляемых вами координатах X, Y и Z. Быстрое, чистое и верное по сути использование скриптов определенно является тем путем, по которому следует идти, и именно этот метод я использую для добавления персонажей на карту в законченной ролевой игре из главы 16, «Объединяем все вместе в законченную игру».


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz