Русский
Русский
English
Статистика
Реклама

2d

2d-графика в React с three.js

06.06.2021 12:22:20 | Автор: admin

У каждого из вас может возникнуть потребность поработать с графикой при создании React-приложения. Или вам нужно будет отрендерить большое количество элементов, причем сделать это качественно и добиться высокой производительности при перерисовке элементов. Это может быть анимация либо какой-то интерактивный компонент. Естественно, первое, что приходит в голову это Canvas. Но тут возникает вопрос: Какой контекст использовать?. У нас есть выбор 2d-контекст либо WebGl. А как на счёт 2d-графики? Тут уже не всё так очевидно.

При работе над задачами с высокой производительностью мы попробовали оба решения, чтобы на практике определиться, какой из двух контекстов будет эффективнее. Как и ожидалось, WebGl победил 2d-контекст, поэтому кажется, что выбор прост.

Но тут возникает проблема. Вы сможете ощутить её, если начнете работать с документацией WebGl. С первых мгновений становится понятно, что она слишком низкоуровневая, в отличие от 2d context. Поэтому, чтобы не писать тонны кода, перед нами встаёт очевидное решение использование библиотеки. Для реализации этой задачи подходят библиотеки pixi.js и three.js с качественной документацией, большим количеством примеров и крупным комьюнити разработчиков.

Pixi.js или three.js

На первый взгляд, выбрать подходящий инструмент несложно: используем pixi.j для 2d-графиков, а three.js для 3d. Однако, чем 2d отличается от 3d? По сути дела, отсутствием 3d-перспективы и фиксированным значением по третьей координате. Для того чтобы не было перспективы, мы можем использовать ортографическую камеру.

Вероятно, вы спросите: Что за камера?. Camera это одно из ключевых понятий при реализации графики, наряду со scene и renderer. Для наглядности приведу аналогию. Представим, что вы стоите в комнате, держите в руках смартфон и снимаете видеоролик. Та комната, в которой вы снимаете видео это scene. В комнате могут быть различные предметы, например, стол и стулья это объекты на scene. В роли camera выступает камера смартфона, в роли renderer матрица смартфона, которая проецирует 3d-комнату на 2d-экран.

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

Таким образом, three.js также подходит для 2d-графики. Так что же в итоге выбрать? Мы попробовали оба варианта и выявили на практике несколько преимуществ three.js.

  • Во-первых, нам нужно было выполнить интерактивное взаимодействие с элементами на сцене. Написать собственную реализацию достаточно трудозатратно, но в обеих библиотеках уже есть готовые решения: в pixi.js из коробки, в three.js библиотека three.interaction.

Казалось бы, в этом плане библиотеки равноценны, но это лишь первое впечатление. Особенность реализации интерактивности в pixi.js предполагает, что интерактивные элементы должны иметь заливку. Но как быть с линейными графиками? У них же нет заливки. Без собственного решения в этом случае не обойтись. Что же касается three.js, то тут этой проблемы нет, и линейные графики также интерактивны.

  • Еще одна задача это экспорт в SVG. Нам нужно было реализовать функциональность, которая позволит экспортировать в SVG то, что мы видим на сцене, чтобы потом это изображение можно было использовать в печати. В three.js для этого есть готовый пример, а вот в pixi.js нет.

  • Ну и будем честны с собой, в three.js больше примеров реализации тех или иных задач. К тому же, изучив эту библиотеку, при желании мы можем работать с 3d-графикой, а вот в случае pixi.js такого преимущества у нас нет.

Исходя из всего вышеописанного, наш выбор очевиден это three.js.

Three.js и React

После выбора библиотеки мы сталкиваемся с новой дилеммой использовать react-обертку или каноническую three.js.

Для react есть реализация обёртки это react-three-fiber. На первый взгляд, в ней довольно мало документации, что может показаться проблемой. Действительно, при переносе кода из примеров three.js в react-three-fiber возникает много вопросов по синтаксису.

Однако, на практике все не так уж сложно. У этой библиотеки есть обёртка drei с неплохим storybook с готовой реализацией множества различных примеров. Впрочем, всё, что за находится пределами этой реализации, по-прежнему может причинять боль.

Еще одна проблема это жёсткая привязка к react. А если мы отлично реализуем view с графикой и захотим использовать где-то ещё? В таком случае снова придётся поработать.

Учитывая эти факторы, мы решили использовать каноническую three.js и написать свою собственную обертку на хуках. Если вы не хотите перебирать множество вариантов реализации, попробуйте использовать нативные ES6 классы это хорошее и производительное решение.

Вот пример нашей архитектуры. В центре сцены нарисован квадрат, который при нажатии на него меняет цвет с синего на серый и с серого на синий.

Создаём класс three.js для работы с библиотекой three.js. По сути, всё взаимодействие с ней будет проходить в объекте данного класса.

class Three {  constructor({    canvasContainer,    sceneSizes,    rectSizes,    color,    colorChangeHandler,  }) {    // Для использования внутри класса добавляем параметры к this    this.sceneSizes = sceneSizes;    this.colorChangeHandler = colorChangeHandler;     this.initRenderer(canvasContainer); // создание рендерера    this.initScene(); // создание сцены    this.initCamera(); // создание камеры    this.initInteraction(); // подключаем библиотеку для интерактивности    this.renderRect(rectSizes, color); // Добавляем квадрат на сцену    this.render(); // Запускаем рендеринг  }   initRenderer(canvasContainer) {    // Создаём редерер (по умолчанию будет использован WebGL2)    // antialias отвечает за сглаживание объектов    this.renderer = new THREE.WebGLRenderer({antialias: true});     //Задаём размеры рендерера    this.renderer.setSize(this.sceneSizes.width, this.sceneSizes.height);     //Добавляем рендерер в узел-контейнер, который мы прокинули извне    canvasContainer.appendChild(this.renderer.domElement);  }   initScene() {    // Создаём объект сцены    this.scene = new THREE.Scene();     // Задаём цвет фона    this.scene.background = new THREE.Color("white");  }   initCamera() {    // Создаём ортографическую камеру (Идеально подходит для 2d)    this.camera = new THREE.OrthographicCamera(      this.sceneSizes.width / -2, // Левая граница камеры      this.sceneSizes.width / 2, // Правая граница камеры      this.sceneSizes.height / 2, // Верхняя граница камеры      this.sceneSizes.height / -2, // Нижняя граница камеры      100, // Ближняя граница      -100 // Дальняя граница    );     // Позиционируем камеру в пространстве    this.camera.position.set(      this.sceneSizes.width / 2, // Позиция по x      this.sceneSizes.height / -2, // Позиция по y      1 // Позиция по z    );  }   initInteraction() {    // Добавляем интерактивность (можно будет навешивать обработчики событий)    new Interaction(this.renderer, this.scene, this.camera);  }   render() {    // Выполняем рендеринг сцены (нужно запускать для отображения изменений)    this.renderer.render(this.scene, this.camera);  }   renderRect({width, height}, color) {    // Создаём геометрию - квадрат с высотой "height" и шириной "width"    const geometry = new THREE.PlaneGeometry(width, height);     // Создаём материал с цветом "color"    const material = new THREE.MeshBasicMaterial({color});     // Создаём сетку - квадрат    this.rect = new THREE.Mesh(geometry, material);     //Позиционируем квадрат в пространстве    this.rect.position.x = this.sceneSizes.width / 2;    this.rect.position.y = -this.sceneSizes.height / 2;     // Благодаря подключению "three.interaction"    // мы можем навесить обработчик нажатия на квадрат    this.rect.on("click", () => {      // Меняем цвет квадрата      this.colorChangeHandler();    });     this.scene.add(this.rect);  }   // Служит для изменения цвета квадрат  rectColorChange(color) {    // Меняем цвет квадрата    this.rect.material.color.set(color);     // Запускаем рендеринг (отобразится квадрат с новым цветом)    this.render();  }}

А теперь создаём класс ThreeContauner, который будет React-обёрткой для нативного класса Three.

import {useRef, useEffect, useState} from "react"; import Three from "./Three"; // Размеры сцены и квадратаconst sceneSizes = {width: 800, height: 500};const rectSizes = {width: 200, height: 200}; const ThreeContainer = () => {  const threeRef = useRef(); // Используется для обращения к контейнеру для canvas  const three = useRef(); // Служит для определения, создан ли объект, чтобы не создавать повторный  const [color, colorChange] = useState("blue"); // Состояние отвечает за цвет квадрата   // Handler служит для того, чтобы изменить цвет  const colorChangeHandler = () => {    // Просто поочерёдно меняем цвет с серого на синий и с синего на серый    colorChange((prevColor) => (prevColor === "grey" ? "blue" : "grey"));  };   // Создание объекта класса Three, предназначенного для работы с three.js  useEffect(() => {    // Если объект класса "Three" ещё не создан, то попадаем внутрь    if (!three.current) {      // Создание объекта класса "Three", который будет использован для работы с three.js      three.current = new Three({        color,        rectSizes,        sceneSizes,        colorChangeHandler,        canvasContainer: threeRef.current,      });    }  }, [color]);   // при смене цвета вызывается метод объекта класса Three  useEffect(() => {    if (three.current) {      // Запускаем метод, который изменяет в цвет квадрата      three.current.rectColorChange(color);    }  }, [color]);   // Данный узел будет контейнером для canvas (который создаст three.js)  return <div className="container" ref={threeRef} />;}; export default ThreeContainer;

А вот пример работы данного приложения.

При первом открытии мы получаем, как и было описано ранее, синий квадрат в центре сцены, которая имеет серый цвет.

После нажатия на квадрат он меняет цвет и становится белым.

Как мы видим, использование нативного three.js внутри React-приложения не вызывает каких-либо проблем, и этот подход достаточно удобен. Однако, на плечи разработчика в этом случае ложится нагрузка, связанная с добавлением/удалением узлов со сцены. Таким образом, теряется тот подход, который берёт на себя virtual dom внутри React-приложения. Если вы не готовы с этим мириться, обратите внимание на библиотеку react-three-fiber в связке с библиотекой drei этот способ позволяет мыслить в контексте React-приложения.

Рассмотрим реализованный выше пример с использованием этих библиотек:

import {useState} from "react";import {Canvas} from "@react-three/fiber";import {Plane, OrthographicCamera} from "@react-three/drei"; // Размеры сцены и квадратаconst sceneSizes = {width: 800, height: 500};const rectSizes = {width: 200, height: 200}; const ThreeDrei = () => {  const [color, colorChange] = useState("blue"); // Состояние отвечает за цвет квадрата   // Handler служит для того, чтобы  const colorChangeHandler = () => {    // Просто поочерёдно меняем цвет с серого на синий и с синего на белый    colorChange((prevColor) => (prevColor === "white" ? "blue" : "white"));  };   return (    <div className="container">      {/* Здесь задаются параметры, которые отвечают за стилизацию сцены */}      <Canvas className="container" style={{...sceneSizes, background: "grey"}}>        {/* Камера задаётся по аналогии с нативной three.js, но нужно задать параметр makeDefault,         чтобы применить именно её, а не камеру заданную по умолчанию */}        <OrthographicCamera makeDefault position={[0, 0, 1]} />        <Plane          // Обработка событий тут из коробки          onClick={colorChangeHandler}          // Аргументы те же и в том же порядке, как и в нативной three.js          args={[rectSizes.width, rectSizes.height]}        >          {/* Материал задаётся по аналогии с нативной three.js,               но нужно использовать attach для указания типа прикрепления узла*/}          <meshBasicMaterial attach="material" color={color} />        </Plane>      </Canvas>    </div>  );}; export default ThreeDrei;

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

В этой статье мы с вами рассмотрели два подхода в использовании библиотеки three.js внутри React-приложения. Каждый из этих подходов имеет свои плюсы и минусы, поэтому выбор за вами.

Спасибо за внимание! Надеемся, что наш опыт был для вас полезен.

Подробнее..

Свой ремейк ZX игры Reskue в Steam

12.06.2021 16:15:59 | Автор: admin

Да, понимаю, что это игра про учёных, но это не игра про немого учёного с монтировкой с цифрой 3, которую все ждут. Что вышло за 4 года разработки.

Официальное описание: Научная станция в глубоком космосе перестала отвечать на запросы. Что там произошло? Вы агент, прибывший выяснить, что случилось и Ваша задача спасти важное открытие, сделанное на станции.

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

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

Это ретро экшен, требующий достаточной быстроты, либо ловкости, либо хитрости от игрока. Есть несколько тактик прохождения игры. Кроме арсенала в 10 видов оружия, каждое из которых накладывает особый эффект на врага и имеет несколько режимов стрельбы, есть ещё и хитрость в виде ловушек или предметов сильно отвлекающих противника. некоторых настолько что игрок будет почти невидим для врагов. Даже на нормальной сложности игра не будет лёгкой прогулкой по которой игрока будут водить за ручку и обьяснять Press F to Win. Однако если вам игра покажется слишком лёгкой уровень сложности можно повысить.

В самой игре заложена и пара "пасхалок" напоминающих о спектруме. Я не скажу где они однако одна из них содержит пару обьектов из Boulder dash, а другая ещё что-то.

Ключевые обновления:

  • Добавлен режим хотсита - кооп (. затем kp9) и версус (. затем kp7). (Игра на 2 клавиатурах и/или джойстиках). Cетевая игра увы возможна только через Steam remote play.

  • Все почти враги теперь анимированы (новое видео пока не готово)

  • Внешний интерфейс (USER GUI) доработан. (Инвентарь, выбранное оружие, датчик жизни, кулдаун, селектор оружия.)

  • Встроенная игровая справка по F2 с описанием тактики поведения и арсенала.

Ключевые особенности

  • Редактор карт поддерживает импорт карт M2K (mission 2000), Rescue+ с реального ZX-Spectrum. Карты будут работать если их копировать программой HOBETA.

  • Мультиязычность и кроссплатформенность.

  • Высокая скорость работы даже на устаревших компьютерах.

Подсказка: Максимально просто игру можно пройти вдвоем - Один из игроков должен выбрать ученого при начале совместной игры.

Игра нетребовательная идёт почти на всём. Требования: 64бит и OpenGL 3.3 и хотя бы 30 мб места.

Steam Ранний доступ.

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

Я ранее писал статью на DTF и если кто хочет просто попробовать игру Reskue или M2K или Colony (очень ранняя версия) может скачать их ниже.

Видео новее пока нет. если только про кооператив и версус ссылка под видео. С тех пор игра была сильно переработана но я пока не осилил трейлер.

Хотсит на русском.

Новый трейлер на польском.

Я на вопросы иногда делаю выпуски видеоответов. Реже чем надо было бы, но делаю. https://www.youtube.com/watch?v=JJAe2b-kTgs - Руководство о портировании готовой игры на Love в Android APK (с подписью) для Linux. В блоге разработчика (devblog) бывают и арты и рисунки и другая всячина.

Игра написана с нуля и сохранившая в основном идею оригинала (Rescue od Mastertronic) и схожесть с Spectrum играми (тайлы, цветовая гамма, некоторая хардкорность геймплея и некоторые команды в Lua движке.). От оригинальной игры не используется ничего, перерисовано все что возможно. Изначально я делал ремейк собственной игры M2K (mission2000), затем понял что на основе движка могу сделать новую игру что и начал в 2019, вдохновили меня в коллективе confa-gd на конкурсе Джем победы на это. Канал по игре.

C чего всё начиналось:

Это оказался прекрасный фундамент для применения множества идей как Sci-fi так и просто современных удобств геймплея каждую из которых пришлось делать самому, т.к. движок мой авторский на Love framework. Я постарался бережно развить идею так как ранее с ограничениями платформы ее развить было бы значительно сложнее. Я с трудом нашел нескольких художников и аниматоров и за ещё 2 года и 16К получилась эта игра. Отдельная история и целая лекция получилась по работе со Steamworks чтобы игра попала в магазин, это заняло целых полгода в основном доработки тексту. Я даже не думаю что она вообще когда то отобьется и будет кормить меня и принесет мне хоть что то. мне просто хотелось возродить частичку классики так как я её вижу и сделать ее доступной всем.

Также я веду небольшой ютуб и телеграм каналы без мемасиков и приколов посвященный Linux для домашнего использования. Сборка в основном для тестирования Windows игр предназначена. Сам я выбрал Mint c Mate DE немного новостей немного взаимопомощи.

N.B. Людям, которые ждут, что один человек почти в одно лицо накодит им Ведьмака 3 в 3D за денек, прошу выйти из чата. Этим методом получатся только игры для Gry z kosza (польская передача об очень плохих играх).

Мне просто хочется, чтобы в эту игру можно было сыграть и через много лет спустя, я думаю Steam с нами всеми надолго и игра там точно проживёт много лет. Да название я написал в духе названия mortal kombat. А почему нет?

Также я время от времени обновляю код движка на github. У меня там несколько проектов.

Подробнее..

Твоя первая игра на Godot Engine

02.12.2020 18:09:40 | Автор: admin

1. Предисловие

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

2.Стартуем!

Думаю установить сам движок не составит труда. После установки открываем его и нажимаем на кнопку новый проект.

Создание проекта.Создание проекта.

В выплывшем окошке введи название проекта и выбери его расположение в файловой системе. В пункте отрисовщик выбираем OpenGL ES 3.0, у нас нет нужды использовать более старую версию opengl, т.к ее обычно применяют при создании браузерных игр.

3.Знакомство с интерфейсом

2D сцена в Godot Engine.2D сцена в Godot Engine.

Итак, мы создали твой первый проект! Отличное начало, на сегодня хватит. Ладно, а если серьезно, то изучать интерфейс программы, особенно на первых парах, очень важно. Перед тобой открылась интересная картина с пустой 3d сценой, но она нам сегодня не понадобится, поэтому переходим в вкладку 2d. Кнопка находится сверху посередине. Стало немного проще, не правда ли? Ну, а теперь перейдем к самому интерфейсу программы (его кстати можно настроить под себя, перетащив какие-то элементы левой кнопкой мыши, но пока лучше оставит все как есть).

4.Работа с файлами через Godot

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

Проводник в Godot Engine.Проводник в Godot Engine.

Пока что там пусто, но это потому, что мы еще ничего не добавили. Так давай сделаем это! Ссылку на архив я прикрепил в конце поста, скачивай его и наслаждайся халявными спрайтами для игры (сразу говорю, они не мои). Если конечно у тебя заготовлена своя графика, то милости прошу.Итак, выделяем все нужные нам файлы и переносим их в окошечко. Вжух и они скопировались в движок! Но на этом магия не заканчивается! Здесь можно делать все то, что ты делаешь в обычном проводнике! Одним словом, полная свобода действий.

Но давай пока оставим эту часть экрана в покое и перейдем к более серьезным вещам.

5.Работа со сценами

Создание новых сцен.Создание новых сцен.

Посмотри в верхний левый угол редактора. Здесь есть вкладка, которая называется Сцена. Давай добавим твою первую сцену! Делается это просто, тебе нужно либо нажать на плюсик, либо ввести сочетание клавиш ctrl + A. Перед тобой выплыло меню, в поиске которого нужно ввести заветное слово Node. Мы давай это будет наша основная сцена, назовем ее World, но название в принципе неважно. Чтобы переименовать сцену нужно лишь дважды щелкнуть на нее левой кнопкой мыши. Теперь давай добавим на сцену игрока!

Многие просто добавляют объект Sprite, но это большая ошибка! Так делать нельзя! Запомни это раз и навсегда! Мы с тобой, как продвинутые пользователи добавим не Sprite, а KinematicBody2D.

Теперь древо твоего проекта выглядит так:

Добавляем игрока.Добавляем игрока.

Как ты наверное успел заметить, напротив нашего KinematicBode2D висит какой-то желты значок. Что он тут забыл? Дело в том, что наш объект пока что не имеет форму, вот Godot и ругается. Но прежде чем добавить форму нашему игроку, давай добавим его спрайт( И не забудь заменить название KinrmaticBode2D на Player ). Для этого нажми один раз правой кнопкой мыши на нашего Player и сочетанием клавиш ctrl + A добавь объект Sprite. Потом опять нажми на Игрока и добавь объект CollisionShape2D. У тебя должна быть примерно такая картина:

Добавляем в спрайт и границы игрока.Добавляем в спрайт и границы игрока.

Если все так, едем дальше. Теперь зададим картинку спрайта нашего персонажа. Выбираем объект Sprite, а потом перетаскиваем из моего архива картинку Player.png( или твою картинку) в раздел Texture. Если картинка импортировалась с сжатым качеством, просто нажми на нее, и в Godot в верхнем левом углу перейди в вкладку Импорт, там в разделе Flags убери галочку с пункта Filter и нажми Переимпортировать. Если не помогло, то просто перезапусти Godot.

Итак, мы добавили спрайт игрока, но выглядит это немного странно.

Добавляем текстуру спрайта игрока.Добавляем текстуру спрайта игрока.

Что же делать? Без паники, все поправимо в пару кликов. В левой части панели Инспектор выбираем параметр Hframes, и подгоняем его по размерам ( у меня это 25). Ну что, поменялась картинка?

Устанавливаем границы спрайта.Устанавливаем границы спрайта.

Супер, едем дальше! Ты еще не забыл про CollisionShape2D? Выделяй его и в пункте Shape выбирай Новый RectangleShape2D. Теперь изменяй его под размер персонажа. У меня получилось так:

CollisionShape2d.CollisionShape2d.

6.Отдельные сцены в Godot

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

Создание сцены из ветки.Создание сцены из ветки.

Теперь Player это отдельная сцена, отлично!Чтобы перейти на сцену игрока достаточно нажать на иконку:

Перейдем на сцену игрока и приступим к очень интересному занятию программированию.

7. Скрипт игрока, GDscript

Для того чтобы добавить скрипт какому-либо объекту нежно просто выбрать этот объект и нажать на иконку свитка:

Создать скрипт.Создать скрипт.

После этого выплывет такая табличка:

Скрипт для игрока.Скрипт для игрока.

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

Простое управление.Простое управление.

Пишем вот такой код, не волнуйся сейчас все объясню. Первая строчка объявляет Godot, что мы используем объект KinematicBody2D. Ее создал сам движок. На 3 и 4 строчке мы задаем две константы, отвечающие за ускорение и максимальную скорость. Они нужны для плавного перемещения персонажа по сцене. На 6 строчке объявляем переменную для вектора перемещения. После этого на 8 строчке создаем функцию physicsprocess, это системная функция движка. Она нужна, чтобы привязать к персонажу физику. В нашем случае - это физика перемещения и сила гравитации. 9 строчка отвечает за управление по оси X. Метод Input помогает нам считывать те самые кнопки для управления (стрелка влево и стрелка вправо). После на 11 строчке мы проверяем была ли нажата какая-то кнопка. Потом мы перемещаемся влево или вправо.

Как ты заметил, мы прибавляем к координате игрока произведение направления по координате на ускорение и на какую-то delta. Вопрос, что такое delta? Delta показывает сколько времени (в секундах, тип float) прошло с момента отрисовки прошлого кадра.Зачем это сделано? Если мы не будем привязывать передвижение игрока ко времени, то оно автоматически привязывается к частоте процессора. На крутых компьютерах или телефонах разница незаметна, но запустив приложение на старом пк или телефоне, ты все поймешь. Поэтому всегда привязывай передвижение к delta!

Потом в строке 13 мы используем какой-то clamp. Опять неразбериха! Все просто, clamp, как можно догадаться из названия, сжимает значение переменной. Сделано это для оптимизации и плавности движения.Ну и в последней строке мы просто запускаем передвижение нашего игрока. Не так уж все и сложно!

8. Первый запуск.

Вот сделали мы все это с тобой, а где результат? Ну так давай поскорее запустим с тобой первую демку! Все очень просто, нажми клавишу F5, после этого выплывет окно, которое скажет тебе, что основания сцена не выбрана. В нашем случае основная сцена World.tscn. Выбираем ее и снова жмем F5. Должно появиться что-то такое:

Окно демки.Окно демки.

В верхнем левом углу можно заметить маленькую часть нашего персонажа. Давай приведем все в порядок. Для этого сначала закрое окошко демки и перейдем в настройки проекта. Чтобы это сделать, в левой верхней части нажми на Проект, а в выплывшем окне нажми Настройки проекта. Здесь переходим в вкладку Window и ставим разрешение на 320x180. Почему такое маленькое? Все просто, мы с тобой задали разрешение экрана в самой сцене, для платформера такие размеры идеальны. А для экрана самой демки нужно задать нормальное разрешение. Это можно сделать в пунктах Test Width и Test Height. Я задам его в формате 1280x720. Спустимся пониже и в пункте Mode ставим 2d, а в Aspect ставим keep. Для красоты предлагаю обратно перейти на сцену и передвинуть персонажа в середину экрана. Делается это легко, просто зажми персонажа левой кнопкой мыши и начни перетаскивать. Теперь все приготовления закончены,можно запускать демку.

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

9.Tilemaps

Что такое Tilemap? Тайлы это плитки, вместе образующие сетку тайлов. Чаще всего они принимают форму квадратов. Как же их добавить в наш платформер? Очень просто, для начала выбери объект World(нашу основную сцену), нажми клавиши ctrl + A и выбери TileMap.

Теперь в этом окошке выбири Tile Set и нажми Новый TileSet.Снова нажми на TileSet, должно получиться ка-то так:

Добавляем анимацию.Добавляем анимацию.

Давай добавим спрайт для нашего tilemap, для этого нажми на плюс снизу и выбери tile.png.

Следующий шаг будет довольно сложным, поэтому слушай внимательно.Итак, в вкладке Регион полостью выделяем нашу картинку, в вкалдке snap options ставим step по x и y на 16. Такие же действия повторяем в вкладках столкновение, перекрытие, навигация, битовая маска. А последней мы остановимся поподробней.

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

Задаем границы тайла.Задаем границы тайла.

Отлично, сохраняем все и переходим обратно на сцену. Еще рах кликаем на Tilemap и в раздеел Cell меняем size на 16x16.Теперь можно делать уровень!

Создаем простой уровень.Создаем простой уровень.

Вот как у меня получилось. Супер, но на нашего игрока до сих пор не действует гравитация, давай это исправим. Для этого перейдем в скрипт player и введем там такой код.

Константы для прыжка и гравитации.Константы для прыжка и гравитации.

Здесь к существующим переменным мы добавляем friction, gravity, jumpforce, airresistance. Названия говорят сами за себя, поэтому объяснять за что они отвечают я не буду.

Реализация прыжка и гравитации.Реализация прыжка и гравитации.

Следом идет сама сила гравитации. Мы прибавляем к motion.y силу тяжести, умноженную на delta. Это действие заставляет нашего игрока падать вниз, если под ним ничего нет. После этого скрипт обрабатывает нажатия на кнопки, характерные для прыжка (стрелочка вверх). И заставляет игрока падать вниз, когда он уже прыгнул.

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

Как выглядит при запуске.Как выглядит при запуске.

10.Анимации

Простые анимации в Godot сделать очень легко. Для этого перейдем на сцену player и добавим туда AnimationPlayer. Жмем на кнопку анимация, далее жмем новый и вводим название анимации. Сделаю анимацию для бега и назову ее Run.Чтобы добавить новый кадр для анимации нужно перейти в sprite.

Добавляем кадры в анимацию.Добавляем кадры в анимацию.

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

Создаем анимацию из кадров.Создаем анимацию из кадров.

Тоже самое повторяем для других анимаций, просто меняя номер кадра. В итоге у тебя будет несколько анимаций для прыжка, ходьбы, и анимация idle. Теперь все это нужно добавить в код.Переходим в код player и вносим некоторые изменения:

Добавляем переменные для анимации.Добавляем переменные для анимации.

Добавляем две переменные sprite и player. Но ты заметил, они какие-то странные. Почему в начале стоит слово onready, что за странное значение этой переменной? Сейчас все объясню. Переменные типа onready нужны для взаимодействий с другими объектами на сцене. В данном случае мы подключаем их для воспроизведения анимации и получения спрайта игрока.

Анимация при ходьбе.Анимация при ходьбе.

На 16-ой строчке мы проигрываем анимацию ходьбы. Однако здесь еще появилась какая-то странная 22 строчка, что она делает? Она зеркально отражает анимацию игрока в зависимости от того, куда он идет. А на 24 строке мы говорим, что если игрок стоит, то проигрывать нужно анимацию idle.

Анимация прыжка.Анимация прыжка.

На 22 строчке мы проигрываем анимацию прыжка, если игрок не на земле. Вот собственно и все изменения в коде.

Заключение

Если ты все правильно делал, то у тебя должен получиться простой платформер. Что делать дальше? Да все что угодно! Улучшай свои навыки в использовании движка, создавай свои собственные игры изучай новые фишки. А этом я вынужден с тобой проститься, надеюсь ты хорошо провел время и научился чему-то новому.

Вот все материалы для этого туториала:

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru