00053. Таймеры

Таймеры|В этом уроке мы рассмотрим работу с таймерами и напишем миссию в качестве примера.|wmysterio|wmysterio||||Очень часто в играх нужно выполнять задания на время. Так же и GTA SA есть такая возможность и в этом вы убедились при прохождении оригинальной игры.

Есть два вида таймеров: возрастающий и убывающий. То есть таймер будет либо прибавлять секунду к времени, либо убавлять. Чтобы создать таймер, нужно использовать опкод:

03C3: set_timer_to $TIMER type 1 GXT 'GXTTIME'

Здесь: $TIMER - переменная ( ЦЕЛОЕ ЧИСЛО ), которая будет хранить время ( в милисекундах ) 1 - тип таймера: 0 - будет прибавлять 1 секунду, 1 - будет отнимать 1 секунду 'GXTTIME' - Перед временем будет выводится текст, например "ВРЕМЯ:" (команду ~1~ использовать не нужно)

Что бы убрать таймер с экрана, используем:

014F: stop_timer $TIMER

Напишем небольшой скрипт. При истечении минуты игроку прибавить миллион:

:TIMER
thread 'TIMER'
wait 0
$TIMER = 60000 // задаём время таймеру 1 минута ( 60 секунд => 60*1000=60000 миллисекунд )
03C3: set_timer_to $TIMER type 1 GXT 'BB_19' // выводим таймер на экран

:TIMER_1
wait 0
if
1 > $TIMER // проверяем: время меньше одной миллисекунды
jf @TIMER_1
014F: stop_timer $TIMER
player.Money($PLAYER_CHAR) += 1000000
end_thread

Давайте усовершенствуем скрипт, чтобы при нажатии кнопки ENTER` ко времени прибавлялось 2 секунды:

:TIMER
thread 'TIMER'
wait 0
$TIMER = 60000 // задаём время таймеру 1 минута ( 60 секунд => 60*1000=60000 миллисекунд)
03C3: set_timer_to $TIMER type 1 GXT 'BB_19' // выводим на экран таймер

:TIMER_1
wait 0
if
0AB0: key_pressed 13 // если нажат ENTER
then
$TIMER += 2000 // прибавляем 2 секунды
end

if
1 > $TIMER // проверяем: время меньше одной миллисекунды
jf @TIMER_1
014F: stop_timer $TIMER
player.Money($PLAYER_CHAR) += 1000000
end_thread

Простой пример мы рассмотрели. Давайте создадим миссию. Когда игрок станет на маркер, появится машина и СЖ будет помещён в неё. После этого появится таймер. Нужно будет успеть за время проехать три точки. Если игрок выйдет с машины и умрёт, то миссия будет считаться проваленой. Я уже написал скрипт и необходимые GXT-записи. Содержимое GXT-записей:

Код миссии:

:MISSION_4
thread 'MISSION_4'
gosub @MISSION_4_29_57 
if 
wasted_or_busted 
jf @MISSION_4_29_46 
gosub @MISSION_4_29_144 

:MISSION_4_29_46
$ONMISSION = 0 
mission_cleanup 
end_thread 

:MISSION_4_29_57
increment_mission_attempts 
$ONMISSION = 1 
0395: clear_area 0 at 2413.7703 -2136.7991 13.3002 radius 300.0
model.Load(#INFERNUS)
038B: load_requested_models

:MISSION_4_1
wait 0
if
model.Available(#INFERNUS)
jf @MISSION_4_1
0@ = car.Create(#INFERNUS, 2413.7703, -2136.7991, 13.3002)
car.Angle(0@) = 0.5542
072A: put_actor $PLAYER_ACTOR into_car 0@ driverseat
03E6: remove_text_box
00BE: text_clear_all
wait 1000
Camera.Restore_WithJumpCut
Camera.SetBehindPlayer
fade 1 1000
wait 1000
player.CanMove($PLAYER_CHAR) = true
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
$TIMER = 6500
03C3: set_timer_to $TIMER type 1 GXT 'TEST002' // global_variable // Time
03BC: 1@ = create_sphere_at 2413.957 -2010.4525 13.0341 radius 2.0
018A: 2@ = create_checkpoint_at 2413.957 -2010.4525 13.0341

:MISSION_4_2
wait 0
if OR
1 > $TIMER // время вышло?
0119: car 0@ wrecked // машина уничтожена?
02BF: car 0@ sunk // машине тонет в воде?
not actor.InCar($PLAYER_ACTOR, 0@) // СЖ не в машине?
then
jump @MISSION_4_29_144
end

 if
 00FE: actor $PLAYER_ACTOR sphere 0 in_sphere 2413.957 -2010.4525 13.0341 radius 2.0 2.0 2.0
 then
 03BD: destroy_sphere 1@
 marker.Disable(2@)
 03BC: 1@ = create_sphere_at 2413.6328 -1882.8612 12.9917 radius 2.0
 018A: 2@ = create_checkpoint_at 2413.6328 -1882.8612 12.9917
 $TIMER += 3000
 jump @MISSION_4_3
 end

jump @MISSION_4_2

:MISSION_4_3
wait 0
if OR
1 > $TIMER
0119: car 0@ wrecked
02BF: car 0@ sunk
not actor.InCar($PLAYER_ACTOR, 0@)
then
jump @MISSION_4_29_144
end

 if
 00FE: actor $PLAYER_ACTOR sphere 0 in_sphere 2413.6328 -1882.8612 12.9917 radius 2.0 2.0 2.0
 then
 03BD: destroy_sphere 1@
 marker.Disable(2@)
 03BC: 1@ = create_sphere_at 2413.1089 -1733.569 13.0411 radius 2.0
 018A: 2@ = create_checkpoint_at 2413.1089 -1733.569 13.0411
 $TIMER += 3000
 jump @MISSION_4_4
 end

jump @MISSION_4_3

:MISSION_4_4
wait 0
if OR
1 > $TIMER
0119: car 0@ wrecked
02BF: car 0@ sunk
not actor.InCar($PLAYER_ACTOR, 0@)
then
jump @MISSION_4_29_144
end

 if
 00FE: actor $PLAYER_ACTOR sphere 0 in_sphere 2413.1089 -1733.569 13.0411 radius 2.0 2.0 2.0
 then
 03BD: destroy_sphere 1@
 marker.Disable(2@)
 jump @MISSION_4_5
 end

jump @MISSION_4_4

:MISSION_4_5
wait 0
0318: set_latest_mission_passed 'TEST001' 
01E3: show_text_1number_styled GXT 'M_PASS' number 20000 time 4000 style 1 
Player.Money($PLAYER_CHAR) += 20000
play_music 1
gosub @MISSION_4_END
create_thread @STARTER_5
return 

:MISSION_4_29_144
wait 0 
gosub @MISSION_4_END
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 
create_thread @STARTER_5 
return

:MISSION_4_END
wait 0 
014F: stop_timer $TIMER
03BD: destroy_sphere 1@
marker.Disable(2@)
return

А вот и полный код для main. На сайт не помещается, так что приходится хранить его на сервере :) У Вас обязательно выйдет что то типа этого:

Теперь рассмотрим детальнее об переменных "32@" и "33@". Как уже было ранее сказано, они являются таймерами и изменяют свои значения динамически, тем самым не давая возможности хранить в них другие данные.

Переменная "33@" ( Как и "32@" ) каждый раз прибавляет к своему значению число. Это хорошо видно с такого скрипта:

33@ = 0
for 0@ = 0 to 10
0AD1: show_formatted_text_highpriority "%d" time 1000 33@
wait 1000
end

Раз в секунду выводится состояние переменной, при этом заметно её значение, которое прибавляется примерно на 1000 миллисекунд ( +разница во времени между кадрами ).|1790|1|0|72011657jpg640400400250``\|10703885jpg437341400312``||tajmery|1499521337

Last updated