И снова рад приветствовать всех вас на своем канале! В прошлых двух уроках мы с вами создали уровень с кирпичами, биту и мяч. Научили биту двигаться влево и вправо, сделали так, чтобы бита упиралась в стены.
А сегодня давайте уже наконец поработаем с мячом. Научим его летать, отскакивать от стен с битой и разбвать кирпичи.
Поехали!
Запускаем мяч
С прошлых уроков мы в мяч добавили всего одну строчку кода в событии шага:
x = Bat.x
Этот код "заставлял" мяч приклеиться к бите и двигаться вместе с ней. Но если мы запустим мяч, то он не сможет летать, так как его x координата будет постоянно привязана к x координате самой биты. По этому давайте введем еще одну переменную, которая будет отвечать за то, стоитли у нас мяч на бите или запущен в полет.
Давайте добавим событие создания (Create) в объекте мяча и объявим в нем переменную:
fixed=true
Это булева переменная. Что это значит? Булева переменная - это та, что может иметь только два значения: true (истина) или false (ложь). Их можно заменить соответственно: 1 (истина) или 0 (ложь).
Я назвал переменную fixed, что значит "зафиксирован", и присвоил ей значение true (истина). Т.е. логически это можно понять как то, что при создании мяча, он зафиксирован. Теперь давайте подправим код в событи шага мяча:
if fixed=true {x = Bat.x}
Т.е. мы добавили проверку условия - если мяч зафиксирован, то его координата будет всегда равняться координате самой биты. Если вы запустите сейчас игру, то увидите, что ничего не изменилось. Но эта переменная нам пригодится далее, думаю вы уже сами понимаете для чего. Когда мы запустим мяч, то просто сменим данную переенную на false и тогда код в скобках {} выполянться не будет и соответственно мяч не будет следовать за битой.
Так. Необходимую подготовку мы провели. Теперь давайте подумаем в каких напрявлениях может летать мяч, введем переменную для направления мяча и для каждого из направлений присвоим свое значение. Вроде кажется несколько запутанным, но из рисункуе ниже все поймете:
Т.е. мы введем переменную dir, которая у нас как раз и будет отвечать за направление полета мяча и условно примем то, что при значении этой переменной:
- равной 0, мяч будет лететь по диагонали влево и вверх
- равной 1, мяч будет лететь по диагонали вправо и вверх
- равной 2, мяч будет лететь по диагонали влево и вниз
- равной 3, мяч будет лететь по диагонали вправо и вниз
Ок. Теперь давайте все то же самое пропишем кодом. Для начала в событии создания мяча добавим еще оду строчку и код будет таким:
fixed=true
dir=0
Т.е. мы задали направление мячу влево вверх.
А вот в событии шага код у нас уже будет побольше:
if fixed=true {x = Bat.x}
if fixed=false {
if dir=0 {x-=2 y-=2}
if dir=1 {x+=2 y-=2}
if dir=2 {x-=2 y+=2}
if dir=3 {x+=2 y+=2}
}
Много расписывать не буду. Думаю вы уже сами вполне можете прочитать данный код. Т.е. если мяч зафиксирован, то x координата мяча будет всегда равняться x координате биты. А вот если мяч не зафиксирован (fixed=false), то в зависимости от направления мяча каждый шаг меняются необходимые нам координаты. Например, при направлении мяча влево вверх, при dir=0, у нас каждый шаг будет xуменьшаться на 2 пикселя и y уменьшатся на 2. Не забываем, что координатная плоскость в GMS2 направлена с верхнего левого угла в правый нижний.
Теперь нам осталось добавить условие, чтобы переменная fixed менялась с true на false. Давайте сделаем, чтобы смена происходила при нажатии на клавишу пробел. А так как у нас все управление находится в объекте биты, то давайте поместим этот код туда.
Вообще, все необходимые знания для этого у вас уже есть. Я рассказал вам обо всем в первых двух уроках. Но если не получается, то код в событии шага биты будет такой:
if keyboard_check(vk_right) {
if !place_meeting(x+spd,y,Wall) {x+=spd}
}
if keyboard_check(vk_left) {
if !place_meeting(x-spd,y,Wall) {x-=spd}
}
if keyboard_check(vk_space) {
Ball.fixed=false
}
У нас там уже был код для движения биты влево и вправо. Мы лишь добавили код нажатия клавиши пробел (vk_space) и если клавиша нажата, то меняли переменную fixed объекта мяча (Ball) на значение false (ложь).
Как вы помните с прошлых уроков, что чтобы обратиться к переменной одного объекта из другого, то используем такую конструкцию: имя объекта в котором хотим поменять переменную + точка + имя переменной (Ball.fixed = false).
Теперь, если вы запустите игру, то при нажатии пробела мяч полетит влево вверх.
Давайте добавим чуть разнообразия. Пора внести немного рандома в нашу игру! Не очень интересно, что каждый раз при запуске мяча он всегда летит влево. Было бы неплохо, чтобы он летел или влево или вправо. И это вполне можно сделать. Немного изменим код в событии создания мяча:
fixed=true
dir=choose(0,1)
Новая функция choose случайно выбирает одно из значений в скобках. Т.е. при каждом запуске переменная dir будет равна либо 0 либо 1, т.е. мяч будет лететь при запуске либо влево либо вправо.
Значений в скобках может быть несколько, т.е. функция может иметь следующий вид:
spd=choose(1,4,6,10,12,20), в этом случае переменная spd примет любое случайное значение из представленных в скобках.
В GMS2 есть еще несколько функций генераторов случайных чисел. Например, одни из часто используемых random и irandom.
Вид у них такой:
spd=random(20)
В данной функции в скобках уже указываем только одно значение. И при таком коде переменная spd примет любое значение от 0 до 20, включая дробные числа. Например, 0.5, 12, 4.7, 18.2. И т.д.
Отличие функции irandom от random лишь в том, что irandom возвращает только целые числа. Т.е. при коде:
spd=irandom(20) ,
переменная spd примет любое случайное целое число. Например, 0, 2, 3, 5, 12, 17 и т.д.
Думаю вы поняли. В GMS2 на самом деле есть и другие функции для рандома, можете подробнее узнать о них из справки если понадобится. На первых порах вам будет достаточно этих: choose, random и irandom.
Это было неболшьое отступление, но теперь давайте вернемся к самой игре. Я предлагаю ввести еще клавишу для рестарта (перезапуска) игры. Пусть это будет клавиша R на клавиатуре. Добавим код в событие шага все той же биты, где у нас все управление игрой:
if keyboard_check(vk_right) {
if !place_meeting(x+spd,y,Wall) {x+=spd}
}
if keyboard_check(vk_left) {
if !place_meeting(x-spd,y,Wall) {x-=spd}
}
if keyboard_check(vk_space) {
Ball.fixed=false
}
if keyboard_check(ord("R")) {
room_restart()
}
В самый низ добавил код для перезапуска комнаты.
Функция room_restart(), как раз перезапускает комнату. В GMS2 есть еще функция game_restart(), которая перезапускает вообще всю игру. В нашем случае пока можно использовать как первую так и вторую, так как в игре пока всего один уровень.
Ну а так же для этого мы писали управление специальными клавишами, типо стрелки или пробел. А теперь ввели проверку нажатия клавиши с буквой с клавиатуры. При этом код немного меняется, как вы видите из примера. Применяется функция ord(" "), где между ковычками уже ставите букву с клавиатуры. На ней не буду заострять внимание. Просто знайте, что для букв используется такой код и все.
Можете запустить игру и по запускать мяч пробелом, потом перезапускайте уровень клавишей R и снова запускайте мяч. Попробуйте так несколько раз, чтобы убедиться, что мяч и правда летит то влево, то вправо.
Как вы заметили, мяч пролетает сквозь стены и кирпичи. Давайте теперь займемся этим вопросом.
Учим мяч сталкиваться со стенами
На самом деле у вас для этого тоже уже есть все необходимые знания. Мы уже учились битой обрабатывать коллизии, т.е. столкновения со стеной. Давайте просто перенесем код в наш мяч. Да, он будет чуть по сложнее, так как нужно учитывать направление мяча. В общем, код в событии шага мяча в итоге получится следующим:
if fixed=true {x = Bat.x}
if fixed=false {
if dir=0 {
if !place_meeting(x-2,y-2,Wall) {x-=2 y-=2}
}
if dir=1 {
if !place_meeting(x+2,y-2,Wall) {x+=2 y-=2}
}
if dir=2 {
if !place_meeting(x-2,y+2,Wall) {x-=2 y+=2}
}
if dir=3 {
if !place_meeting(x+2,y+2,Wall) {x+=2 y+=2}
}
}
Видите, какой объемный код у вас уже получается. Но это только начало, скоро вы легко будете писать сотни строк кода в объектах.
Тут мы просто добавили проверку для каждого направления наличия стены перед мячом. И если стены нет, то мяч полетит дальше, если нет, то координаты не сменятся, т.е. мяч просто остановится.
Хотел в этот же урок прописать столкновение с кирпичами и прописать отскакивание мяча от стен с битой, но урок и так уже вышел слишком объемным. По этому думаю прийдется перенести все на следующий.
Спасибо, что дочитали статью до конца! Ставьте лайки, делитесь, задавайте вопросы, сообщайте об ошибках. Статьи пишутся в основном ночью, так как днем времени на это нет, по этому могут присутствовать опечатки. Всем еще раз спасибо! Увидимся в следующей статье.
Кстати, сейчас в Steam идет скидка 25% на десктопную версию GMS2. Его цена сейчас не более 1200 руб.