Как составить свою игру онлайн

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

Благодаря современным технологиям вы буквально за 10-20 минут можете создать викторину наподобие «Своей игры» и сыграть в нее с друзьями. В этой статье мы расскажем, как сделать такую викторину в PowerPoint. Начинайте придумывать вопросы!

Кроме того, вы получите подробную пошаговую инструкцию по созданию викторины с нуля и бесплатный шаблон викторины в формате PPT.

Итак, приступим!

Этап 1: Создаем игровое поле

  1. Откройте PowerPoint и создайте новую презентацию.
  2. На вкладке Дизайн выберите и примените понравившуюся тему оформления.
  3. Создайте новый слайд и добавьте на него таблицу (ВставкаТаблица).

Вставка таблицы в PowerPoint

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

Таблица

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

Заливка

Когда вы выполните все шаги, игровое поле будет выглядеть примерно так:

Игровое поле

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

Разбираемся с макетами слайдов

У каждого слайда в PowerPoint есть свой макет. Например, Титульный слайд или Заголовок и объект.

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

Образец слайдов

Вы также можете редактировать и создавать новые макеты слайдов при помощи инструмента Образец cлайдов (Slide Master).

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

В основном у вас будут слайды двух типов:

  • Слайд с вопросом. На нем будет размещен текст вопроса и кнопка Узнать ответ для проверки правильности ответа игрока.

Слайд с вопросом

  • Слайд с правильным ответом. На нем будет содержаться ответ на вопрос и кнопка Домой, ведущая обратно на игровое поле.

Слайд с ответом

Если вы внесете какие-либо изменения через Образец cлайдов, они будут автоматически применены ко всем слайдам этого типа в презентации.

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

Этап 2: Создаем макеты слайдов для вопросов и ответов

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

Если вы хотите самостоятельно создать макеты, выполните следующие шаги:

  1. Перейдите на вкладку Вид и выберите Образец слайдов.
  2. Нажмите Вставить макет.

макет

  1. Кликните по макету правой кнопкой мышки и нажмите «Переименовать».

Переименовать макет

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

Управляющие кнопки

  1. В Настройке действия выберите Перейтина по гиперссылке: следующий слайд и нажмите ОК.

Настройка действия

  1. Кликните правой кнопкой мышки по кнопке, нажмите Изменить текст и напишите слово «Ответ» (или «Узнать ответ» — как больше нравится).

Ответ

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

Домой

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

закрыть-образец

Этап 3: Добавляем слайды и расставляем ссылки на игровом поле

Итак, у нас уже есть титульный слайд и слайд с игровым полем. Кроме того, мы сделали макеты слайдов для вопросов и ответов.

  1. Создайте третий слайд. Кликните правой кнопкой мышки и выберите ранее созданный макет Вопрос.
  2. Создайте четвертый слайд. Кликните правой кнопкой мышки и выберите ранее созданный макет Правильный ответ. У вас должно получиться так:

Слайд с вопросом

  1. У вас получилась пара вопрос-ответ. Продублируйте слайды 3 и 4 столько раз, сколько активных клеток на игровом поле. В нашем примере поле состоит из 20 клеток. Итоговое количество слайдов вместе с первыми двумя будет равняться 42.

Примечание: Рекомендуем на слайдах с вопросами вместо самих вопросов сперва написать черновые обозначение (например, Категория 1, Вопрос на 200). Так вам будет проще расставить гиперссылки.

Соедините клетки игрового поля с соответствующими слайдами:

  1. Выделите цифры в клетке игрового поля, кликните правой кнопкой мышки и выберите Гиперссылка (или нажмите Ctrl+K).

Гиперссылка

  1. В открывшемся окне в левой панели выберите Место в документе и укажите нужный слайд (например, Категория 1, Вопрос на 200).
  2. Нажмите ОК, чтобы вставить гиперссылку.

Вставка гиперссылки

Ограничиваем навигацию

Перейдите во вкладку Переходы. Выберите все слайды за исключением первого и снимите галочку с пункта Смена слайда: по щелчку. Это обеспечит навигацию по гиперссылкам и кнопкам в вашей игре вместо перехода на следующий слайд по щелчку мышки.

по-щелчку

Этап 4: Добавляем интерактивные вопросы

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

Добавляем изображения к вопросам

Просто перетащите любую картинку в презентацию из папки на вашем компьютере. Лучше всего использовать изображения в формате PNG с прозрачным фоном.

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

Вопрос с изображением

Вы можете добавлять разные эффекты, например, тень, отражение или подсветку. Выберите вкладку Формат и нажмите Формат рисунка. При желании можно добавить анимацию.

Правильный ответ: Он чувствует себя не в своей тарелке

Загружаем музыку и настраиваем автопроигрывание

Перетащите аудиофайл на слайд или нажмите Вставить → Аудио.

Аудиовопрос

Кликните на иконку аудиофайла и перейдите во вкладку Воспроизведение. Установите Начало: автоматически.

Звук автоматически

Мы рекомендуем использовать аудиофайлы длиной 15 секунд или меньше. Кстати, Musopen.org — отличный сайт, где можно легально и бесплатно скачать музыку.

Правильный ответ: Соловей

Добавляем видеовопросы

Перетащите видео на слайд с вопросом или перейдите во вкладку Вставка и нажмите Видео.

Скриншот из викторины Своя игра

По аналогии с аудиофайлом, перейдите во вкладку Воспроизведение и установите Начало: автоматически.

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

Правильный ответ: Итальянский

Другие улучшения

Вот несколько советов, как еще улучшить вашу игру:

  • Добавьте эффекты перехода для слайдов с вопросами («Выцветание» или «Увеличение»), используя режим Образец слайдов.
  • Добавьте эффект «Перелистывание» на слайды с ответами, чтобы они выглядели так, будто вы переворачиваете карточку.
  • Добавьте триггеры, чтобы скрыть клетки с отвеченными вопросами (вы увидите их в образце презентации, который прилагается к этой статье. В веб-презентации в формате HTML5 их не будет видно).
  • Добавьте аудиотриггеры на слайды с вопросами. Например, звуки победы или поражения. Используйте эти звуки во время игры, чтобы было веселее.
  • Добавьте второй тур викторины и финал и вставьте ссылки на них на слайд с игровым полем первого тура.

Протестируйте получившуюся игру

Убедитесь, что все ссылки и эффекты работают корректно. Запустите презентацию, нажав F5оказ слайдовС начала), и просмотрите игру целиком. Проверьте каждую гиперссылку на игровом поле и удостоверьтесь, что они ведут на правильные вопросы.

Выложите игру в интернет

С помощью iSpring Converter Pro вы можете опубликовать свою викторину в интернет всего за один клик в виде веб-файла, как в этой статье.

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

Не забудьте проверить ее работоспособность после публикации.

Сыграйте в свою игру

А теперь самое интересное! После того как вы создали игру и разместили ее в интернете, пришло время пригласить друзей и сыграть! Вам понадобится два или более игроков, лист бумаги и карандаш для записи счета.

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

Правила игры просты:

  • Первый игрок выбирает категорию и сложность вопроса. Например, Президенты США, 300.
  • Ведущий кликает на выбранную клетку игрового поля и зачитывает вопрос вслух. Например: «Медвежонок Тедди был изобретен после того, как этот американский президент отказался на охоте застрелить медведя, привязанного к дереву».
  • После того как ведущий прочитает вопрос, любой из участников может хлопнуть в ладоши, чтобы ответить. Например, предположить, что это был Теодор Рузвельт.
  • Если ответ верный, игрок получает количество очков, полагающееся за этот вопрос, и может выбрать следующий.
  • Если ответ неверный, игрок получает штрафные очки, при этом другой игрок может попытаться ответить на вопрос.
  • После того как все вопросы на игровом поле будут отвечены, начинается подсчет очков. Игрок с наибольшим количеством очков побеждает.

Посмотрите, какая игра получилась у нас:

Викторина Своя игра

Чтобы узнать больше об официальных правилах игры, прочитайте официальную страничку оригинальной игры Jeopardy! на Википедии, а также страничку о «Своей Игре».

В «Свою игру» можно играть где угодно: хоть в садике, хоть в офисе. Цель викторины — не только проверить знания и скорость реакции, но и разрядить обстановку и сблизить участников.

Если у вас возникли трудности с составлением вопросов, посмотрите записи прошедших телевизионных игр.

Скачайте готовый шаблон

Скачайте готовый шаблон викторины «Своя игра» от iSpring.
Если вам нужна помощь с созданием викторины в PowerPoint — дайте знать специалистам поддержки iSpring. 

Современная вычислительная техника позволяет создавать классные компьютерные игры! И сейчас, достаточно популярны игры с 3d-графикой, так как, играя в них, ты окунаешься в вымышленный мир и теряешь всякую связь с реальностью. Развитие интернета и браузерных технологий сделало возможным запускать головоломки и стрелялки в любимом Хроме, Мозилле или еще в чем-то там (про Эксплорер помолчим) в онлайн-режиме, без загрузки. Так вот, здесь я расскажу о том, как создать простую трехмерную браузерную игру.

Выбор жанра, сюжета и стилистики игры является достаточно интересной задачей, и от решения этих вопросов может зависеть успех игры. Кроме этого, свои нюансы вносит и выбор технологии, на основе которой будет создаваться продукт. Моя цель – показать элементарные основы этого увлекательного процесса, поэтому я буду делать 3-мерный лабиринт с незамысловатым оформлением. Более того, я это сделаю на чистом коде без использования библиотек и движков, типа three.js (хотя большие проекты лучше делать все-таки на нем), чтобы показать, как можно создать движок для своих нужд. Полностью самописная игра может быть оригинальной, а потому интересной. В общем, оба подхода имеют свои плюсы и минусы.

Я полагаю, если вы читаете эту статью, то вам интересна тема создания игр для гугл Хром, а, значит, понимаете, как работает связка html-css-javaScript, поэтому не буду останавливаться на основах, а сразу приступлю к разработке. В html5 и css3, которые поддерживают все современные браузеры (Эксплорер не в счет), есть возможность расположения блоков в 3-мерном пространстве. Также есть элемент , в котором можно рисовать линии и графические примитивы. Большинство браузерных движков используют <сanvas>, так как на нем можно сделать больше вещей, да и производительность на нем выше. Но для простых вещей вполне можно использовать методы transform-3d, которые будут занимать меньше кода.

1. Инструменты для разработки

Я использую для проверки сайтов и игр только 2 браузера: Chrome и Mozilla. Все остальные браузеры (кроме того самого Эксплорера) построены на движке первого, поэтому использовать их я не вижу смысла, ибо результаты точно такие же, как и в Chrome. Для написания кода достаточно Notepad++.

2. Как реализуется трехмерное пространство в html?

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

По умолчанию, дочерний блок имеет координаты (left и top) 0 пикселей по x и 0 пикселей по y. Смещение (translate), также 0 пикселей по всем трем осям. Покажем это на примере, для чего создадим новую папку. В нем создадим файлы index.html, style.css и script.js. Откроем index.html и запишем туда следующее:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world">
        </div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

В файле style.css зададим стили для элементов “container” и “world”.

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
}
#world{
	width:300px;
	height:300px;
        background-color:#C0FFFF;
}

Сохраним. Откроем index.html c помощью Chrome, получим:

Попробуем применить translate3d к элементу “world”:

#world{
	width:300px;
	height:300px;
        background-color:#C0FFFF;
        transform:translate3d(200px,100px,0px);
}

Как вы поняли, я перешел в полноэкранный режим. Теперь зададим смещение по оси Z:
transform:translate3d(200px,100px,-1000px);

Если вы снова откроете html-файл в браузере, то никаких изменений вы не увидите. Чтобы увидеть изменения, нужно задать перспективу для объекта “container”:

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
	perspective:600px;
}

В результате:

Квадрат отдалился от нас. Как работает перспектива в html? Взглянем на картинку:

d – расстояние от пользователя до объекта, а z – его координата. Отрицательный z (в html это translateZ) означает, что мы отдалили объект, а положительный – наоборот. Значение perspective определяет величину d. Если же свойство perspective не задано, то значение d принимается за бесконечность, а в этом случае объект визуально не изменяется для пользователя с изменением z. В нашем случае мы задали d = 600px. По умолчанию, точка взгляда перспективы находится в центре элемента, однако ее можно изменить путем задания свойства perspective-origin: .

Теперь повернем “world” вокруг какой-нибудь оси. В сss можно использовать 2 способа вращения. Первый – вращение вокруг осей x,y и z. Для этого используются transform-свойства rotateX(), rotateY() и rotateZ(). Второй – вращение вокруг заданной оси с помощью свойства rotate3d(). Мы будем использовать первый способ, так как он больше подходит для наших задач. Обратите внимание, что оси вращения выходят из центра прямоугольника!

Точка, относительно которой происходят трансформации, может быть изменена путем задания свойства translate-origin: . Итак, зададим вращение “world” по оси x:

#world{
	width:300px;
	height:300px;
background-color:#C0FFFF;
transform:translate3d(200px,100px,0px) rotateX(45deg);
}

Получим:

Заметно смещение против часовой стрелки. Если же мы добавим rotateY(), то получим смещение уже по оси Y. Важно заметить, что при вращении блока оси вращения также поворачиваются. Вы также можете поэкспериментировать с различными значениями вращения.
Теперь внутри блока “world” создадим еще один блок, для этого добавим тег в html-файл:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world">
			<div id="square1"></div>
		</div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

В style.css добавим стили к этому блоку:

#square1{
	position:absolute;
	width:200px;
	height:200px;
	background-color:#FF0000;
}

Получим:

То есть, элементы внутри блока “world” будут трансформироваться в составе этого блока. Попробуем повернуть “square1” по оси y, добавив к нему стиль вращения:
transform: rotateY(30deg);

В итоге:

«Где вращение?» — спросите вы? На самом деле именно так выглядит проекция блока “square1” на плоскость, образуемую элементом “world”. Но нам нужна не проекция, а настоящее вращение. Чтобы все элементы внутри “world” стали объемными, необходимо применить к нему свойство transform-style:preserve-3d. После подстановки свойства внутрь списка стилей “world” проверим изменения:

Отлично! Половина блока “square” скрылась за голубым блоком. Чтобы его полностью показать, уберем цвет блока “world”, а именно, удалим строку background-color:#C0FFFF; Если мы добавим еще прямоугольников внутрь блока “world”, то мы можем создать трехмерный мир. Сейчас же уберем смещение мира “world”, удалив строку со свойством transform в стилях для этого элемента.

3. Создаем движение в трехмерном мире

Для того, чтобы пользователь мог по этому миру передвигаться, нужно задать обработчики нажатия клавиш и перемещения мыши. Управление будет стандартным, какое присутствует в большинстве 3д-шутеров. Клавишами W, S, A, D мы будем перемещаться вперед, назад, влево, вправо, пробелом мы будем прыгать (проще говоря – перемещаться вверх), а мышью мы будем менять направление взгляда. Для этого откроем пока еще пустой файл script.js. Сначала впишем туда такие переменные:

// Нажата ли клавиша?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;

Изначально клавиши не нажаты. Если мы нажмем клавишу, то значение определенной переменной изменится на 1. Если отпустим ее, то она снова станет 0. Реализуем это посредством добавления обработчиков нажатия и отжатия клавиш:

// Обработчик нажатия клавиш

document.addEventListener("keydown", (event) =>{
	if (event.key == "a"){
		PressLeft = 1;
	}
	if (event.key == "w"){
		PressForward = 1;
	}
	if (event.key == "d"){
		PressRight = 1;
	}
	if (event.key == "s"){
		PressBack = 1;
	}
	if (event.keyCode == 32 && onGround){
		PressUp = 1;
	}
});

// Обработчик отжатия клавиш

document.addEventListener("keyup", (event) =>{
	if (event.key == "a"){
		PressLeft = 0;
	}
	if (event.key == "w"){
		PressForward = 0;
	}
	if (event.key == "d"){
		PressRight = 0;
	}
	if (event.key == "s"){
		PressBack = 0;
	}
	if (event.keyCode == 32){
		PressUp = 0;
	}
});

Номер 32 – код пробела. Как видите, тут появилась переменная onGround, указывающая на то, находимся ли мы на земле. Пока разрешим движение вверх, добавив после переменных press… переменную onGround:

// На земле ли игрок?

var onGround = true;

Итак, мы добавили алгоритм нажатия и отжатия. Теперь необходимо добавить само передвижение. Что, собственно, мы передвигаем. Представим, что у нас есть объект, который мы двинаем. Назовем его “pawn”. Как и принято у нормальных разработчиков, для него мы создадим отдельный класс “Player”. Классы в javaScript создаются, как ни странно, с помощью функций:

function player(x,y,z,rx,ry) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.rx = rx;
	this.ry = ry;
}

Вставим этот код в script.js в самом начале файла. В конце же файла создадим объект данного типа:

// Создаем новый объект

var pawn = new player(0,0,0,0,0);

Распишем, что означают эти переменные. x, y, z – это начальные координаты игрока, rx, ry – углы его поворота относительно осей x и y в градусах. Последняя записанная строка означает, что мы создаем объект “pawn” типа “player” (специально пишу тип, а не класс, так как классы в javascript означают несколько другие вещи) с нулевыми начальными координатами. Когда мы двигаем объект, координата мира изменяться не должна, а должна изменяться координата «pawn». Это с точки зрения переменных. А с точки зрения пользователя, игрок находится на одном месте, а вот мир двигается. Таким образом, нужно заставить программу изменять координаты игрока, обрабатывать эти изменения и двигать, в конце концов, мир. На деле это проще, чем кажется.

Итак, после загрузки документа в браузер мы запустим функцию, которая перерисовывает мир. Напишем функцию перерисовки:

function update(){
	
	// Высчитываем смещения
	
	let dx = (PressRight - PressLeft);
	let dz = - (PressForward - PressBack);
	let dy = PressUp;
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	
	// Изменяем координаты мира (для отображения)
	
	world.style.transform = 
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
	
};

В новых браузерах world будет соответствовать элементу с id=«world», однако надежнее ее присвоить перед функцией update() с помощью следующей конструкции:

var world = document.getElementById("world");

Мы будем изменять положение мира каждые 10 мс (100 обновлений в секунду), для чего запустим бесконечный цикл:

TimerGame = setInterval(update,10);

Запустим игру. Ура, теперь мы можем двигаться! Однако мир вылазит за пределы рамок элемента «container». Чтобы этого не происходило, зададим css-свойство для него в style.css. Добавим строку overflow:hidden; и посмотрим на изменения. Теперь мир остается в пределах контейнера.

Вполне возможно, что вы не всегда понимаете, куда нужно записывать те или иные строчки кода, поэтому сейчас я вам представлю файлы, которые, как я полагаю, у вас должны получиться:

index.html:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world">
			<div id="square1"></div>
		</div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

style.css:

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
	perspective:600px;
	overflow:hidden;
}
#world{
	position:absolute;
	width:300px;
	height:300px;
	transform-style:preserve-3d;
}
#square1{
	position:absolute;
	width:200px;
	height:200px;
	background-color:#FF0000;
	transform:rotateY(30deg);
}

script.js:

// Конструктор Pawn

function player(x,y,z,rx,ry) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.rx = rx;
	this.ry = ry;
}

// Нажата ли клавиша?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;

// На земле ли игрок?

var onGround = true;

// Обработчик нажатия клавиш

document.addEventListener("keydown", (event) =>{
	if (event.key == "a"){
		PressLeft = 1;
	}
	if (event.key == "w"){
		PressForward = 1;
	}
	if (event.key == "d"){
		PressRight = 1;
	}
	if (event.key == "s"){
		PressBack = 1;
	}
	if (event.keyCode == 32 && onGround){
		PressUp = 1;
	}
});

// Обработчик отжатия клавиш

document.addEventListener("keyup", (event) =>{
	if (event.key == "a"){
		PressLeft = 0;
	}
	if (event.key == "w"){
		PressForward = 0;
	}
	if (event.key == "d"){
		PressRight = 0;
	}
	if (event.key == "s"){
		PressBack = 0;
	}
	if (event.keyCode == 32){
		PressUp = 0;
	}
});

// Создаем новый объект

var pawn = new player(0,0,0,0,0);

// Привяжем новую переменную к world

var world = document.getElementById("world");

function update(){
	
	// Задаем локальные переменные смещения
	
	let dx = (PressRight - PressLeft);
	let dz = - (PressForward - PressBack);
	let dy = - PressUp;
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	
	// Изменяем координаты мира (для отображения)
	
	world.style.transform = 
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
	
};

TimerGame = setInterval(update,10);

Если у вас что-то по-другому, обязательно поправьте!

Мы научились двигать персонажа, однако мы еще не умеем поворачивать его! Поворот персонажа, конечно же, будет осуществляться с помощью мыши. Для мыши к переменным состояния клавиш press… мы добавим переменные состояния движения мыши:

// Нажата ли клавиша и двигается ли мышь?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;

А после обработчиков нажатия-отжатия вставим обработчик движения:

// Обработчик движения мыши

document.addEventListener("mousemove", (event)=>{
	MouseX = event.movementX;
	MouseY = event.movementY;
});

В функцию update добавим поворот:

	// Задаем локальные переменные смещения
	
	let dx = (PressRight - PressLeft);
	let dz = - (PressForward - PressBack);
	let dy = - PressUp;
	let drx = MouseY;
	let dry = - MouseX;
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	pawn.rx = pawn.rx + drx;
	pawn.ry = pawn.ry + dry;

Обратите внимание на то, что движение мыши по оси y вращает pawn по оси x и наоборот. Если мы посмотрим на результат, то ужаснемся от увиденного. Дело в том, что если смещения нет, то MouseX и MouseY остаются прежними, а не приравниваются к нулю. Значит, после каждой итерации update смещения миши должно обнуляться:

// Задаем локальные переменные смещения
	
	let dx = (PressRight - PressLeft);
	let dz = - (PressForward - PressBack);
	let dy = - PressUp;
	let drx = MouseY;
	let dry = - MouseX;

// Обнулим смещения мыши:
	
	MouseX = MouseY = 0;

// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	pawn.rx = pawn.rx + drx;
	pawn.ry = pawn.ry + dry;

Уже лучше, мы избавились от инерции вращения, однако вращение происходит все равно странно! Чтобы понять, что все-таки происходит, добавим div-элемент «pawn» внутрь «container»:

	<div id="container">
		<div id="world">
			<div id="square1"></div>
		</div>
		<div id="pawn"></div>
	</div>

Зададим ему стили в style.css:

#pawn{
	position:absolute;
	width:100px;
	height:100px;
	top:400px;
	left:600px;
	transform:translate(-50%,-50%);
	background-color:#0000FF;
}

Проверим результат. Теперь все ровно! Единственное — синий квадрат остается впереди, но пока оставим это. Чтобы сделать игру от первого лица, а не от третьего, нужно приблизить мир к нам на значение perspective. Сделаем это в script.js в функции update():

world.style.transform = 
	"translateZ(600px)" +
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";

Теперь можно делать игру от первого лица. Скроем pawn добавив строку в style.css:

#pawn{
	display:none;
	position:absolute;
	top:400px;
	left:600px;
	width:100px;
	height:100px;
	transform:translate(-50%,-50%);
	background-color:#0000FF;
}

Отлично. Сразу скажу, что ориентироваться в мире с одним квадратом крайне тяжело, поэтому создадим площадку. Добавим в «world» блок «square2»:

	<div id="world">
			<div id="square1"></div>
			<div id="square2"></div>
		</div>

А в style.css добавим стили для него:

#square2{
	position:absolute;
	width:1000px;
	height:1000px;
	top:400px;
	left:600px;
	background-color:#00FF00;
	transform:translate(-50%,-50%) rotateX(90deg) translateZ(-100px);
}

Теперь все четко. Ну… не совсем. Когда мы нажимаем по клавишам, мы движемся строго по осям X и Z. А мы хотим сделать движение по направлению взгляда. Сделаем следующее: в самом начале файла script.js добавим 2 переменные:

// Мировые константы

var pi = 3.141592;
var deg = pi/180;

Градус — это pi/180 от радиана. Нам придется применить синусы и косинусы, которые считаются от радиан. Что нужно сделать? Взгляните на рисунок:

Когда наш взгляд направлен под углом и мы хотим пойти вперед, то изменятся обе координаты: X и Z. В случае перемещения в сторону тригонометрические функции просто поменяются местами, а перед образовавшимся синусом изменится знак. Изменим уравнения смещений в update():

// Задаем локальные переменные смещения
	
	let dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
	let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);	
	let dy = -PressUp;
	let drx = MouseY;
	let dry = - MouseX;

Внимательно просмотрите все файлы полностью! Если у вас что-то оказалось не так, то потом обязательно буду ошибки, из-за которых вы сломаете голову!

index.html:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world">
			<div id="square1"></div>
			<div id="square2"></div>
		</div>
		<div id="pawn"></div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

style.css:

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
	perspective:600px;
	overflow:hidden;
}
#world{
	position:absolute;
	width:inherit;
	height:inherit;
	transform-style:preserve-3d;
}
#square1{
	position:absolute;
	width:200px;
	height:200px;
	top:400px;
	left:600px;
	background-color:#FF0000;
	transform:translate(-50%,-50%) rotateY(30deg);
}
#square2{
	position:absolute;
	width:1000px;
	height:1000px;
	top:400px;
	left:600px;
	background-color:#00FF00;
	transform:translate(-50%,-50%) rotateX(90deg) translateZ(-100px);
}
#pawn{
	display:none;
	position:absolute;
	top:400px;
	left:600px;
	transform:translate(-50%,-50%);
	width:100px;
	height:100px;
	background-color:#0000FF;
}

script.js:

// Мировые константы

var pi = 3.141592;
var deg = pi/180;

// Конструктор Pawn

function player(x,y,z,rx,ry) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.rx = rx;
	this.ry = ry;
}

// Нажата ли клавиша и двигается ли мышь?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;

// На земле ли игрок?

var onGround = true;

// Обработчик нажатия клавиш

document.addEventListener("keydown", (event) =>{
	if (event.key == "a"){
		PressLeft = 1;
	}
	if (event.key == "w"){
		PressForward = 1;
	}
	if (event.key == "d"){
		PressRight = 1;
	}
	if (event.key == "s"){
		PressBack = 1;
	}
	if (event.keyCode == 32 && onGround){
		PressUp = 1;
	}
});

// Обработчик отжатия клавиш

document.addEventListener("keyup", (event) =>{
	if (event.key == "a"){
		PressLeft = 0;
	}
	if (event.key == "w"){
		PressForward = 0;
	}
	if (event.key == "d"){
		PressRight = 0;
	}
	if (event.key == "s"){
		PressBack = 0;
	}
	if (event.keyCode == 32){
		PressUp = 0;
	}
});

// Обработчик движения мыши

document.addEventListener("mousemove", (event)=>{
	MouseX = event.movementX;
	MouseY = event.movementY;
});


// Создаем новый объект типа player

var pawn = new player(0,0,0,0,0);

// Привяжем новую переменную к world

var world = document.getElementById("world");

function update(){
	
	// Задаем локальные переменные смещения
	
	let dx = (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
	let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
	let dy = - PressUp;
	let drx = MouseY;
	let dry = - MouseX;
	
	// Обнулим смещения мыши:
	
	MouseX = MouseY = 0;
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	pawn.rx = pawn.rx + drx;
	pawn.ry = pawn.ry + dry;

	
	// Изменяем координаты мира (для отображения)
	
	world.style.transform = 
	"translateZ(600px)" +
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
	
};

TimerGame = setInterval(update,10);

С движением мы почти разобрались. Но осталось неудобство: курсор мыши может двигаться только в пределах экрана. В трехмерных шутерах можно вращать мышью сколь угодно долго и сколь угодно далеко. Сделаем также: при нажатии на экран игры (на “container”) курсор будет пропадать, и мы сможем вращать мышью без ограничений на размер экрана. Активируем захват мыши при нажатии на экран, для чего перед обработчиками нажатия клавиш поставим обработчик нажатия мыши на “container”:

// Привяжем новую переменную к container

var container = document.getElementById("container");

// Обработчик захвата курсора мыши

container.onclick = function(){
	container.requestPointerLock();
};

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

// Введен ли захват мыши?

var lock = false;

Добавим обработчик изменения состояния захвата курсора (захвачен или нет) перед обработчиком захвата курсора (извините за тавтологию):

// Обработчик изменения состояния захвата курсора

document.addEventListener("pointerlockchange", (event)=>{
	lock = !lock;
});

А в update() добавим условие вращения “pawn”:

// Если курсор захвачен, разрешаем вращение

	if (lock){
		pawn.rx = pawn.rx + drx;
		pawn.ry = pawn.ry + dry;
	};

А сам захват мыши при клике по контейнеру разрешим только тогда, когда курсор еще не захвачен:

// Обработчик захвата курсора мыши

container.onclick = function(){
	if (!lock) container.requestPointerLock();
};

С движением мы полностью разобрались. Перейдем к генерации мира

4. Загрузка карты

Мир в нашем случае удобнее всего представить в виде множества прямоугольников, имеющих разное местоположение, поворот, размеры и цвет. Вместо цвета также можно использовать текстуры. На самом деле, все современные трехмерные миры в играх – это набор треугольников и прямоугольников, которые называют полигонами. В крутых играх их количество может достигать десятков тысяч в одном только кадре. У нас же их будет около сотни, так как браузер сам по себе имеет невысокую графическую производительность. В предыдущих пунктах мы вставляли блоки “div” внутрь “world”. Но если таких блоков много (сотни), то вставлять каждый из них в контейнер очень утомительно. Да и уровней может быть много. Поэтому пусть эти прямоугольники вставляет javaScript, а не мы. Для него же мы будем создавать специальный массив.

Откроем index.html и удалим из блока “world” все внутренние блоки:

<BODY>
	<div id="container">
		<div id="world"></div>
		<div id="pawn"></div>
	</div>
</BODY>

Как видим, в “world” теперь ничего нет. В style.css удалим стили для #square1 и #square2 (вообще удалим #square1 и #square2 из этого файла), а вместо них создадим стили для класса .square, который будет общим для всех прямоугольников. Причем зададим для него только одно свойство:


.square{
	position:absolute;
}

Теперь создадим массив прямоугольников (запихнем его, примеру, между конструктором player и переменными press… в script.js):

// Массив прямоугольников

var map = [
		   [0,0,1000,0,180,0,2000,200,"#F0C0FF"],
		   [0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
		   [1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
		   [-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
		   [0,100,0,90,0,0,2000,2000,"#666666"]
]

Можно было это сделать в виде конструктора, но пока обойдемся чисто массивом, так как запуск цикла расстановки прямоугольников проще реализовать именно через массивы, а не через конструкторы. Я же поясню, что означают цифры в нем. Массив map содержит одномерные массивы из 9 переменных: [,,,,,,,,]. Я думаю, вы понимаете, что первые три числа – это координаты центра прямоугольника, вторые три числа – углы поворота в градусах (относительно того же центра), затем два числа – его размеры и последнее число – фон. Причем фон может быть сплошным цветом, градиентом или фотографией. Последнее очень удобно использовать в качестве текстур.

Массив мы записали, теперь запишем функцию, которая переделает этот массив в собственно прямоугольники:

function CreateNewWorld(){
	for (let i = 0; i < map.length; i++){
		
		// Создание прямоугольника и придание ему стилей
		
		let newElement = document.createElement("div");
		newElement.className = "square";
		newElement.id = "square" + i;
		newElement.style.width = map[i][6] + "px";
		newElement.style.height = map[i][7] + "px";
		newElement.style.background = map[i][8];
		newElement.style.transform = "translate3d(" +
                (600 - map[i][6]/2 + map[i][0]) + "px," +
		(400 - map[i][7]/2 + map[i][1]) + "px," +
		(map[i][2]) + "px)" +
		"rotateX(" + map[i][3] + "deg)" +
		"rotateY(" + map[i][4] + "deg)" +
		"rotateZ(" + map[i][5] + "deg)";
		
		// Вставка прямоугольника в world
		
		world.append(newElement);
	}
}

Поясню, что происходит: мы создаем новую переменную, которая указывает на только что созданный элемент. Ему мы присваиваем id и css-класс (именно это и имеется ввиду под словом класс в языке javaScript), задаем ширину с высотой, фон и трансформацию. Примечательно, что в трансформации помимо координат центра прямоугольника мы указываем смещение на 600 и 400 и половины размеров для того, чтобы центр прямоугольника точно оказался в точке с нужными координатами. Запустим генератор мира перед таймером:

CreateNewWorld();
TimerGame = setInterval(update,10);

Теперь мы видим площадку с розовыми стенами и серым полом. Как видите, создание карты технически несложно реализовать. А в результате ваш код в трех файлах должен получиться примерно таким:

index.html:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world"></div>
		<div id="pawn"></div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

style.css

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
	perspective:600px;
	overflow:hidden;
}
#world{
	position:absolute;
	width:inherit;
	height:inherit;
	transform-style:preserve-3d;
}
.square{
	position:absolute;
}
#pawn{
	display:none;
	position:absolute;
	top:400px;
	left:600px;
	transform:translate(-50%,-50%);
	width:100px;
	height:100px;
}

script.js:

// Мировые константы

var pi = 3.141592;
var deg = pi/180;

// Конструктор player

function player(x,y,z,rx,ry) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.rx = rx;
	this.ry = ry;
}

// Массив прямоугольников

var map = [
		   [0,0,1000,0,180,0,2000,200,"#F0C0FF"],
		   [0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
		   [1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
		   [-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
		   [0,100,0,90,0,0,2000,2000,"#666666"]
]

// Нажата ли клавиша и двигается ли мышь?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;

// Введен ли захват мыши?

var lock = false;

// На земле ли игрок?

var onGround = true;

// Привяжем новую переменную к container

var container = document.getElementById("container");

// Обработчик изменения состояния захвата курсора

document.addEventListener("pointerlockchange", (event)=>{
	lock = !lock;
});

// Обработчик захвата курсора мыши

container.onclick = function(){
	if (!lock) container.requestPointerLock();
};

// Обработчик нажатия клавиш

document.addEventListener("keydown", (event) =>{
	if (event.key == "a"){
		PressLeft = 1;
	}
	if (event.key == "w"){
		PressForward = 1;
	}
	if (event.key == "d"){
		PressRight = 1;
	}
	if (event.key == "s"){
		PressBack = 1;
	}
	if (event.keyCode == 32 && onGround){
		PressUp = 1;
	}
});

// Обработчик отжатия клавиш

document.addEventListener("keyup", (event) =>{
	if (event.key == "a"){
		PressLeft = 0;
	}
	if (event.key == "w"){
		PressForward = 0;
	}
	if (event.key == "d"){
		PressRight = 0;
	}
	if (event.key == "s"){
		PressBack = 0;
	}
	if (event.keyCode == 32){
		PressUp = 0;
	}
});

// Обработчик движения мыши

document.addEventListener("mousemove", (event)=>{
	MouseX = event.movementX;
	MouseY = event.movementY;
});

// Создаем новый объект

var pawn = new player(0,0,0,0,0);

// Привяжем новую переменную к world

var world = document.getElementById("world");

function update(){
	
	// Задаем локальные переменные смещения
	
	let dx =   (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
	let dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
	let dy = - PressUp;
	let drx = MouseY;
	let dry = - MouseX;
	
	// Обнулим смещения мыши:
	
	MouseX = MouseY = 0;
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	
	// Если курсор захвачен, разрешаем вращение
	
	if (lock){
		pawn.rx = pawn.rx + drx;
		pawn.ry = pawn.ry + dry;
	};

	// Изменяем координаты мира (для отображения)
	
	world.style.transform = 
	"translateZ(" + (600 - 0) + "px)" +
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
	
};

function CreateNewWorld(){
	for (let i = 0; i < map.length; i++){
		
		// Создание прямоугольника и придание ему стилей
		
		let newElement = document.createElement("div");
		newElement.className = "square";
		newElement.id = "square" + i;
		newElement.style.width = map[i][6] + "px";
		newElement.style.height = map[i][7] + "px";
		newElement.style.background = map[i][8];
		newElement.style.transform = "translate3d(" +
		(600 - map[i][6]/2 + map[i][0]) + "px," +
		(400 - map[i][7]/2 + map[i][1]) + "px," +
		                    (map[i][2]) + "px)" +
		"rotateX(" + map[i][3] + "deg)" +
		"rotateY(" + map[i][4] + "deg)" +
		"rotateZ(" + map[i][5] + "deg)";
		
		// Вставка прямоугольника в world
		
		world.append(newElement);
	}
}

CreateNewWorld();
TimerGame = setInterval(update,10);

Если все хорошо, переходим к следующему пункту.

5. Столкновения игрока с объектами мира

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

function collision(){
	
}

А вызывать ее будем в update():

// Обнулим смещения мыши:
	
	MouseX = MouseY = 0;
	
	// Проверяем коллизию с прямоугольниками
	
	collision();

Как это происходит? Представим себе, что игрок – это шар с радиусом r. И он движется в сторону прямоугольника:

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

function coorTransform(x0,y0,z0,rxc,ryc,rzc){
	let x1 =  x0;
	let y1 =  y0*Math.cos(rxc*deg) + z0*Math.sin(rxc*deg);
	let z1 = -y0*Math.sin(rxc*deg) + z0*Math.cos(rxc*deg);
	let x2 =  x1*Math.cos(ryc*deg) - z1*Math.sin(ryc*deg);
	let y2 =  y1;
	let z2 =  x1*Math.sin(ryc*deg) + z1*Math.cos(ryc*deg);
	let x3 =  x2*Math.cos(rzc*deg) + y2*Math.sin(rzc*deg);
 	let y3 = -x2*Math.sin(rzc*deg) + y2*Math.cos(rzc*deg);
	let z3 =  z2;
	return [x3,y3,z3];
}

И обратную функцию:

function coorReTransform (x3,y3,z3,rxc,ryc,rzc){
	let x2 =  x3*Math.cos(rzc*deg) - y3*Math.sin(rzc*deg);
	let y2 =  x3*Math.sin(rzc*deg) + y3*Math.cos(rzc*deg);
	let z2 =  z3
	let x1 =  x2*Math.cos(ryc*deg) + z2*Math.sin(ryc*deg);
	let y1 =  y2;
	let z1 = -x2*Math.sin(ryc*deg) + z2*Math.cos(ryc*deg);
	let x0 =  x1;
	let y0 =  y1*Math.cos(rxc*deg) - z1*Math.sin(rxc*deg);
	let z0 =  y1*Math.sin(rxc*deg) + z1*Math.cos(rxc*deg);
	return [x0,y0,z0];
}

Вставим эти функции после функции update(). Я не буду объяснять, как это работает, потому что мне не хочется рассказывать курс аналитической геометрии. Скажу, что есть такие формулы перевода координат при вращении и мы просто ими воспользовались. С точки зрения прямоугольника наш игрок расположен вот так:

В этом случае условие коллизии становится таким: если после смещения шара на величину v (v – это вектор) координата z между –r и r, а координаты x и y лежат в пределах прямоугольника или отстоят от него на величину, не большую r, то объявляется коллизия. В этом случае координата игрока по z после смещения будет составлять r или – r (в зависимости от того, с какой стороны придет игрок). В соответствии с этим, смещение игрока изменяется. Мы специально вызываем коллизию перед тем, как в update() координаты игрока будут обновлены, чтобы вовремя изменить смещение. Таким образом, шар никогда не пересечется с прямоугольником, как бывает в других алгоритмах коллизии. Хотя физически игрок будет представлять собой, скорее, случае куб, мы не будем обращать на это внимание. Итак, реализуем это в javaScript:

function collision(){
	for(let i = 0; i < map.length; i++){
		
		// рассчитываем координаты игрока в системе координат прямоугольника
		
		let x0 = (pawn.x - map[i][0]);
		let y0 = (pawn.y - map[i][1]);
		let z0 = (pawn.z - map[i][2]);
		
		let x1 = x0 + dx;
		let y1 = y0 + dy;
		let z1 = z0 + dz;
		
		let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
		let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
		let point2 = new Array();
		
		// Условие коллизии и действия при нем
		
		if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
			point1[2] = Math.sign(point0[2])*50;
			point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
			dx = point2[0] - x0;
			dy = point2[1] - y0;
			dz = point2[2] - z0;
		}
	};
}

x0,y0 и z0 – начальные координаты игрока в системе координат прямоугольника (без поворотов. x1,y1 и z1 – координаты игрока после смещения без учета коллизии. point0, point0, point1 и point2 – начальный радиус-вектор, радиус-вектор после смещения без коллизии и радиус-вектор с коллизией соответственно. map[i][3] и другие, если вы помните, это углы поворота прямоугольника. Заметим, что в условии мы к размерам прямоугольника прибавляем не 100, а 98. Это костыль, зачем, подумайте сами. Запустите игру и вы увидите довольно качественные столкновения.

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


if ((x0**2 + y0**2 + z0**2 + dx**2 + dy**2 + dz**2) < (map[i][1]**2 + map[i][2]**2)){
		
			let x1 = x0 + dx;
			let y1 = y0 + dy;
			let z1 = z0 + dz;
		
			let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
			let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
			let point2 = new Array();
		
			// Условие коллизии и действия при нем
		
			if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
				point1[2] = Math.sign(point0[2])*50;
				point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
				dx = point2[0] - x0;
				dy = point2[1] - y0;
				dz = point2[2] - z0;
			}
			
		} 

Итак, с коллизиями мы разобрались. Мы спокойно можем взбираться и по наклонным поверхностям, а возникновение багов возможно только на медленных системах, если, конечно, возможно. По сути, вся основная техническая часть на этом закончилась. Нам осталось лишь добавить частные вещи, такие как гравитация, вещи, меню, звуки, красивую графику. Но это достаточно легко сделать, а к самому движку, который мы только что сделали, это отношения не имеет. Поэтому об этом я расскажу в следующей части. А сейчас проверьте то, что у вас получилось с моим кодом:

index.html:

<!DOCTYPE HTML>
<HTML>
<HEAD>
	<TITLE>Игра</TITLE>
	<LINK rel="stylesheet" href="style.css">
	<meta charset="utf-8">
</HEAD>
<BODY>
	<div id="container">
		<div id="world"></div>
		<div id="pawn"></div>
	</div>
</BODY>
</HTML>
<script src="script.js"></script>

style.css

#container{
	position:absolute;
	width:1200px;
	height:800px;
	border:2px solid #000000;
	perspective:600px;
	overflow:hidden;
}
#world{
	position:absolute;
	width:inherit;
	height:inherit;
	transform-style:preserve-3d;
}
.square{
	position:absolute;
}
#pawn{
	display:none;
	position:absolute;
	top:400px;
	left:600px;
	transform:translate(-50%,-50%);
	width:100px;
	height:100px;
}

script.js:

// Мировые константы

var pi = 3.141592;
var deg = pi/180;

// Конструктор player

function player(x,y,z,rx,ry) {
	this.x = x;
	this.y = y;
	this.z = z;
	this.rx = rx;
	this.ry = ry;
}

// Массив прямоугольников

var map = [
		   [0,0,1000,0,180,0,2000,200,"#F0C0FF"],
		   [0,0,-1000,0,0,0,2000,200,"#F0C0FF"],
		   [1000,0,0,0,-90,0,2000,200,"#F0C0FF"],
		   [-1000,0,0,0,90,0,2000,200,"#F0C0FF"],
		   [0,100,0,90,0,0,2000,2000,"#666666"]
];

// Нажата ли клавиша и двигается ли мышь?

var PressBack = 0;
var PressForward = 0;
var PressLeft = 0;
var PressRight = 0;
var PressUp = 0;
var MouseX = 0;
var MouseY = 0;

// Введен ли захват мыши?

var lock = false;

// На земле ли игрок?

var onGround = true;

// Привяжем новую переменную к container

var container = document.getElementById("container");

// Обработчик изменения состояния захвата курсора

document.addEventListener("pointerlockchange", (event)=>{
	lock = !lock;
});

// Обработчик захвата курсора мыши

container.onclick = function(){
	if (!lock) container.requestPointerLock();
};

// Обработчик нажатия клавиш

document.addEventListener("keydown", (event) =>{
	if (event.key == "a"){
		PressLeft = 1;
	}
	if (event.key == "w"){
		PressForward = 1;
	}
	if (event.key == "d"){
		PressRight = 1;
	}
	if (event.key == "s"){
		PressBack = 1;
	}
	if (event.keyCode == 32 && onGround){
		PressUp = 1;
	}
});

// Обработчик отжатия клавиш

document.addEventListener("keyup", (event) =>{
	if (event.key == "a"){
		PressLeft = 0;
	}
	if (event.key == "w"){
		PressForward = 0;
	}
	if (event.key == "d"){
		PressRight = 0;
	}
	if (event.key == "s"){
		PressBack = 0;
	}
	if (event.keyCode == 32){
		PressUp = 0;
	}
});

// Обработчик движения мыши

document.addEventListener("mousemove", (event)=>{
	MouseX = event.movementX;
	MouseY = event.movementY;
});

// Создаем новый объект

var pawn = new player(-900,0,-900,0,0);

// Привяжем новую переменную к world

var world = document.getElementById("world");

function update(){
	
	// Задаем локальные переменные смещения
	
	dx =   (PressRight - PressLeft)*Math.cos(pawn.ry*deg) - (PressForward - PressBack)*Math.sin(pawn.ry*deg);
	dz = - (PressForward - PressBack)*Math.cos(pawn.ry*deg) - (PressRight - PressLeft)*Math.sin(pawn.ry*deg);
	dy = - PressUp;
	drx = MouseY;
	dry = - MouseX;
	
	// Обнулим смещения мыши:
	
	MouseX = MouseY = 0;
	
	// Проверяем коллизию с прямоугольниками
	
	collision();
	
	// Прибавляем смещения к координатам
	
	pawn.x = pawn.x + dx;
	pawn.y = pawn.y + dy;
	pawn.z = pawn.z + dz;
	console.log(pawn.x + ":" + pawn.y + ":" + pawn.z);
	
	// Если курсор захвачен, разрешаем вращение
	
	if (lock){
		pawn.rx = pawn.rx + drx;
		pawn.ry = pawn.ry + dry;
	};

	// Изменяем координаты мира (для отображения)
	
	world.style.transform = 
	"translateZ(" + (600 - 0) + "px)" +
	"rotateX(" + (-pawn.rx) + "deg)" +
	"rotateY(" + (-pawn.ry) + "deg)" +
	"translate3d(" + (-pawn.x) + "px," + (-pawn.y) + "px," + (-pawn.z) + "px)";
	
};

function CreateNewWorld(){
	for (let i = 0; i < map.length; i++){
		
		// Создание прямоугольника и придание ему стилей
		
		let newElement = document.createElement("div");
		newElement.className = "square";
		newElement.id = "square" + i;
		newElement.style.width = map[i][6] + "px";
		newElement.style.height = map[i][7] + "px";
		newElement.style.background = map[i][8];
		newElement.style.transform = "translate3d(" +
		(600 - map[i][6]/2 + map[i][0]) + "px," +
		(400 - map[i][7]/2 + map[i][1]) + "px," +
		(map[i][2]) + "px)" +
		"rotateX(" + map[i][3] + "deg)" +
		"rotateY(" + map[i][4] + "deg)" +
		"rotateZ(" + map[i][5] + "deg)";
		
		// Вставка прямоугольника в world
		
		world.append(newElement);
	}
}

function collision(){
	for(let i = 0; i < map.length; i++){
		
		// рассчитываем координаты игрока в системе координат прямоугольника
		
		let x0 = (pawn.x - map[i][0]);
		let y0 = (pawn.y - map[i][1]);
		let z0 = (pawn.z - map[i][2]);
		
		if ((x0**2 + y0**2 + z0**2 + dx**2 + dy**2 + dz**2) < (map[i][6]**2 + map[i][7]**2)){
		
			let x1 = x0 + dx;
			let y1 = y0 + dy;
			let z1 = z0 + dz;
		
			let point0 = coorTransform(x0,y0,z0,map[i][3],map[i][4],map[i][5]);
			let point1 = coorTransform(x1,y1,z1,map[i][3],map[i][4],map[i][5]);
			let point2 = new Array();
		
			// Условие коллизии и действия при нем
		
			if (Math.abs(point1[0])<(map[i][6]+98)/2 && Math.abs(point1[1])<(map[i][7]+98)/2 && Math.abs(point1[2]) < 50){
				point1[2] = Math.sign(point0[2])*50;
				point2 = coorReTransform(point1[0],point1[1],point1[2],map[i][3],map[i][4],map[i][5]);
				dx = point2[0] - x0;
				dy = point2[1] - y0;
				dz = point2[2] - z0;
			}
			
		}
	};
}

function coorTransform(x0,y0,z0,rxc,ryc,rzc){
	let x1 =  x0;
	let y1 =  y0*Math.cos(rxc*deg) + z0*Math.sin(rxc*deg);
	let z1 = -y0*Math.sin(rxc*deg) + z0*Math.cos(rxc*deg);
	let x2 =  x1*Math.cos(ryc*deg) - z1*Math.sin(ryc*deg);
	let y2 =  y1;
	let z2 =  x1*Math.sin(ryc*deg) + z1*Math.cos(ryc*deg);
	let x3 =  x2*Math.cos(rzc*deg) + y2*Math.sin(rzc*deg);
 	let y3 = -x2*Math.sin(rzc*deg) + y2*Math.cos(rzc*deg);
	let z3 =  z2;
	return [x3,y3,z3];
}

function coorReTransform(x3,y3,z3,rxc,ryc,rzc){
	let x2 =  x3*Math.cos(rzc*deg) - y3*Math.sin(rzc*deg);
	let y2 =  x3*Math.sin(rzc*deg) + y3*Math.cos(rzc*deg);
	let z2 =  z3
	let x1 =  x2*Math.cos(ryc*deg) + z2*Math.sin(ryc*deg);
	let y1 =  y2;
	let z1 = -x2*Math.sin(ryc*deg) + z2*Math.cos(ryc*deg);
	let x0 =  x1;
	let y0 =  y1*Math.cos(rxc*deg) - z1*Math.sin(rxc*deg);
	let z0 =  y1*Math.sin(rxc*deg) + z1*Math.cos(rxc*deg);
	return [x0,y0,z0];
}

CreateNewWorld();
TimerGame = setInterval(update,10);

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

Super Mario Maker 2

Super Mario Maker 2 — конструктор уровней игр серии Super Mario для платформы Nintendo Switch. Возможна разработка в 2D и 3D. Механизм прост: за основу вы берете классическую игру, открываете набор инструментов, и начинаете проектировать головоломки, внедрять боссов, усложнять уровни, придумывать препятствия, разбрасывать монеты, прорабатывать дизайн и выполнять любые другие доступные действия. В конечном итоге вы можете получить абсолютно видоизмененную игру, которая похожа на оригинал только одной механикой.

Также за основу вы можете брать разные уровни и разные платформы.

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

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

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

Был резонансный случай, связанный с этим конструктором: фанат игровой серии создал неофициальное продолжение игры, состоящее из 40 уровней в 8 мирах. Продолжением заинтересовались студии разработчиков и фанаты игры. Всего в неофициальную версию сыграло более 55 000 людей.

VCS Game Maker

Простенький онлайн-конструктор, в котором без кода и навыков программирования можно разработать игру для приставки Atari 2600. Установлена блочная система управления — основную часть разработки вы будете работать именно с блоками. Далее предстоит сгененрировать исходных код Batari Basic. Дальше остается создать ROM-файл путем компиляции. Готовую игру можно запустить либо на оригинальной приставке, либо на соответствующем эмуляторе.

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

Wicked Engine

Многофункциональный, и, главное, бесплатный движок с лицензией MIT, созданный для разработок 3D-игр. В отличие от более простых движков, Wicked Engine рассчитан на полноценные игры, а не на казуальные проекты. Для создания сложных игровых проектов потребуются продвинутые навыки программирования, однако, в инструментарий включены простые функции, благодаря которым можно разрабатывать 3D-модели объектов и выполнять простые задания для их дальнейшего переноса в другие проекты. Интерфейс доступен на русском и английском языках.

Взгляните на скриншоты — эти игры были созданы на движке Wicked Engine:

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

Levelhead: Platformer Maker

Платформа для редактирования уровней одной конкретной игры, которая работает на ПК, консолях и мобильных ОС. Даже не имея никаких навыков программирования и разработки, вы сможете строить уровни и готовить испытания для главного героя игры.

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

Java Universal Role Playing Engine (J.U.R.P.E.)

Простой конструктор для создания ролевых игр с открытым кодом. Функционал примитивный и рассчитан на ретро-игры в стиле RPG и Quest. Вы можете создавать карты маршрутов, прописывать характеристики персонажей, продумывать тексты диалогов и их логику, настраивать события, кланы, фракции, взаимодействие между персонажами и так далее.

Поскольку движок простой в функционале, люди, разрабатывающие игры на нем, делают акцент на мощный сюжет и развитые отношения между персонажами. Игры, разработанные на J.U.R.P.E. оценят любители текстовых жанров и владельцы слабых устройств.

Mosi

Примитивный конструктор для создания элементарных 2D-игр. Бесплатная лицензия, открытый исходный код, интерфейс на английском языке. Игры здесь разрабатываются на уровне старых Nokia 2000-х годов. Тем не менее, если вы хотите попробовать свои силы в элементарной разработке игр, чтобы понять, желаете ли вы дальше развиваться в этом направлении, попробовать Mosi стоит.

Работает программа прямо в браузере. Интерфейс выглядит так:

Sok-stories

Еще один простой конструктор 2D-игр, с помощью которого можно создавать мультипликационные игры в жанре квест, RPG, приключение. Создавать мини-игры можно прямо в браузере. Однако, исходный код не предоставляется, а лицензия на него платная.

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

Flickgame

Онлайн-конструктор для создания простых игр и даже презентаций. Конструктор доступен в браузере, для разработки не требуются языки программирования. Лицензия бесплатная, исходный код предоставляется. Подойдет для квестовых и ролевых игр, а также для простых развивающих детских проектов и игр.

Также во Flickgame можно делать прикольные рисунки и забавные презентации, например для детских утренников.

Dreams

Мощный конструктор игр для консолей семейства Sony Play Station. Один из немногих конструкторов, в котором можно не только создавать полноценные игры любых жанров, но и элементы графики. То есть вы можете рисовать объекты, создавать уникальные музыкальные композиции и даже делать ремиксы. Предусмотрена работа с 3D-графикой.

Хоть для использования базовых возможностей конструктора Dream не требуются навыки программирования, совсем без них не обойтись. Оптимальный вариант использования конструктора — командная работа в связке с профильными специалистами.

Проекты, созданные в Dream, получаются увлекательными и комфортными в управлении.

Adventuron Classroom

Конструктор для создания казуальных игр, основа которых — работа с текстом. Следовательно, подойдет Adventuron Classroom в большей степени для приключений, квестов и RPG. Язык интерфейса на английском, лицензия бесплатная, создать свою игру можно без специальных навыков. Конструктор доступен прямо в браузере.

RPGWizard

Бесплатный конструктор на JavaScript, на котором можно создавать RPG-игры в 2D с открытым исходным кодом. Интерфейс на английском, для запуска программы необходимо скачать файл на ПК. Позволяет создавать простые игры в стилизации 2000-х годов. Учитывая слабую графику и ключевые возможности, но при этом развитую систему создания вещей, предметов и заданий, идеально подойдет для разработки ролевых игр с дальнейшей их адаптацией под мобильные устройства. Разобраться можно вручную, знание языков программирования не требуется.

CYOA Factory

Конструктор с бесплатной лицензией, который дает возможность создавать текстовые игры, интерактивные книги и квесты. Возможна разработка историй с разными концовками и нелинейными сюжетами. То есть, другими словами, можно сделать так, чтобы в зависимости от действий игрока сюжет развивался по-разному и вел к разным финалам. Для начала работы нужно скачать программу на ПК (поддерживается Windows и Linux) или на смартфон на базе Android.

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

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

Заключение

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

Материал написан редакцией Traffic Cardinal — это медиа о маркетинге, арбитраже трафика и заработке в Интернете. Подписывайтесь на наш Телеграм, чтобы быть в курсе актуальных новостей манимейкинга!

Бродилка — жанр приключенческих компьютерных игр, герой которых перемещается по неизвестной местности для нахождения какого-либо объекта. Пожалуй, бродилки — это вечнозеленый жанр со времен Acornsoft Labyrinth (и тому подобного). На любом игровом портале или том же Google Play сотни такого рода игр. Учитывая популярность и востребованность жанра, у многих возникает вопрос — как создать свою игру

Существуют десятки движков разного уровня сложности (Unity, Unreal Engine и так далее). В этой статье продемонстрирую функционал игрового движка Gamefroot с базовым набором возможностей. Его плюсом является возможность «клепать» игры прямо в браузере без установки софта на диск. Результат можно проверить там же, запустив предпросмотр.

Как создать собственную игру-бродилку

Основные инструменты Gamefroot

После создания аккаунта вам доступна контрольная панель (Dashboard), где вы можете создать игру с чистого листа или оценить возможности платформы, выбрав Game Kits — готовые игровые наборы, либо Tutorial Games — учебные игры.

GamefrootНапример, выбираем Maia the Brave и попадаем в заготовку лесной бродилки с персонажем-девушкой. Выглядит неплохо, правда?

Возможностей графики хватает для создания приличных бродилок. В левой части экрана имеются различные объекты, которые можем добавлять в игру простым перетаскиванием. Имеются три раздела Media, Code и Levels — отвечающие за объекты, код игры и ее уровни — естественно, можно делать многоуровневую бродилку со сложной логикой и скриптами. Кроме того, имеется маркетплейс — страница, где можно приобретать (Premium) или скачивать бесплатно (Free) разнообразные наборы предметов для игры и тому подобное. Это очень облегчает создание игры. Собственных персонажей можно создавать при помощи кнопки Character Creator, постепенно «собирая» их.

Character CreatorВ середине находится игровой экран, а также карта всего «царства» (уровня), масштаб которого можно менять кнопками — и +.

Справа расположено окно, в котором платформа предоставляет возможность работать со слоями (Layers), создавать достаточно сложную логику поведения объектов — это реализовано при нажатии на них правой кнопкой. Для удобства окно Layers можно перетащить в любое место экрана, если оно закрывает какую-то нужную в данный момент часть.

Посмотрим, как работает слой с главным персонажем. Для этого выберем строку «Player», и вокруг девушки возникнет синий прямоугольник. С помощью него ее можно менять в размерах, вращать, перемещать.

Player Gamefroot

Gamefroot Editor

Gamefroot Pickup Dog Bait

Gamefroot Своя Игра

Gamefroot Character StudioДалее мы видим слой Park objects, к которому относятся объекты парка — в данном случае это деревья. Их также можно двигать и модифицировать. Ниже находится слой Collectibles, самый вожделенный для любителей игр. В него можно добавлять те самые предметы, которые требуется собирать: монеты, шоколадки, одним словом, клад (gem). В левой части экрана есть выбор из 6 таких предметов. Они имеют статус pre-scripted asset — то есть предмет, имеющий заданное скриптом заранее поведение. 

Следующий слой Non-Player — это другие персонажи, не относящиеся к главному. Здесь это некоторые животные. Их тоже можно перетащить на основной экран и добавить в игру. Например, это Dr. Peck — птичка в стиле Angry Birds, расхаживающая туда-сюда. Выглядит это просто потрясающе, в лучших традициях бродилок. Что особенно приятно, процесс расхаживания птички можно редактировать в редакторе анимации Animation Editor, управляя ей покадрово. Для этого надо нажать на птичку правой кнопкой и выбрать Dr. Peck -> View Animation. А при контакте девушки с птичкой появляется сообщение, либо можно запрограммировать другую логику на ваш вкус. Также есть слои с водоемами (Water), дорожками (Paths) и насаждениями (Hedges). Их можно включать или отключать, по аналогии с Adobe Photoshop.

Слой Background отвечает за фон игры. Также важным моментом является добавление нового слоя. Это можно сделать, нажав плюсик справа от надписи Layers. На выбор будет два варианта: New Layer (добавление нового слоя) и New Tile Map (добавление сетки для выравнивания элементов). Последнее требуется для того, чтобы расположить элементы ровно по сетке.

Проверить, как работает игра в режиме предпросмотра можно, нажав кнопку Play. Разрешение игры меняется в разделе Game Settings. По умолчанию это 960×540. А общий размер игрового мира находится в разделе Levels, по умолчанию это 2800×2880, довольно масштабная бродилочка.

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

Платформа имеет свое сообщество и учебные руководства. Правда, интерфейс пока на английском языке и русскоязычный не предусмотрен. Gamefroot позволяет сохранять и публиковать проекты онлайн, в PRO-версии возможно скачать все файлы игры.

С помощью Gamefroot можно встроить игру на собственный сайт, предоставляется embed-код. Получится вот такая игра (на третьем слайде нажмите Play):

Читайте также

Лучшие игры для iOS

Лучшие бесплатные игры

10 альтернативных игровых движков

Платформа Gamefroot имеет определенные ограничения. Если вам захочется окунуться в более сложную разработку, также советую обратить внимание на следующие платформы:

  • Construct 3. Браузерный кросс-платформенный визуальный движок разработки игр.
  • Game Maker: Studio. Позволяет писать расширения под множество платформ на соответствующих им языках.
  • Unity. Одна из самых известных платформ. Позволяет создавать 3D-игры. Основными преимуществами Unity являются наличие визуальной среды разработки, межплатформенной поддержки и модульной системы компонентов. К недостаткам относят появление сложностей при работе с многокомпонентными схемами и затруднения при подключении внешних библиотек.
  • GDevelop. Open-source браузерный кросс-платформенный визуальный движок разработки игр, также есть версия для скачивания 
  • GameSalad. Движок с платной подпиской (абонентской платой), позволяющий создавать игры для Android, iOS и на HTML5. Приложение основано на принципе Drag-and-drop специально для людей, не знающих программирование.
  • Buildbox. Скачиваемая платформа для разработки мобильных игр, есть бесплатная и платная версии, различающиеся функционалом. Знание программирования не требуется.
  • Godot Engine. Мощный открытый кроссплатформенный 2D и 3D игровой движок под лицензией MIT. Игра создаётся с использованием собственного высокоуровневого динамически типизированного скриптового языка программирования под названием GDScript, синтаксис которого напоминает язык Python.
  • Unreal Engine. Мощнейший всемирно известный трехмерный движок. Написанный на языке C++, движок позволяет создавать игры для большинства операционных систем и платформ. Со 2 марта 2015 года Unreal Engine 4 стал бесплатным. Разработчики игр должны передавать 5% от выручки с продаж игры компании Epic Games, если ежеквартальная выручка превышает $3000.
  • Panda3D. Движок малоизвестный, разработан компанией «Дисней» и в последствии передан университету CMU и сообществу. Движок написан на языке C++ и небольшая его часть — на Python. Panda3D спроектирован таким образом, чтобы разработка проектов с его использованием велась на языке Python в большей степени, а также на языке C++.
  • Stencyl. Скачиваемый кроссплатформенный конструктор игр. Stencyl работает в интеграции с онлайновым магазином компонентов игр StencylForge и сайтом Stencyl.com. На сайте расположены учебные материалы, форумы пользователей конструктора и опубликованные ими игры. Позволяет создавать игры для платформ iOS, Android, настольных компьютеров под управлением Windows, Linux и Mac OS, а также игр в формате Adobe Flash и HTML 5. Есть бесплатная и платные версии с расширенными возможностями.

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

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

На самом деле создать браузерную онлайн игру может любой, у кого есть желание учиться, но не думайте, что вас ждет легкая прогулка. Даже если вы мастер на все руки (программист и дизайнер в одном флаконе), то придется потратить уйму времени. Если же вы не владеете ни кодом, ни карандашом, то затраты будут финансовыми.

Как создать браузерную игру ничего не изучая?

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

Для создания браузерной игры придется выучить HTML, CSS, PHP и JavaScript, так что бессонные ночи вам гарантированы

Язык программирования PHP нужен для создания движка игры. Он используется на сервере для обработки данных, поступающих от разных геймеров. Это – ядро, которое приводит в действие все внутренние механизмы.

Я не хочу ничего учить, но у меня есть деньги

Поздравляем, вы избежали многих проблем. И тут же получили новые. Чтобы сделать браузерную игру хорошего качества (в плохую никто играть не будет) нужно иметь хорошую команду разработчиков, а хорошие спецы стоят денег. Если брать по минимуму, то вам необходимы:

  • Программист – 2 штуки
  • Дизайнер и художник – 2 штуки
  • Гейм-дизайнер – 1 штука
  • Комьюнити-менеджер – 1 штука
  • Гейм-мастер – 1 штука.

Если у вас нет личных знакомств, то придется обращаться к аутсорсингу. Обычно такие ребята трутся на биржах фрилансеров, самой популярной их которых является www.fl.ru/.

Всех необходимых работников можно найти на биржах фрилансеров

Правда, в этом случае нужно быть очень осторожным, поскольку фрилансеры привыкли регулярно срывать сроки. Как говорят опытные руководители, можно бесконечно смотреть на 3 вещи: как течет память, как горит дедлайн и как не работает фрилансер.

Во сколько обойдется разработка?

Во столько, сколько у вас есть денег. Вот здесь приведены примерные выкладки и структура расходов на создание среднестатистической браузерки. Итоговая сумма – 25 миллионов рублей. Однако не стоит пугаться этой цифры. В статье автор посчитал расходы на разработку по максимуму, так что при желании эту сумму модно уменьшить в разы и даже десятки раз. Или увеличить, если ваш папа – прокурор. Безусловно, такие проекты, как Drakensang Online или City of Steam требуют сумм как минимум с шестью нулями, но простую табличную браузерку можно сделать за пару десятков тысяч рублей.

В конце концов, вы всегда можете обратиться к краудфандингу. Пути Кикстартера неисповедимы, взлететь там может любой проект. Главное правильно подать блюдо.

Этапы разработки

Создание браузерной игры с нуля можно разделить на несколько этапов:

1. Поиск идеи

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

2. Разработка сюжета

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

3. Создание игры

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

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

4. Продвижение проекта

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

Как создать браузерную игру с помощью конструктора

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

Популярный игровой конструктор Construct 2

Большой популярностью пользуется MMO Constructor – отечественный продукт, в котором можно создать все элементы полноценной браузерной RPG. Взамен авторы требуют совсем ничего – 50% от прибыли проекта. Разобраться в конструкторе непросто, но добрые люди уже написали гайды. Также чтобы создать браузерную игру, можно воспользоваться такими программами, как Construct Classic, Eclipse, FPS Creator.

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

Так что там насчет миллиона?

Любая, даже мобильная игра должна приносить прибыль. Иначе нет никакого смысла тратить свое и чужое время. Дабы сделать свой проект финансово успешным, нужно слушать, что говорят опытные разработчики и делать то же самое:

  • Не жадничайте! Более 80% игроков вообще не платят, либо платят копейки. Однако они создают массовку, на которую подтягивается крупная рыба. Сконцентрируйтесь на ней. Остальным дайте возможность резвиться бесплатно.
  • Постарайтесь сделать так, чтобы донаторы не сильно выделялись из общей массы, иначе масса уйдет, оставив вас без донаторов и без денег. В общем, бряцайте мускулами аккуратно.
  • Лучше всего тратят деньги те, кто не хочет тратить свое время, поэтому монетизируйте наиболее рутинные операции. Не разменивайтесь по мелочам.
  • Уроки истории создания игр показывают, то онлайн-проект должен быть бесконечным. Если у геймера появится чувство, что ему нечего делать — он уйдет, а туда, где нет онлайна, новый геймер не придет никогда.

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

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

  • Движки для создания браузерных игр
  • Раздел «Разработка игр» на бирже фриланса
  • Список движков на HTML 5
  • Игровой движок Unity

Понравилась статья? Поделить с друзьями:
  • Как найти фирму по инн узбекистан
  • Глубокий прикус лицо как его исправить
  • Как найти инвестора список
  • Как найти автосервис по ремонту авто
  • Гта 5 как найти ленни эйвери