Геймдев за 7 дней. 4 День

05.05.2020
Posted in blog-article
05.05.2020 admin

Геймдев за 7 дней. 4 День

Для тех, кто хорошо отдохнул и полон сил на пути к саморазвитию — 4 день курса Геймдева!

Механика

Сегодня мы углубимся в программирование на C #.

Переменные C #

Ключевая часть программирования — использовать память компьютера, помещая в него что-то и вытаскивая это нечто. В C # мы используем для этого переменные. Переменные — это контейнеры, которые могут содержать информацию определенного типа. Например, переменная одного типа может содержать изображения, а переменная другого типа — аудио.

Переменные бывают множества типов. Некоторые относятся только к Unity, а некоторые — к языку программирования C # . Приведу несколько примеров переменных.

float jumpForce

• Rigidbody2D rb

• Vector2 speed

Первая — это переменная jumpForce, которая может содержать число с плавающей точкой (например, 77.5454).

Вторая — это переменная с именем rb, которая может содержать Rigidbody2D — компонент Unity, который мы использовали для нашего персонажа, чтобы заставить его подчиняться гравитации.

Третья — это переменная, называемая скоростью (speed). Она может содержать вектор из двух элементов. В нашем случае это x и y для горизонтальной и вертикальной скоростей. Очень часто переменные, такие как скорость, могут иметь множество различных элементов.

Подобные элементы часто называют членами и ими могут быть также другие переменные или методы. Например, скорость вы можете рассматривать как совокупность двух других переменных: float x и float y.

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

jumpForce = 10f

Помните, что вы можете использовать только данные того же типа, что и переменная. В приведенном выше примере f — это уникальный способ сообщить компьютеру, что число является значением с плавающей запятой.

Теперь значение 10 находится внутри переменной, и вы можете использовать его в своих расчетах. К примеру, jumpForce + jumpForce даст нам 20, а jumpForce * 5 равен 50.

Прыжки

Лучший способ обучения — практика. Для начала откроем JumpScript и определеним переменные, которые я ввел ранее. Вы можете поместить их в верхнюю часть блока класса следующим образом.

public class JumpScript : MonoBehaviour {

float jumpForce;

    Rigidbody2D rb;

    Vector2 velocity;

.

Прыжок в реальном мире — это действие, при котором скорость объекта выталкивает его вверх. К счастью, компонент Rigidbody2D игрока уже обладает скоростью, которой мы можем манипулировать. В настоящее время на скорость влияет только сила тяжести, постоянно тянущая объект вниз. Мы хотим, чтобы касание экрана активировало другую скорость.

План такой. Определим абстрактное значение силы прыжка, например, как 10. Затем создадим собственную переменную скорости и изменим ее член y так, чтобы он был равен значению силы прыжка. Теперь возьмем компонент Rigidbody2D игрока и изменим его элемент скорости, приравняв его к тому, который мы только что создали.

Конечно, гравитация будет постоянно воздействовать на объект. Но каждый раз, когда игрок будет касаться экрана, новая скорость снова поднимает объект вверх.

Теперь нам нужно инициализировать переменные с некоторыми значениями. Это то, что нам потребуется сделать только один раз, поэтому мы можем воспользоваться методом Start. Фактически, комментарий (строка, начинающаяся с //) над ним уже говорит: «Используйте это для инициализации». Кто мы такие, чтобы спорить программой, верно?

Чтобы всё получилось, нам необходимо задать значение каждой из трех наших переменных.

// Use this for initialization

void Start () {

        jumpForce = 10f;

        rb = gameObject.GetComponent<Rigidbody2D>();

        velocity = rb.velocity;

    }

Про первую строку с jumpForce я вам уже рассказал, но сейчас нам встретилась и вторая строка. Я не хочу, чтобы вы слишком увлекались синтаксисом в самом начале знакомства с созданием игр. Эти вещи выходят за рамки нашей инструкции. Признайте, что вы способны использовать инструменты, даже если не совсем понимаете, как они работают.

Суть в том, что мы обращаемся к gameObject, в котором есть этот скрипт, чтобы получить компонент Rigidbody2D этого объекта. Затем мы помещаем нужный компонент в переменную rb, которую мы определили ранее.

Вы, вероятно, можете определить, какой будет третья строка. Если вы ещё не догадались, то она уже перед вами. Сейчас, когда компонент Rigidbody2D находится в переменной rb, мы можем получить доступ к его члену скорости. Итак, поместите его в переменную speed, которую мы также определили ранее.

Здорово. Теперь у нас есть куча переменных, горячих и загруженных. Осталось только сделать с ними что-нибудь осмысленное.

Перейдем к методу JumpClick. Он выполняется, когда игрок касается экрана, поэтому начать с него – логичнее всего.

Мы настроили все так аккуратно, что нам нужно всего две строчки, чтобы заставить прыгать персонажа. Во-первых, измените y-член нашей переменной скорости — он должен быть равен значению jumpForce. Во-вторых, сделайте скорость Rigidbody2D равной нашей переменной скорости.

public void JumpClick () {

velocity.y = jumpForce;

rb.velocity = velocity;

}

Примечание. Технически вы можете немного сократить количество строк, но я хотел, чтобы каждый из наших шагов обладал достаточно подробным объяснением.

Теперь вы можете вернуться в Unity и запустить игру. Нажатие на экран должно привести к тому, что персонаж игрока будет ускоренно подниматься вверх.

Прокрутка уровня

Прокрутка уровня осуществляется с помощью двух последовательных действий.

1. Создание препятствий за пределами экрана.

2. Перемещение их справа налево.

Персонаж игрока никогда не двигается горизонтально. Мы просто создаем иллюзию движения, перемещая на экране все остальное.

Также нам необходимо между верхней и нижней частью каждого препятствия создать невидимую зону для получения очков. Таким образом, когда персонаж игрока попадет в зону очков, его счёт увеличится на единицу.

Создайте пустой объект. Для этого перейдите в меню GameObject и выберите Create Empty. Затем возьмите два прямоугольника, уже находящихся в сцене, и поместите их в пустой GameObject. Вы можете это сделать с помощью перетаскивания прямоугольников на вкладку «Иерархия». Мы получим аккуратную небольшую группу объектов.

Переименуйте в Inspector меню GameObject на HoopObstacle. Это упростит ориентирование в файле при дальнейшей работе.

Отцентруйте прямоугольники. Для этого установите обе их позиции X на 0, а позиции Y на что-то вроде 6 для верхней части и -6 для нижней. Чем ближе они окажутся друг к другу, тем сложнее будет игра.

Чтобы препятствия двигались справа налево, нам нужен дополнительный сценарий. Выберите препятствие HoopObstacle, расположенное в сцене, и переместите его вправо до тех пор, пока оно не исчезнет с экрана. Положение х должно выйти около 12.

Теперь нажмите в Инспекторе кнопку «Добавить компонент» и введите «новый». В результате Unity предложит вам новый скрипт. Нажмите ввод, введите имя для изображения, например, «Motion» («Движение»), и нажмите ввод еще раз. После этого компонент будет добавлен. Теперь дважды щелкните серым текстовым полем «Изображение» с надписью «Движение». У вас откроется скрипт в Visual Studio.

На этот раз мы используем внутри скрипта метод Update. Тем более, что комментарий (строка, начинающаяся с //), указывает нам на цель метода, полностью соответствующую нашим потребностям. Метод Update выполняется несколько раз в секунду. Таким образом, все, что мы поместим внутрь, будет повторяться вновь и вновь. Это именно то, что нам нужно. И это должно переместить препятствия в невидимую зону справа.

void Update () {

gameObject.transform.position += new Vector3(-0.1f, 0, 0);

}

Эта линия выполняет несколько задач.

1. Она присваивает себе позицию HoopObstacle, получая доступ к компоненту преобразования этого игрового объекта.

2. Поскольку я знаю, что позиция — это Vector3 (для значений x, y и z), я могу создать новый Vector3 со слегка отрицательным значением x.

3. Новый Vector3 будет добавлен к текущей позиции HoopObstacle с помощью оператора + =.

Поскольку обновление вызывается один раз за кадр, позиция x в HoopObstacle уменьшается снова и снова. Если вы запустите игру прямо сейчас, то заметите, что препятствие, которое вы разместили за кадром, медленно движется к персонажу игрока.

Больше препятствий

Я не знаю, как вы, но я хочу, чтобы действие продолжалось. Это означает, что нам нужно больше препятствий!

Создадим еще один пустой объект. Когда вы это сделаете, переименуйте его в GameMode. Это будет объект менеджера, который обрабатывает всё, что происходит за кадром.

Создайте для объекта GameMode новый скрипт. Назовите его «ObstacleSpawner». И перейдём к определению и инициализации нескольких переменных.

public class ObstacleSpawner : MonoBehaviour {

    float nextActionTime = 3.0f;

    float period = 3.0f;

    GameObject obstacle;

    Vector2 startPos;

// Use this for initialization

    void Start () {

obstacle = GameObject.Find(«HoopObstacle»);

   

startPos.x = 12;

}

.

Как видите, некоторые переменные могут быть определены и инициализированы в одной строке. Это сделает записи более компактными.

Мы не можем создавать препятствия в каждом кадре – так мы полностью зальём ими экран и не оставим места для самой игры. Поэтому мы создадим систему, которая будет порождать препятствие каждые три секунды. В этом нам помогут переменные nextActionTime и period.

В методе Start, чтобы получить созданный нами HoopObstacle, используем GameObject.Find. Объясню ещё раз: нам нужно указать коду пойти и найти GameObject с именем HoopObstacle внутри Unity, потому что в противном случае код не поймёт, что от него требуем.

C # — это отдельная экосистема, в которой человек не может перемещаться самостоятельно. За него это делают маленькие помощники. Например, GameObject.Find отвечает за поиск в игровом движке всего, что нам может понадобиться. Как только объект HoopObstacle найден, мы помещаем его в переменную GameObject, называемую Obstacle.

Также мы устанавливаем начальную позицию для препятствий равную 12 по оси x, поскольку знаем, что она находится за кадром.

Начинается самое интересное.

Внутри метода Update используем оператор if

void Update() {

        if(Time.time > nextActionTime

{

Instantiate(obstacle, startPos, Quaternion.identity

nextActionTime += period

}

}

Код внутри блока оператора if выполняется только в том случае, если выполняется условие в скобках. В противном случае система «перепрыгнет» через код данного оператора.

Здесь указано условие Time.time> nextActionTime. Мы знаем, что такое nextActionTime 3.0, но что такое Time.time? Time.time – это время в секундах, прошедшее с начала игры. Условие гласит, что Time.time должно быть больше, чем nextActionTime 3,0.

Если мы войдем в блок оператора if, то увидим, что мы просто создаем (или порождаем) объект. Вы сообщаете команде Instantiate, какой именно объект хотите создать, в каком месте вы хотите, чтобы он был создан, и в каком направлении ему предстоит перемещение.

Следующая строка — ключ к нашему нерестовому заговору. Мы добавляем точку в nextActionTime, что превращает его в 6.0. Это означает, что мы не пойдем внутрь блока if до тех пор, пока Time.time не станет больше 6.0. Когда это произойдет, мы создадим новое препятствие, и точка будет добавлена ​​в nextActionTime, что придаст ему новое значение 9.0, а в следующий раз 12.0 и так далее.

Примечание. Мы не хотим создавать препятствие в самом начале, потому что у нас на сцене уже есть одно препятствие.

Запустите игру прямо сейчас. Вы должны обнаружить, что препятствия появляются в заданном ритме, но ничего другого пока не происходит.

Столкновения

Добавим в игру объекты столкновения. Как вы понимаете, этот элемент призван заставить объекты сталкиваться друг с другом.

Нам потребуются коллайдеры для игрока и два прямоугольника в HoopObstacle. Выберите объект игрока и добавьте для него компонент под названием Circle Collider 2D. Затем отдельно добавьте Box Collider 2D для каждого прямоугольника в объекте HoopObstacle.

Если вы сейчас протестируете игру, то обнаружите, что игрок научился сталкиваться с препятствиями. К слову, было бы интересно настроить Flappy Bird таким образом, чтобы проигрыш не происходил сразу после первого столкновения с препятствием. Возможно, мы будем придерживаться классики. Или нет. Решим этот момент завтра.

Вы потрудились на славу! Я знаю, что сегодня мы работали долго. Но нам это удалось!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Contact

Давайте работать вместе!

Пишите нам и найдем точки соприкосновения, может станем партнерами, а может поможем вам зайти в нашу чудесную нишу

Вы разработчик?

Пишите! Нам постоянно нужны новые кадры, либо можем помочь в продвижении вашего приложения

Новичок?

Поможем быстро войти в нишу, не тратя годы на понимание

Давно в нише?

Рады будем пообщаться как на темы whitehat, так и blackhat тематики ^_^ + всегда есть что обсудить по поводу рекламных сетей

ПИШИ В TELEGRAM!

Contact