ACS. Разбираем код инвентаря (1).

Введение

Сегодня, мы разберем код инвентаря представленного в Wad. Кастомный инвентарь (Custom Inventory). Для начала, пройдите по ссылке, и скачайте wad. Затем, откройте его код в Slade или Doom Builder. После этого, можно начинать.

Разбор кода.

#define ITEM_NUMBER 6

define — это комманда для создания константы.

Синтаксис у define, следующий:

#define название_константы значение

Таким образом, константе присваивается значение.

В нашем случае, ITEM_NUMBER, задает максимальное количество предметов в инвентаре.

str posible_items[ITEM_NUMBER] = {"SuperShotgun","RocketLauncher","BFG9000","Chaingun","PlasmaRifle","Shotgun"};
str item_icons[ITEM_NUMBER] = {"SGN2A0","LAUNA0","BFUGA0","MGUNA0","PLASA0","SHOTA0"};

Массив posible_items принимает названия акторов оружия, они в будущем будут использоваться в SetWeapon. Принимает возможные варианты оружия.

Массив item_icons принимает названия иконок, которые будут отображаться у оружий. Например у оружия «SuperShotgun«, будет показываться иконка «SGN2A0«. Массивы posible_items и item_icons, связаны меж собой, это значит что индекс (значение между квадратных скобок [ ]) должен совпадать у обоих массивов.

int img_size = 64.0;

img_size — задает разрешение картинки ячейки. В нашем случае разрешение = 64×64 пикселя. В будущем этот размер будет использоваться для правильного построения таблицы предметов инвентаря.

str your_items[ITEM_NUMBER];
int item_slots[ITEM_NUMBER]; //automaticly generated array

Массив your_items — хранит предметы вашего инвентаря. Его мы будем генерировать автоматически, проверяя наличие предметов в инвентаре, и добавляя их в your_items.

Массив item_slots — указывает есть ли предмет в инвентаре. Если есть предмет, то 1, если нет то 0. Массив item_slots связан с массивом your_items (индексы одинаковые).

Script 1

script 1 (void)
{
  ACS_NamedExecuteWait("InvInit",0,0,0,0);
  ACS_NamedExecute("DrawInventory",0,0,0,0);
}

Скрипт 1 — это стартовый скрипт (именно он вызывается в KEYCONF). В нем вызывается скрипт InvInit, который заполняет массивы значениями. Следующий за ним скрипт DrawInventory, рисует инвентарь, и просчитывает нахождение мышки в каждой из ячеек.

InvInit

Далее разберем скрипт InvInit

script "InvInit" (void)
{
	int i=0;
	//clear arrays
	while(i<ITEM_NUMBER)
	{
		your_items[i] = "none";
		item_slots[i] = 0;
		i++;
	}

Здесь, мы задаем пустые значения массивам your_items и item_slots.

i=0;
while(i<ITEM_NUMBER)
{
  int has_items = CheckInventory(posible_items[i]);
  if(has_items)
  {
    your_items[i] = posible_items[i];
    item_slots[i] = 1;
  }
  i++;
}

А здесь, с помощью CheckInventory, проверяем наличие каждого из предметов posible_items, в нашем инвентаре. Если нашелся предмет, то добавляем его в массив your_items, и занимаем его слот item_slots[i] = 1;

DrawInventory.

Далее идет скрипт DrawInventory, он кстати, основан на коде мышки из урока ACS. Управляем мышкой.:

script "DrawInventory" (void)
{
  SetPlayerProperty(0,1,PROP_TOTALLYFROZEN);

Здесь, мы заморозили игрока.

int MouseX = 200.0;
int MouseY = 200.0;
bool MouseDown = false;

Создали нужные переменные. Далее вошли в бесконечные цикл while.

SetHudSize(640, 400, false);
SetFont("DOOMFONT");

В SetHudSize указали разрешение экрана и указали SetFont(«DOOMFONT»); для дебага.

int DeltaX = -GetPlayerInput(-1, INPUT_YAW);
int DeltaY = -GetPlayerInput(-1, INPUT_PITCH);

Несмотря на то что, игрок заморожен, мы все еще можем получить yaw и pitch через GetPlayerInput. Получаем yaw и pitch игрока.

yaw / pitch / roll — это 3D углы, подробно о них узнать, можно в уроке DECORATE. Добавляем гильзы.

int buttons = GetPlayerInput(-1, INPUT_BUTTONS);
MouseDown = buttons & BT_ATTACK;

Получили код нажатых кнопок GetPlayerInput(-1, INPUT_BUTTONS), и среди всего этого месива, при помощи битовой маски «&» выцепляем кнопку выстрела.

MouseX += DeltaX*0.05;
MouseY += DeltaY*0.05;

Уменьшаем чувствительность мыши

SetCVar("mouseX",MouseX);
SetCVar("mouseY",MouseY);
SetCVar("leftClick",MouseDown);

И присваиваем информацию о мышке, нашим кварам.

createTable(50.0,50.0,5,5);

С помощью createTable, рисуем инвентарь. Синтаксис у него следующий:

createTable(начальное_значение_x, начальное_значение_y, количество_рядов, количество_столбцов);

Далее, остальной код «DrawInventory» я разбирать не буду, потому-что он полностью копирует код мышки из ACS. Управляем мышкой.

	//Mouse
	if(MouseX > 640.0)
	MouseX = 640.0;
	if(MouseX < 0.0)
		MouseX = 0.0;
	if(MouseY > 400.0)
		MouseY = 400.0;
	if(MouseY < 0.0)
		MouseY = 0.0;
	if(!MouseDown)
		SetFont("BAL1A0");
	else
	SetFont("BAL2A0");
	HudMessage(s:"a";HUDMSG_PLAIN,1,CR_BRICK,floor(MouseX),floor(MouseY),0.1);
	Delay(1);
}

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

drawImage.

function void drawImage(str image, int id, int x, int y)
{
  SetFont(image);
  HudMessage(s:"a";HUDMSG_PLAIN,id,CR_BRICK,x,y,0.1);
}

Функция drawImage — это более простой способ рисования изображений. Код, я думаю понятен, если нет то посмотрите урок ACS. Печатаем на экране (HudMessage)

Синтаксис у drawImage следующий:

drawImage("название_изображения", id, x, y)

findIconForItem.

function str findIconForItem(str item_name)
{
	int i = 0;
	while(i<ITEM_NUMBER)
	{
		if(posible_items[i] == item_name)
			return item_icons[i];
		i++;
	}
	return "none";
}

Функция findIconForItem ищет иконку, по названию предмета item_name. Для этого функция findIconForItem ищет предмет item_name в массиве posible_items. Если находит, то по индексу «i» возвращает иконку предмета. Опять же, подобные трюки работают, только потому-что posible_items и item_icons связаны индексом. Если такого предмета не нашлось, в качестве иконки возвращается «none«.

drawItem.

function void drawItem(int index,int block_size, int image_id, int x, int y)
{
	int block_size_div_2 = block_size/2;
	if(item_slots[index] != 0)
	{
		drawImage(findIconForItem(your_items[index]), image_id+500, x+block_size, y+block_size);

		SetFont("DOOMFONT");
		int number_of_items = CheckInventory(your_items[index]);
		if(number_of_items)
		{
		HudMessage(i:number_of_items;HUDMSG_PLAIN,image_id,CR_WHITE,x+block_size_div_2-5.0,y+block_size_div_2-5.0,0.1);
		}
	}
}

Функция drawItem рисует иконку предмета, и его количество. Синтаксис у него следующий:

drawItem(индекс, размер_ячейки, id_изображения, x, y);
  • индекс — так как, данная функция вызывается в цикле. Ему нужно передавать индекс, что-бы перебирать массив последовательно.
  • размер_ячейки — нужен, для вычисления смещения картинки.
  • id — задает id для HudMessage.
  • x,y — координаты, на которых рисуется предмет.
int block_size_div_2 = block_size/2;

Вычисляю смещение картинки.

if(item_slots[index] != 0)

Если предмет, по заданному индексу — существует.

drawImage(findIconForItem(your_items[index]), image_id+500, x+block_size, y+block_size);

То мы рисуем его иконку «findIconForItem(your_items[index])«. Задаем необходимый image_id и смещение, чтобы предмет находился внутри ячейки (ячейка рисуется отдельно).

SetFont("DOOMFONT");
int number_of_items = CheckInventory(your_items[index]);
if(number_of_items)
{
	HudMessage(i:number_of_items;HUDMSG_PLAIN,image_id,CR_WHITE,x+block_size_div_2-5.0,y+block_size_div_2-5.0,0.1);
}

Далее, задаем нужный шрифт. Получаем количество предмета «number_of_items«. И если количество предмета не 0, то рисуем это количество на экране.

HudMessage(i:number_of_items;HUDMSG_PLAIN,image_id,CR_WHITE,x+block_size_div_2-5.0,y+block_size_div_2-5.0,0.1);

Функцию drawItem разобрали, и честно говоря, мы уже много чего разобрали. Функцию createTable, та в которой рисуется инвентарь, я разберу во следующем уроке.

Итоговый результат.

Пожалуйста отключи блокировщик рекламы, или внеси сайт в белый список!

Please disable your adblocker or whitelist this site!