ACS. Управляем мышкой.

Данный урок, является продолжением урока ACS. Захватываем управление.

Предисловие

Комманда PlayerInput, помимо проверки нажатых клавиш, может считывать pitch и yaw (подробнее об углах в 3D пространстве здесь). Полученные данные позволят нам, двигать курсор по экрану.

Создаем курсор.

Перед началом, скачайте спрайты курсора на MEGA. Загрузите их к себе в wad, и задайте правильное смещение.

После этого, откройте ACS, и добавьте туда следующий код:

script 16 (void)
{
  SetPlayerProperty(0,1,PROP_TOTALLYFROZEN);
  int MouseX = 200.0;
  int MouseY = 200.0;
  bool MouseDown = false;
  while(true)
  {
    SetHudSize(640, 400, false);
    int DeltaX = -GetPlayerInput(-1, INPUT_YAW);
    int DeltaY = -GetPlayerInput(-1, INPUT_PITCH);
    int buttons = GetPlayerInput(-1, INPUT_BUTTONS);
    MouseDown = buttons & BT_ATTACK;
    MouseX += DeltaX*0.05;
    MouseY += DeltaY*0.05;
    //--> Debug <--//
    SetFont("DOOMFONT");
    print(s:"x: ",f:MouseX,s:"\ny: ",f:MouseY,s:"\nPressed: ",b:MouseDown);
    if(!MouseDown)
      SetFont("ARROW");
    else
      SetFont("ARROW2");
    HudMessage(s:"a";HUDMSG_PLAIN,1,CR_BRICK,floor(MouseX),floor(MouseY),0.1);
    Delay(1);
  }
}

Теперь, разберем этот код подробно:

SetPlayerProperty(0,1,PROP_TOTALLYFROZEN);

SetPlayerProperty — многофункциональная комманда, которая меняет состояние игрока. В нашем случае, она его замораживает. Синтаксис у неё следующий:

SetPlayerProperty(tid_игрока,значение, property);
  • tid_игрока — указывает tid игрока.
  • значение — присваивает значение к property.
  • property— что менять.
int MouseX = 200.0;
int MouseY = 200.0;
bool MouseDown = false;

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

SetHudSize(640, 400, false);

Устанавливаем разрешение экрана равным 640×400 px.

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

Получаем относительные значения yaw и pitch.

  • yaw — (кручение мышкой влево / вправо)
  • pitch — (кручение мышкой вверх / вниз)

Комманду GetPlayerInput, я разбирал в уроке ACS. Захватываем управление.

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

Далее, получаем код нажатых кнопок

GetPlayerInput(-1, INPUT_BUTTONS);

И, среди нажатых кнопок, проверяем, нажата ли кнопка стрельбы (BT_ATTACK)?

MouseDown = buttons & BT_ATTACK;

Битовая маска «&» при нажатии вернет true.

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

Меняем координаты курсора, в зависимости от yaw и pitch. Чувствительность мыши, по умолчанию, крайне высока, поэтому мы её уменьшим, умножив изменение позиции мыши (DeltaX / DeltaY) на 0.05.

//--> Debug <--//
SetFont("DOOMFONT");
print(s:"x: ",f:MouseX,s:"\ny: ",f:MouseY,s:"\nPressed: ",b:MouseDown);

Дальше идет Debug, он нужен для отладки, вы можете его пропустить.

if(!MouseDown)
  SetFont("ARROW");
else
  SetFont("ARROW2");

Если не нажата ПКМ, то рисуем обычный курсор, если нажата, рисуем нажатый курсор.

HudMessage(s:"a";HUDMSG_PLAIN,1,CR_BRICK,floor(MouseX),floor(MouseY),0.1);

Здесь, мы рисуем курсор. Позиции MouseX и MouseY я округлил до целых чисел, при помощи функции floor. Если этого не сделать, то курсор будет дергаться.

Смотрим, что в итоге получилось.

Круто, работает, но пока, пользы от курсора 0. Исправим это.

Используем курсор.

Чтобы курсор не улетал за границы экрана, добавьте в ACS следующий код:

//Mouse frame
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;

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

Далее я нарисовал на экране, спрайт оружия «coolGun«.

SetFont("CWERA0");
HudMessage(s:"a";HUDMSG_PLAIN,2,CR_BRICK,300.0,200.0,0.1);

И, при помощи хардкодинга, я написал условие при котором, если курсор находится на координатах «coolGun» и нажата ПКМ, то выдается оружие и патроны.

if(MouseDown)
  {
    if((MouseX > 350.0 && MouseX < 460.0) && (MouseY > 240.0 && MouseY < 320.0))
    {
      GiveInventory("coolGun",1);
      GiveInventory("coolGunAmmo",20);
      SetWeapon("coolGun");
      Delay(5);
      SetPlayerProperty(0,0,PROP_TOTALLYFROZEN);
      Terminate;
    }
  }

Теперь, подробнее:

if(MouseDown)
  {
    if((MouseX > 350.0 && MouseX < 460.0) && (MouseY > 240.0 && MouseY < 320.0))
    {

Если нажата ПКМ, и курсор находится на координатах «coolGun«, то:

GiveInventory("coolGun",1);
GiveInventory("coolGunAmmo",20);

Выдаются оружие и патроны.

SetWeapon("coolGun");

Оружие «coolGun» берется в руки.

Delay(5);

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

SetPlayerProperty(0,0,PROP_TOTALLYFROZEN);

Размораживаем игрока.

Terminate;

И выходим из скрипта. Тем самым, возвращаем игроку управление.

Полный код, можете посмотреть здесь:

Скрытый текст
script 16 (void)
{
	SetPlayerProperty(0,1,PROP_TOTALLYFROZEN);
	int MouseX = 200.0;
    int MouseY = 200.0;
	bool MouseDown = false;
	while(true)
	{
		SetHudSize(640, 400, false);
		SetFont("DOOMFONT");

		int DeltaX = -GetPlayerInput(-1, INPUT_YAW);
		int DeltaY = -GetPlayerInput(-1, INPUT_PITCH);
		int buttons = GetPlayerInput(-1, INPUT_BUTTONS);
		MouseDown = buttons & BT_ATTACK;
		MouseX += DeltaX*0.05;
		MouseY += DeltaY*0.05;
		//--> Debug <--//
		print(s:"x: ",f:floor(MouseX),s:"\ny: ",f:floor(MouseY),s:"\nPressed: ",b:MouseDown);

		SetFont("CWERA0");
		HudMessage(s:"a";HUDMSG_PLAIN,2,CR_BRICK,300.0,200.0,0.1);
		if(MouseDown)
		{
			if((MouseX > 350.0 && MouseX < 460.0) && (MouseY > 240.0 && MouseY < 320.0))
			{
				GiveInventory("coolGun",1);
				GiveInventory("coolGunAmmo",20);
				SetWeapon("coolGun");
				Delay(5);
				SetPlayerProperty(0,0,PROP_TOTALLYFROZEN);
				Terminate;
			}
		}

		//Mouse frame
		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("ARROW");
		else
			SetFont("ARROW2");
		HudMessage(s:"a";HUDMSG_PLAIN,1,CR_BRICK,floor(MouseX),floor(MouseY),0.1);
		Delay(1);
	}
}

В итоге, получилось следующее.

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