Делаем графическое меню|Всем привет! Этот урок я делаю по заказу многих пользователей нашего сайта. Сегодня будем учиться рисовать меню.|wmysterio|wmysterio||||Как вариант, можно было сделать с помощью панелей, но наша задача сегодня состоит в следующем: написать скрипт драки, где игроку нужно выбрать себе бойца. Иконки участников я возьму со стандартного TXD-архива - обычные карты, что были при игре в покер.
Прежде всего определим размер текстур. Они составили 128 пикселей.
Как уже звучало в уроке по рисованию ранее, размер экрана в GTA SA - 640х448. Сделаем арифметические расчёты, что бы определить к-во картинок, которые поместятся на экран: 640/128 = 5. Такое количество бойцов меня не устроило, так как желательным результатом для меня - 7 персонажей. Следовательно нам нужно рисовать текстуры с меньшем размером. Я подсчитал, что размер должен быть - 64, мы получим 10 бойцов в экране. Так как этого многовато, то с 640 - ( 7*64 ) = 192 пикселей можно равномерно отдалить картинки друг от друга. С размерами определились.
Следующим шагом будет выбор места и условий запуска меню. Я выбрал автошколу в Сан Фиерро. Вот блок условий в нашем скрипте:
{$CLEO}
0000:
var
$PLAYER_ACTOR: actor
$PLAYER_CHAR: player
end
:BOXEN
thread 'BOXEN'
wait 0
while true
03A1: show_sphere_at -2039.1498 -106.7122 34.191 radius 1.5
if AND
0AB0: key_pressed 71 // G
00EC: actor $PLAYER_ACTOR 0 near_point -2039.1498 -106.7122 radius 2.0 2.0
then
if AND
8A0C: not player $PLAYER_CHAR on_jetpack
$ONMISSION == 0
then
gosub @BOXEN_INIT
wait 1000
end
end
wait 0
end
:BOXEN_INIT
wait 0
Следующий шаг - загрузка текстур, объявление переменных:
30@ = 0 - переменная, которая будет условием цикла. Я использую переменную а не true, так как при срабатывании разных условий, мы можем сделать ещё некоторые проверки после цикла и изменить ветвь алгоритма.
0@ = 0 // switch - Эта переменная будет использовать в таблице переходов. Собственно она будет делать наше меню, так как в зависимости от неё будет изменятся прозрачность нашей текстуры. Так как наше меню будет состоять из 7 участников, то к-во пунктов меню тоже будет равна цифре 7, а значения, которые будет принимать - 0, 1, 2, 3, 4, 5 и 6.
1@ ... 7@ - указываем значение прозрачности для загруженных нами текстур на значение 64. Таким образом прозрачность пункта меню, который не выбран будет равен этому значению.
8@ = #WMYDRUG // model enemy - переменная будет менять модель актёра, который будет нашим противником
10@s = 'BJ_PUSH' - строковая переменная носит имя нашего противника и так же меняется в зависимости от выбранного пункта меню.
9@ = 0.0 - переменная отвечает за переключатель меню. Что бы пользователь без проблем мог двигаться по меню, нужно удержать отклик на величину 0.25. Когда переменная будет иметь значения 0.0 1.0 2.0 3.0 4.0 5.0 6.0, то переменная 0@ будет иметь такое же значение, что и 9@, только в целой форме.
Создадим цикл, где укажем условия выхода и условия изменения 0@:
while 30@ == 0
if OR // EXIT
0AB0: key_pressed 71 // G
$PLAYER_ACTOR.Dead
0741: actor $PLAYER_ACTOR busted
09FA: is_menu_closed
then
30@ = -1
end
if
9@ == 0.0
then
0@ = 0
end
if
9@ == 1.0
then
0@ = 1
end
if
9@ == 2.0
then
0@ = 2
end
if
9@ == 3.0
then
0@ = 3
end
if
9@ == 4.0
then
0@ = 4
end
if
9@ == 5.0
then
0@ = 5
end
if
9@ == 6.0
then
0@ = 6
end
// // // Цикл продолжается // // //
wait 0
end
Нужно так же учесть, что если игрок выведет переменные "0@" и "9@" за нужный диапазон, то текстуры пропадут с экран, так как их нужно рисовать в цикле при точных условиях. Нужно написать условия, которые не дают выйти значениям за нужные рамки. В моём случае это такой код:
if
9@ > 6.75
then
9@ = 0.0
end
if
9@ < -0.75
then
9@ = 6.0
end
Осталось нам написать управление переменной "9@". Я сделал, что при нажатии левой или правой стрелки значение уменьшалось или увеличивалось соответственно:
{ NAVIGATE }
if
0AB0: key_pressed 37 // LEFT
then
9@ -= 0.25
end
if
0AB0: key_pressed 39 // RIGNT
then
9@ += 0.25
end
Основная работа закончилась. Теперь нам нужно само рисование. Для этого используем таблицу переходов, что бы назначить модель персонажа и прозрачность всех пунктов меню:
При нажатии ВЛЕВО/ВПРАВО нужная карта будет подсвечиваться а ниже будет отображаться его имя. На этом рисование окончено. Теперь уже техническая часть. Напишем условие, которые выходит из меню:
if
0ab0: key_pressed 32 // Space
then
30@ = 1
end
Как видите, ничего сложного нет, но следует помнить, что вариантов таких графических штучек может быть много и для каждого свой алгоритм. Я привёл самый распространённый вариант - горизонтальное меню. Допишем уже концовку для скрипта:
0391: release_txd_dictionary
if
30@ == 1
then
fade 0 1000
wait 1000
jump @BOXEN_RUN
end
0826: enable_hud 1
0581: enable_radar 1
$PLAYER_CHAR.CanMove = true
$PLAYER_ACTOR.SetImmunities(0, 0, 0, 0, 0)
return
:BOXEN_RUN
wait 0
0826: enable_hud 1
0581: enable_radar 1
$PLAYER_ACTOR.PutAt(-2066.6797, -107.5093, 35.3276)
$PLAYER_ACTOR.Angle = 90.0
camera.Restore_WithJumpCut
camera.SetBehindPlayer
model.Load(8@)
038B: load_requested_models
repeat
wait 0
until model.Available(8@)
29@ = actor.Create(23, 8@, -2078.1331, -107.5472, 34.3203)
actor.Angle(29@) = 270.0
actor.Health(29@) = 1000
model.Destroy(8@)
wait 1000
fade 1 1000
wait 1000
$PLAYER_CHAR.CanMove = true
$PLAYER_ACTOR.SetImmunities(0, 0, 0, 0, 0)
05E2: AS_actor 29@ kill_actor $PLAYER_ACTOR
30@ = 0
while 30@ == 0
if
$PLAYER_ACTOR.Dead
then
30@ = -1
end
if
actor.Dead(29@)
then
30@ = 1
end
wait 0
end
if
30@ == 1
then
01E3: show_text_1number_styled GXT 'WIN_BOX' number 20000 time 5000 style 1 // You Win
$PLAYER_CHAR.Money += 20000
end
return
Полный вариант вы можете скачать здесь. Там вы найдете и исходный код даного скрипта. Ничего сложного нет. Нужно только знать, что должна быть переменная-регулятор ( 9@ ) и переменная-switch ( 0@ ). Позиции уже могут быть абсолютно разные. Хочу добавить, что на разработку скрипта ушло 2.5 часа ( было даже видео, где я кодю ), так что быстро такие скрипты не разрабатываются. На этом урок окончен! С вами, как всегда, был wmysterio. Удачи в рисовании!