Перейти к содержимому

Как создать игру на годот

  • автор:

#2 – Создание 2D платформера в Godot

#2 – Создание 2D платформера в Godot

В ходе большой лекции мы с вами разработаем полноценные 2Д проект. Мы создадим игру платформер. В игре будет главный игрок, платформы и механика для прыжков и передвижения.

Видеоурок

Полезные ссылки:

  • Официальный сайт Godot ;
  • Ссылка на скачивание готового проекта из видео.

Разработка 2Д игры на Godot

Для игры вам потребуется всего пару картинок. Вы можете их скачать ниже:

Скачивание и установка

Скачивание и установка движка – проста и удобна. Вам необходимо зайти на официальный сайт , перейти на вкладку «Download» и далее скачать «Standart Verison» под вашу операционную систему. После скачивания нажмите на скачанный файл и далее вы сможете мгновенно очутиться на главном экране движка.

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

Уроки Godot Engine

#1 – Введение в движок Godot. Почему про него все говорят?

#1 – Введение в движок Godot. Почему про него все говорят?

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

Видеоурок

Полезные ссылки:

  • Официальный сайт Godot ;
  • Статья на нашем сайте .

Информация про Godot Engine

Игровой движок Godot появился относительно недавно. Его первый выход в свет был в феврале 2014 года. На момент релиза движок обладал минимальным необходимым набором функционала без перегруженной системы вкладок и настроек.

За эту простоту он быстро стал любимчиком многих молодых разработчиков. На сегодняшний день Godot Engine постепенно перерастает из формата любительского движка в формат полноценного движка для разработки как 2Д, так и 3Д проектов.

Сам движок написан при использовании языков Си и C++ . Курсы по этим языкам вы также можете найти на нашем сайте.

Стоимость использования

Godot Engine является полностью бесплатным игровым движком. Можно сразу сказать, что и Unity и Unreal тоже предлагают бесплатно свои движки, но есть существенная разница. Они оба предлагают бесплатно движки до определённого момента. В Unity цена стартует от 100 долларов за версию Pro и вам придется платить эту цену, если ваши игры приносят более 100 тысяч долларов в год. В Unreal нужно платить определенный процент от прибыли если вы привесили сумму дохода в размере 1 млн долларов.

Простое написание кода

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

Godot – это один из простейших игровых движков в плане написания кода. И если сравнивать с GameMaker, то нужно выделить большую разницу между ними. GameMaker позволяет создать лишь 2Д проекты, а Godot может позволит вам создать как 2D, так и 3D проект.

План курса

В ходе курса мы с вами с нуля разработаем несколько полноценных игр на основе игрового движка Godot Engine. Мы будем создавать как 2Д проекты, так и 3Д проекты. К концу курса «Уроки Godot Engine для новичков с нуля» у вас будут достаточно хорошие навыки в создании проектов на основе данного движка.

Дополнительный курс

На нашем сайте также есть углубленный курс по изучению игрового движка Unity . В ходе огромной программы вы изучите не только движок Unity, но также научитесь писать консольные и интерфейсные программы на языке C#. Также вы изучите сам движок Unity, включая создание 2D и 3D игр, а также игр и приложений с дополненной реальностью.

Задание к уроку

Ответьте на несколько вопросов:

  1. Какая стоимость использования Godot?
  2. Какой язык используется в движке?
  3. Возможна ли разработка 3Д проектов с мультиплеером?

Первая игра на Godot

В этой статье напишем простую казуальную игру под Android и опубликуем ее в RuStore. Эта игра нужна как пример. Я напишу обертки для RuStore SDK(подписки, пуши, отзывы), myTracker и myTarget. И в будущем постараюсь все их использовать в этой игре. Добавлю рекламу и подписки, попробую закупить трафик. Посмотрим, сколько можно заработать на игре в RuStore.

Игру будем писать на Godot. Это прекрасный движок для игр. Особенно, если вы начинающий разработчик. У него очень много плюсов: легковесность, простой скриптовый язык, достаточно подробная документация, бесплатность. И, самое главное, крутая идея построения всей игры из узлов. Как по мне, движок значительно проще Unity.

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

Сейчас наиболее популярны 3я и 4я версия движка. В 4 добавлено очень много оптимизаций и достаточно сильно переработан API движка. Все новые проекты имеет смысл создавать на 4ой версии.

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

Подготовка

Запускаем редактор и начинаем с настроек проекта. В первую очередь указываю размер окна 640×180 — подойдет для дебага.

Сразу можно настроить цвет фона. Это должно быть что-то темное, почти как космос. Прекрасно подойдет цвет #0f0f16

Готовим модели

Тут необходимо небольшое отступление про ключевые концепции Godot. Любая игра на Godot представляет собой дерево сцен. А сцена — это дерево узлов(node). Все строится из узлов и это строительные кирпичики вашей игры. Есть очень много разных видов узлов под разные задачи.

Если вы собираете из узлов, например, персонажа — то это уже будет сцена. Такую сцену можно сохранить в отдельный файл и потом использовать ее как еще один узел.

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

Начнем с главной сцены, которую назовем game.tscn . Пока это просто пустая сцена, в дальнейшем добавим в нее героя и простой UI интерфейс.

Создаем новую сцену для героя. Добавляем в сцену родительский узел CharacterBody2D — это специальный узел для физических объектов, которые должны передвигаться через скрипт. Дочерним узлом добавим Sprite2D и укажем в этом элементе цвет для героя: #F2F3F4

Еще один дочерний узел — это CollisionShape2D . Он нужен для работы коллизий между врагами и героем. В настройках узла в параметре Shape нужно выбрать RectangleShape2D , потом настроить размеры зоны для коллизий.

Все коллизии будут происходить на 1 слое, поэтому все узлы должны быть на 1 слое.

Сохраняем героя отдельной сценой hero.tscn и потом добавляем героя на главную сцену игры как новый узел.

Теперь делаем все тоже самое для врагов. Только цвет для врага выбираю #F200A5 и сохраняем сцену как enemy.tscn .

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

Пишем скрипты

У вас есть возможность писать скрипты для игры на GDScript или C#. Кроме того, с версии 4.0 появилась улучшенная поддержка C++ через механизм GDExtension, который позволяет писать игры на C++ без рекомпиляции самого движка. А если вы совсем уж любитель экзотики и изотерики, то можно использовать биндинги для Rust от сообщества.

В этом простом туториале будем использовать стандартный GDScript. Для него больше всего документации и примеров. Это самый популярный язык разработки среди Godot разработчиков.

В Godot все скрипты прикрепляются узлу. Для создания нового скрипта или добавления к узлу уже существующего скрипта, нужно выбрать узел в дереве и нажать на иконку добавления скрипта:

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

 1extends CharacterBody2D 2 3 4const SPEED = 300.0 5const JUMP_VELOCITY = -400.0 6 7# Get the gravity from the project settings to be synced with RigidBody nodes. 8var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") 9 10 11func _physics_process(delta): 12 # Add the gravity. 13 if not is_on_floor(): 14 velocity.y += gravity * delta 15 16 # Handle Jump. 17 if Input.is_action_just_pressed("ui_accept") and is_on_floor(): 18 velocity.y = JUMP_VELOCITY 19 20 # Get the input direction and handle the movement/deceleration. 21 # As good practice, you should replace UI actions with custom gameplay actions. 22 var direction = Input.get_axis("ui_left", "ui_right") 23 if direction: 24 velocity.x = direction * SPEED 25 else: 26 velocity.x = move_toward(velocity.x, 0, SPEED) 27 28 move_and_slide() 

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

Перемещение героя

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

 1extends CharacterBody2D 2 3 4const SPEED = 300.0 5 6var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") 7var direction = 1 8 9func _physics_process(delta): 10 if Input.is_action_just_pressed("ui_accept"): 11 direction = direction * -1 12 13 if get_global_transform_with_canvas().origin.x  0: 14 direction = 1 15 16 if get_global_transform_with_canvas().origin.x >= get_window().size.x: 17 direction = -1 18 19 velocity.x = direction * SPEED 20 21 move_and_slide() 

Логика перемещения реализована в методе _physics_process(delta) . В Godot есть два метода, которые вызываются автоматически для обновления состояния перед отрисовкой кадров: _process и _physics_process . Первый метод блокирующий и запускается так часто, насколько это возможно. Второй метод работает с фиксированной частотой, по умолчанию 60 раз в секунду. _physics_process обеспечивает плавную обработку физики, поэтому все задачи, связанные с обработкой любой физики, нужно производить именно в этом методе.

Готово, наш герой двигается от одного края экрана к другому. За направление отвечает переменная direction . Чтобы изменить направление, мы получаем текущее положение героя по оси x с помощью get_global_transform_with_canvas().origin.x . Если это значение меньше 0, то пора изменить направление героя чтобы он начал двигаться от левого края экрана к правому. А если это значение больше чем размер окна, то отправляем героя в путешествие от правого края окна к левому.

Падающие враги

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

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

1extends Node2D 2 3# Called when the node enters the scene tree for the first time. 4func _ready(): 5 var enemy = preload("res://scenes/enemy.tscn").instantiate() 6 enemy.add_to_group("Enemy") 7 enemy.position = Vector2(50, 50) 8 add_child(enemy) 

Метод _ready() гарантирует, что сцена полностью загружена и все узлы в сцене уже доступны. Если вам нужно разово выполнить какой-нибудь код, то это отличное место для такой логики.

Каждый враг добавляется в группу Enemy . Это поможет нам правильно удалить всех врагов после столкновения.

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

 1extends Node2D 2 3var max = 3.0 4var timeout = max 5 6# Called when the node enters the scene tree for the first time. 7func _ready(): 8 randomize() 9 10# Called every frame. 'delta' is the elapsed time since the previous frame. 11func _process(delta): 12 timeout -= delta 13 if timeout  0: 14 timeout = max 15 spawn() 16 17 18func spawn(): 19 var enemy = preload("res://scenes/enemy.tscn").instantiate() 20 enemy.add_to_group("Enemy") 21 var pos = Vector2(randf_range(3, get_window().size.x/ProjectSettings.get_setting("display/window/stretch/scale") - 3), -5) 22 enemy.position = pos 23 add_child(enemy) 

В метод _process передается параметр delta . Это разница по времени между отрисовкой двух кадров. Его нужно использовать для обратного отсчета до создания следующего врага.

В методе _ready вызывается метод randomize() . Он нужен для подготовки генератора псевдослучайных чисел, который будет использоваться для указания позиции нового врага на главной сцене: var pos = Vector2(randf_range(3, get_window().size.x/ProjectSettings.get_setting(«display/window/stretch/scale») — 3), -5) . Эта строка кода может показаться страшной, но тут нет ничего сложного. Разберем все по частям:

ProjectSettings.get_setting(«display/window/stretch/scale») — это получение настроек проекта. На девайсе игра может выглядеть не так как ожидалось, все размеры могут оказаться слишком мелкими. Тогда нужно или изменить размер каждого элемента, или заскейлить все сразу через настройки проекта. Но в случае со скейлом, мы не сможем правильно рассчитать размеры окна, если не будем делить его на значения скейла.

get_window().size.x — значение ширины окна, в котором запущена игра

randf_range(a, b) — функция, которая генерирует случайное значение в диапазоне от a до b

var pos = Vector2(x, y) — создание двухмерного вектора со значениями x и y . Такой вектор используется для задания позиции узла на сцене.

Мы задаем позицию врагу на 5 пикселей выше верхнего края окна по оси y и случайное положение на оси x с отступами по 3 пикселя с левого и правого края окна.

Важно отметить, что в Godot, как и в большинстве современных движков, позиционирование задается от верхнего левого края окна.

В функции spawn мы инстанционируем врага preload(«res://scenes/enemy.tscn»).instantiate() . Метод preload загружает сцену врага, а instantiate создает узел. Метод add_child(enemy) добавляет новый узел в главную сцену.

Коллизии

Герой и враги находятся на одном слое с номером 1 и могут сталкиваться друг с другом. Это максимально простая логика. Можно разнести врагов и героя на отдельные слои — тогда враги не будут сталкиваться с врагами. Но в такой простой игре это лишнее и может быть задачей на будущее.

Для отслеживания коллизии будем перемещать героя и врага с помощью move_and_collide . Посмотрим как это сделано в скрипте Hero.gd :

 1signal collided 2var active = true 3 4func _physics_process(delta): 5 if !active: 6 return 7 8 # . 9 10 var collision = move_and_collide(velocity * delta) 11 if collision: 12 collided.emit() 

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

Еще одна мощная штука в Godot — сигналы. По своей сути, сигналы это сообщения, которые производит узел при определенных событиях, например — клик по кнопке. Другие узлы могут перехватывать этот сигнал и вызывать нужную функцию. Кроме перехвата стандартных сигналов, вы сами можете создавать кастомные сигналы и обрабатывать их как вам нужно. Такой подход дает невероятную гибкость разработки и позволяет разделять код на независимые части.

Посмотрим как мы используем сигналы в коде. Для начала создается signal collided — это и есть наш сигнал. В момент коллизии вызывается метод collided.emit() который “бросает” сигнал. Чуть позже напишем код, который будет перехватывать этот сигнал.

Обратите внимание на переменную active в коде выше. Она используется для остановки движения героя героя. Если она будет установлена в false, то вся обработка в функции _physics_process будет пропущена

Для врагов делаем все очень похожее как и у героя, но в скрипте Enemy.gd :

1signal collided 2 3 4func _physics_process(delta): 5 velocity.y = SPEED * delta 6 7 var collision = move_and_collide(velocity * delta) 8 if collision: 9 collided.emit() 

Отлавливать сигналы о коллизиях будем в скрипте игры Game.gd . Для этого нужно подключится к сигналу героя и к сигналам врагов во время их создания с помощью вызова метода collided.connect(_on_collided)

 1var hero 2var play = true 3 4 5func _ready(): 6 randomize() 7 hero = $Hero 8 hero.collided.connect(_on_collided) 9 10func _process(delta): 11 if !play: 12 return 13 14 timeout -= delta 15 if timeout  0: 16 timeout = max 17 spawn() 18 19func spawn(): 20 var enemy = preload("res://scenes/enemy.tscn").instantiate() 21 enemy.add_to_group("Enemy") 22 var pos = Vector2(randf_range(3, get_window().size.x/10 - 3), -5) 23 enemy.position = pos 24 enemy.collided.connect(_on_collided) 25 add_child(enemy) 

В этом коде переменная play работает аналогично переменной active в скрипте героя. Только в этом случае перестает работать логика в методе _process , и новые враги перестают создаваться.

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

1func _on_collided(): 2 hero.active = false 3 play = false 4 for ch in get_children(): 5 if ch.is_in_group("Enemy"): 6 remove_child(ch) 

Важно отметить, что при таком подходе нужно получать коллизии и от врагов, и от героя. При коллизии нам нужно остановить создание врагов. Для этого устанавливаем переменную play = false . Для героя выставляем hero.active = false — это остановит движение героя.

Интерфейс

Сейчас в игре при столкновении героя с врагом — все останавливается. В целом, это и есть конец игры. Но неплохо было бы дать возможность перезапуска. Для этого нам нужно отобразить простейшее меню с одной кнопкой рестарта.

Начнем с добавления элементов интерфейса

  • CanvasLayer — отвечает за весь слой, на котором будет отображаться интерфейс. Я назову этот узел UserInterface .
  • CenterContainer — специальный контейнер, который будет центрировать все элементы нашего интерфейса
  • Button — простая кнопка, при клике на которую игра запускается по новой. Узел будет называться ButtonRestart .

Настроить параметры кнопки можно через отдельную тему:

Настройка тем в Godot заслуживает большего внимания, но не в этой статье. Пока достаточно изменить размер шрифта для кнопок. Для этого выберите кнопку на панели с примерами элементов и в параметрах поменяйте размер шрифта.

По умолчанию кнопка должна быть скрыта и отображаться только при завершении игры. Для этого узел необходимо скрыть в дереве сцены. Это можно сделать руками, но я стараюсь все по-максимуму переносить все в коде самой игры. Поэтому, скроем кнопку в методе _ready()

1var restart: Button 2 3func _ready(): 4 # . 5 6 restart = $UserInterface/CenterContainer/ButtonRestart 7 restart.hide() 8 restart.pressed.connect(_on_restart_pressed) 

А заодно добавлю обработку сигнала нажатия кнопки в отдельном методе. По нажатию на кнопку нужно перезапускать игру. Для этого перезагрузим всю нашу сцену с помощью метода reload_current_scene() .

1func _on_restart_pressed(): 2 get_tree().reload_current_scene() 

Кнопка должна отображаться в момент завершения игры. Для этого есть подходящее место в функции _on_collided()

1func _on_collided(): 2 restart.show() 3 4 # . 

Подсчет очков

В игру уже можно играть. Но ей не хватает хоть какого ни будь смысла. Будем считать очки за каждого врага, которого удалось избежать. Для этого необходимо понимать, когда враг ушел за край экрана. Для этого в скрипте Enemy в методе _process будем проверять позицию врага и если он оказался ниже края окна, то удалять врага queue_free() и бросать сигнал skip.emit() .

1signal skip 2 3func _process(delta): 4 if get_global_transform_with_canvas().origin.y > (get_window().size.y + 10): 5 skip.emit() 6 queue_free() 

И теперь нужно подключится к сигналу skip в скрипте Game.gd при создании врага и добавить обработчик этого сигнала _on_skip()

1func spawn(): 2 # . 3 enemy.skip.connect(_on_skip) 4 5 6func _on_skip(): 7 points += 1 8 print(points) 

Осталось научится отображать заработанные очки в интерфейсе игры. Для этого добавляем узел интерфейса Label , который назовем Points .

И будем записывать обновление счетчика в этот Label

 1var points: Label 2var score = 0 3 4func _ready(): 5 # . 6 points = $UserInterface/MarginContainer/Points 7 8func _on_skip(): 9 score += 1 10 points.text = "%d" % score 

Нарастающая сложность

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

 1var score = 0 2var speed = 100 3 4func spawn(): 5 var enemy: Enemy = preload("res://scenes/enemy.tscn").instantiate() 6 enemy.speed = speed 7 # . 8 9 10func _on_skip(): 11 score += 1 12 points.text = "%d" % score 13 14 max -= score * 0.01 15 if max  0.5: 16 max = 0.5 17 18 speed += score / 3 

Тут max — это время между созданием врагов. В логике, описанной выше, это время будет уменьшатся. Можно сразу подумать над улучшением алгоритма — время может быть не фиксированным, его можно рандомно выбирать из промежутка. В таком случае, добавится элемент непредсказуемости.

Скорость возрастает с каждым новым заработанным очком. Сейчас скорость добавляется как speed += score / 3 . Эту функцию можно менять, чтобы подобрать самый подходящий ритм игры и плавно наращивать сложность.

Чтобы красиво

Осталось добавить несколько штрихов и игра будет готова. Добавим рандомное вращение врагам и эффект столкновения. Начнем с вращения. Для этого в скрипте Enemy.gd в методе _physics_process() начнем вращать узел.

1var rotate = 1 2var angle = 1 3 4 5func _physics_process(delta): 6 velocity.y = speed * delta * 100 7 8 rotation = angle * delta 9 angle += rotate 
  • angle — это текущее значение угла, на который нужно повернуть узел.
  • rotate — это дефолтное значение приращения угла. Его нужно будет задать в скрипте Game.gd
1func spawn(): 2 # . 3 enemy.rotate = randf_range(1, 10)N 

Осталось добавить красивый эффект при столкновении. Для этого будем использовать частицы. Пример настройки частиц для нашего героя ниже:

Тут важно указать, что это должно быть одноразовое “on shot” воспроизведение, которое мы будем включать сами во время столкновения. В скрипте Hero.gd добавляем работу с частицами.

1var particles: CPUParticles2D 2 3func _ready(): 4 particles = $Boom 5 6func boom(): 7 particles.restart() 

А в скрипте Game.gd вызываем метод boom() для воспроизведения анимации частиц

1func _on_collided(): 2 # . 3 hero.boom() 

Отлично! Теперь у нас все готово, и можно собирать игру под Android.

Сборка для Android

Первым делом нужно настроить шаблон для экспорта проекта. Этот шаблон будет использоваться для создания полноценного Android приложения. Это делается через меню Project

Шаблон нужно будет скачать. Это займет некоторое время.

После скачивания шаблона для Android — применяем его

После применения шаблона, в проекте появится папка android со всеми необходимыми файлами для настройки Android проекта. Это и есть Android проект, который можно открыть Android Studio и внести какие угодно изменения.

Переходим на экран экспорта через меню Project

И теперь можем экспортировать проект для Android.

Кроме того, теперь можно запускать и отлаживать игру на эмуляторе.

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

Ориентацию починить просто. Для этого переходим в настройки проекта Project -> Project Settings -> Display -> Window и выставляем ориентацию Portrait

Поправить логику движения нашего героя тоже можно через настройки проекта. Для этого на экране Project Settings переходим на вкладку Input Map, находим экшен ui_accept и добавляем событие клика для этого экшена.

И мне не нравится как выглядит игра на эмуляторе. Необходимо увеличить размер героя и врагов, поправить позиционирование героя. Это можно сделать, увеличивая в редакторе каждый узел. Но это долго, поэтому проще изменить значение scale на 2 в настройках проекта Project -> Project Settings -> Display -> Window -> Stretch -> Scale

Вот так выглядит итоговый вариант игры, запущенный на эмуляторе.

Теперь наша игра полностью готова для публикации в RuStore

Публикуем игру в RuStore

Есть неплохая документация, в которой можно найти ответы на многие вопросы. Но публикация игр и приложений в RuStore действительно очень простая.

Для публикации необходимо подписать нашу сборку. Для этого генерируем подпись через стандартные инструменты Android. Переходим в папку ./android и в ней генерируем подпись, которая будет использоваться для публикации.

1keytool -keyalg RSA \ 2 -genkeypair \ 3 -alias proton \ 4 -keypass proton \ 5 -keystore proton.keystore \ 6 -storepass proton 

Теперь указываем подпись в настройках экспорта в секции Keystore. Я использую одну подпись для дебага и релиза. Так делать не хорошо, но кто меня остановит.

Нужно добавить кастомную иконку. Стандартная с логотипом Godot хороша, но хочется чего-то индивидуального. Для создания иконки воспользуемся приложением от Яндекс shedevrum.ai — нейронка, которая по запросу может генерировать картинку.

Ресайзим картинку под два размера: 192х192 для главной иконки и 432х432 для адаптивной. Указываем эти иконки в настройках экспорта. На самом деле, для Adaptive Background лучше использовать отдельную иконку, но тут немного срежем углы и вернемся к настройке иконок, когда понадобится.

Все готово для экспорта apk. На том же экране с настройками убираем галку Export With Debug, нажимаем кнопку Export Project и сохраняем готовый apk файл

Проверяем, что готовая игра работает нормально, устанавливаем ее через adb:

1adb install proton.apk 

Запускаем и убеждаемся, что все окей.

Отлично! Настало время загрузки игры в RuStore. Создаем новое приложение в консоли разработчика, указываем название и выбираем тип “бесплатное”.

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

Для каталога нам нужна еще одна иконка размером 512х512. Ресайзим нашу сгенерированную иконку и загружаем ее. Добавляем краткое и расширенное описание.

Осталось подготовить и загрузить скриншоты для игры. Я делаю скрины с эмулятора и загружаю их в консоль как есть.

Все загружено и вся необходимая информация добавлена. Игра готова. Отправляем ее на проверку. Модерация, как правило, проходит очень быстро. Курим, смотрим пару видосов на ютубе, и игра уже опубликована.

Что дальше

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

Полный курс по созданию мобильных игр на Godot 4

Раскрой свой потенциал с помощью авторского курса по разработке мобильных игр с использованием бесплатного движка Godot Engine 4. В отличие от обычных уроков с потоковых сервисов-обучалок, этот курс представляет собой аутентичный, тщательно продуманный учебный комплекс, который разрабатывался автором 1,5 года.

Начальный уровень
2-3 часа в неделю
Начать просмотр
242 учащихся

Чему вы научитесь

  • Создавать игры на Godot 4
  • Программировать на языке gdscript (python*)
  • Верстать адаптивный интерфейс под различные экраны мобильных устройств
  • Использовать паттерны проектирования в геймдэве
  • Экспортировать игры на различные платформы (Android, PC, Mac, Linux и.т.д)
  • Отлаживать и исправлять баги
  • Писать грамотный код и организовывать структуру расширяемого проекта

О курсе

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

Ты начнешь с изучения базового функционала движка и основ программирования. Далее постепенно на практике закрепишь эти знания и освоишь продвинутые техники работы с Godot. Все это ты сделаешь, решая реальные практические задачи, возникающие при создании игр.

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

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

Модули курса

  1. Введение в Godot
  2. Написание скриптов на gdscript
  3. Создание базовых механик
  4. Верстка адаптивного UI/HUD
  5. Организция игрового цикла
  6. Добавление игрового контента
  7. Экспорт игры на Android

В курсе нет воды и пространных рассуждений. Динамика курса достаточно высокая. Материал курса учитывает фидбэк подписчиков YouTube канала Frontend Pashtet и стремится быть емким и доступным

Для кого этот курс

Этот курс подходит для начинающих и продолжающих разработчиков. Любой опыт программирования будет полезен

Начальные требования

PC на windows, linux или mac. Опционально: телефон на Android

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

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

https://alkogolizm.vyvod-iz-zapoya-v-stacionare-samara11.ru/