Decorate. Создание рун.

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

Разбираем акторы

Перед началом, скачайте wad с MEGA.

Затем, откройте в нем файл DECORATE. Там находятся 3 актора:

  • rune_part — руна, которая спавнит rune_part_generator каждые 10 тиков (1 тик = 1/35 секунды)
  • rune_part_generator — невидимый актор, спавнит вокруг себя несколько частиц, придавая им скорость.
  • my_rune — актор частицы, со временем исчезает.

Вот код наших акторов.

actor my_rune : Inventory 10000 {
	ActiveSound SFIRE
	height 32
	radius 32
	+float
	+floatbob
	states {
		spawn:
			TNT1 A 0 A_LoopActiveSound
			RUNE A 0 A_SpawnItemEx("rune_part_generator",0,0,0,0,0,0,0,0,0,0)
			RUNE A 10 Bright

			loop
		pickup:
			RUNE A 1 A_StopSound
			stop
	}
}
actor rune_part_generator {
	+NOGRAVITY
	+noclip
	states {
		spawn:
			TNT1 AAAAAAAAA 1 A_SpawnItemEx("rune_part",random(20,-20),random(20,-20),random(-10,20),0,0,random(2,6),0,128,0)
			stop
	}
}
actor rune_part {
	+noclip 
	+NOGRAVITY
	scale 0.3
	states {
		spawn:
			PART AAAAAAAAAA 2 Bright A_FadeOut
			stop
	}
}

Разберем эти акторы.

+float
+floatbob

Эти флаги заставляют спрайт актора передвигаться вверх/вниз.

ActiveSound SFIRE

В качестве звука активации, устанавливаем звук огня. Звук SFIRE, как и все другие, задаются в SNDINFO.

spawn:
  TNT1 A 0 A_LoopActiveSound
  RUNE A 0 A_SpawnItemEx("rune_part_generator",0,0,0,0,0,0,0,0,0,0)

В стейте spawn, включаем повтор звука активации (огня) с помощью комманды A_LoopActiveSound

И спавним rune_part_generator.

actor rune_part_generator {
	+NOGRAVITY
	+noclip
	states {
		spawn:
			TNT1 AAAAAAAAA 1 A_SpawnItemEx("rune_part",random(20,-20),random(20,-20),random(-10,20),0,0,random(2,6),0,128,0)
			stop
	}

Он же в свою очередь, спавнит несколько частиц, находящийся на случайном расстоянии вокруг руны. Так-же, скорость частицы случайна random(2,6), и направленна вверх по оси z.

У генератора частиц, нет ни гравитации (+NOGRAVITY), ни коллизии (+noclip), т.к. они ему не нужны.

actor rune_part {
	+noclip 
	+NOGRAVITY
	scale 0.3
	states {
		spawn:
			PART AAAAAAAAAA 2 Bright A_FadeOut
			stop
	}
}

Сама частица, постепенно становится прозрачной (A_FadeOut), и затем исчезает.

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

pickup:
  RUNE A 1 A_StopSound
  stop

С руной разобрались. Перейдем к ACS коду.

Разбираем ACS код.

Функции drawImage, drawString, drawInt, я разбирать не буду т.к. разбирал здесь

Нас сейчас интересуют две скрипта:

  • player_loop — проверяется наличие нужной руны
  • simple_rune — скрипт, который вызывается, если подобрана.

Т.е. в этом скрипте

script "player_loop" ENTER {
	SetHudSize(640, 480,0);
	if (CheckInventory("my_rune") > 0)
	{
		ACS_NamedExecute("simple_rune",0);
	}
	Delay(1);
	restart;
}

Вызывается скрипт simple_rune. Самое приятное то, что ACS_NamedExecute, не позволит вызвать скрипт simple_rune, пока он не закончит свою работу, поэтому проблем с синхронизацией не возникнет.

ACS_NamedExecute("simple_rune",0);

Если количество предметов my_rune больше 0 (если есть в наличии).

if (CheckInventory("my_rune") > 0)

Далее идем скрипт simple_rune.

script "simple_rune" (void) {
	int my_timer = 1000;

	while(CheckInventory("my_rune") > 0) {
		drawInt(my_timer, 1, 1000,1000);
		drawImage("RUNEA0",5,2000,12000);
		if (my_timer <= 0) break;
		if ((my_timer % 35) == 0) {
			HealThing(10);
		}
		SpawnForced("rune_part_generator",GetActorX(0),GetActorY(0),GetActorZ(0),0,0);
		my_timer--;
		Delay(1);
	}
	TakeInventory("my_rune", 1);
	Delay(1);
}

В нем хранится переменная my_timer, которая указывает время действия руны в тиках.

Если руна в инвентаре (подобрана)

while(CheckInventory("my_rune") > 0) {

То, рисуем значение таймера, и картинку руны, на экране.

drawInt(my_timer, 1, 1000,1000);
drawImage("RUNEA0",5,2000,12000);

Если таймер <= 0, то выходим из цикла.

if (my_timer <= 0) break;

Каждые 35 тиков (1 секунда) мы выдаем игроку 10 хп.

if ((my_timer % 35) == 0) {
  HealThing(10);
}

Спавним на месте игрока, частицы руны.

SpawnForced("rune_part_generator",GetActorX(0),GetActorY(0),GetActorZ(0),0,0);

Уменьшаем на единицы таймер, чтобы цикл не был бесконечным. И делаем заддержку в 1 тик.

my_timer--;
Delay(1);

После того, как руна отработала свое, мы её отбираем.

TakeInventory("my_rune", 1);

Разбираем по мелочи.

Осталось разобрать GLDEFS который добавляет свечение акторам, и SNDINFO добавляющий звуки.

GLDEFS, я подробно разбирал здесь.

FLICKERLIGHT rune_light
{
Color 1 0 0
OffSet 0 8 0
Size 20
SecondarySize 35
Chance 0.2
}

object rune_part
{
	frame PARTA0 {light rune_light}
}

У SNDINFO синтаксис элементарный.

название_переменной название_файла
  • название_переменной — название звука в коде Decorate и ACS.
  • название_файла — имя файла без расширения, которое будет проигрываться при вызове название_переменной

Собственно, вот код SNDINFO.

SFIRE SFIRE
ZLOVESCH ZLOVESCH

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

avatar

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

Please disable your adblocker or whitelist this site!