Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming / GameProg / RPG_Programming_2ed.pdf
Скачиваний:
240
Добавлен:
12.02.2016
Размер:
12.06 Mб
Скачать

Джим Адамс

while(Item != NULL) { Item->Index = Index++; Item = Item->Next;

}

// Сопоставляем дочерние предметы и родителей

Item = m_ItemParent; while(Item != NULL) {

if(Item->Parent != NULL)

Item->Owner = Item->Parent->Index;

else

Item->Owner = -1; Item = Item->Next;

}

// Сохраняем все

Item = m_ItemParent; while(Item != NULL) {

// Номер предмета

fprintf(fp, "%lu\r\n", Item->ItemNum);

// Количество

fprintf(fp, "%lu\r\n", Item->Quantity);

// Координаты

fprintf(fp, "%lf\r\n%lf\r\n%lf\r\n", Item->XPos, Item->YPos, Item->ZPos);

// Номер владельца

fprintf(fp, "%ld\r\n", Item->Owner);

// Следующий предмет

Item = Item->Next;

}

fclose(fp); // Закрываем файл

return TRUE; // Возвращаем флаг успеха!

}

И, наконец, функцию Free вы используете, когда уничтожаете класс (удаляя таким образом связанный список предметов). Вот код для Free:

BOOL cMapICS::Free()

{

m_NumItems = 0; delete m_ParentItem; m_ParentItem = NULL; return TRUE;

}

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

cMapICS::Add и cMapICS::Remove

Когда на карте появляется новый предмет (например, брошенный игроком), вам необходимо вызвать функцию Add, чтобы этот брошенный предмет был

включен в связанный список объектов карты. Функция Add начинается с

netlib.narod.ru

501

Глава 11. Определение и использование объектов

создания новой структуры sMapItem, затем она заполняет эту структуру

предоставленной вами информацией о предмете и включает структуру в список объектов карты:

BOOL cMapICS::Add(long ItemNum, long Quantity,

float XPos, float YPos, float ZPos, sMapItem *OwnerItem)

{

sMapItem *Item;

//Создание новой структуры данных предмета

Item = new sMapItem();

//Вставляем ее в вершину списка

Item->Next = m_ItemParent; if(m_ItemParent != NULL)

m_ItemParent->Prev = Item; m_ItemParent = Item;

// Заполняем структуру данных

Item->ItemNum = ItemNum; Item->Quantity = Quantity; Item->XPos = XPos; Item->YPos = YPos; Item->ZPos = ZPos; Item->Parent = OwnerItem;

return TRUE;

}

Функцию Add вы вызываете чтобы добавить предмет к списку объектов карты, и точно так же вы и спользуете функцию Remove для удаления

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

BOOL cMapICS::Remove(sMapItem *Item)

{

sMapItem *ItemPtr, *NextItem;

// Сперва удаляем дочерние предметы if((ItemPtr = m_ItemParent) != NULL) {

while(ItemPtr != NULL) { NextItem = ItemPtr->Next; if(ItemPtr->Parent == Item)

Remove(ItemPtr); ItemPtr = NextItem;

}

}

//Удаляем из связанного списка и сбрасываем

//корень, если это текущая голова списка if(Item->Prev != NULL)

Item->Prev->Next = Item->Next;

else

m_ItemParent = Item->Next;

502

netlib.narod.ru

Джим Адамс

if(Item->Next != NULL) Item->Next->Prev = Item->Prev;

//Очищаем связанный список

Item->Prev = Item->Next = NULL;

//Освобождаем память

delete Item;

return TRUE;

}

cMapICS::GetNumItems, cMapICS::GetParentItem и cMapICS::GetItem

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

long cMapICS::GetNumItems() { return m_NumItems; }

sMapItem cMapICS::GetParentItem() { return m_ParentItem; }

sMapItem *cMapICS::GetItem(long Num)

{

sMapItem *Item;

//Начинаем с родительского предмета

Item = m_ItemParent;

//Цикл, пока не достигнут предмет с указанным номером while(Num-) {

if(Item == NULL)

return NULL; // Нет больше предметов для сканирования, // возвращаем ошибку

Item = Item->Next; // Переходим к следующему предмету

}

// в связанном списке

 

return Item; // Возвращаем найденный предмет

}

 

ПРИМЕЧАНИЕ

С указателем на родительскую структуру, возвращаемым

GetParentItem, вы можете просканировать весь связанный список предметов, используя указатель Next

каждой структуры. Если вам надо получить заданную

структуру данных предмета, основываясь на ее индексе в списке, используйте функцию GetItem.

Использование класса cMapICS

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

netlib.narod.ru

503

Глава 11. Определение и использование объектов

предмет к имуществу игрока (если он подбирает находящийся на карте предмет).

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

cMapICS MapICS;

MapICS.Load("sample.mi"); // Загрузка файла

//Добавляем один предмет с номером 10

MapICS.Add(10, 1, 0.0f, 0.0f, 100.0f, NULL);

//Удаляем второй предмет в списке

MapICS.Remove(MapICS.GetItem(1));

//Сохраняем список

MapICS.Save("sample.mi");

Это очень простой пример модификации списка предметов карты, но что мешает нам двинуться дальше и посмотреть, насколько сложным он может быть?

Демонстрационная программа MapICS (рис. 11.9) содержит полный код класса cMapICS, показанный в этой главе и структуру sItem из

программы MIL Editor. Вы можете загрузить программу MapICS с прилагаемого к книге CD-ROM (она находится в папке \BookCode\Chap11\MapICS). В ней используется ICS карты и MIL для визуализации набора объектов, разбросанных по небольшому уровню.

Рис. 11.9. Программа MapICS позволяет вам перемещаться по небольшому уровню, подбирать и бросать предметы

504

netlib.narod.ru

Соседние файлы в папке GameProg