Как сделать 3д игру на java

Добавил пользователь Евгений Кузнецов
Обновлено: 19.09.2024

Любите ли вы играть? А создавать игры? Даже если раньше не пробовали, никогда не поздно начать! Тем более, написать свою собственную игру теперь можно всего за час. А если понравится быть не игроком, а творцом, новое умение можно превратить в полноценную профессию. Как? Сейчас расскажем!

Змейка или Тетрис - какая вам ближе?

IT-портал GeekBrains запустил новый проект - серию вебинаров по созданию несложных игр на языке Java.

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

На вебинарах подробно рассказывается о создании таких игр, как Conway'sGameofLife, Snake, Тетрис, SpaceInvaders, и полностью раскрывается процесс написания кода. Если же что-то не получилось или вам интересно увидеть “официальный” вариант кода, - все файлы для игры можно скачать со страницы с описанием вебинара.

Сейчас для просмотра доступны четыре вебинара, посвященных теплым ламповым играм 80-х годов. То, во что вы самозабвенно рубились когда-то на приставке или Nokia 3310, теперь можете создать сами!

Snake (“змейка”)

“Тетрис”

Space Invaders

Conway

А дальше что?

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

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

Всё, свершилось. Созрел для Явы. Чтобы процесс обучения шёл интереснее, буду писать игру. К большому для себя интересу обнаружил, что без определённого скилла шаманства всё получается не так как надо. Посему решил для начала набросать игровой движок, определить его возможности и уже на него "вешать" игру.

Раз игра, значит будет графика. Для рисования окон в Java предусмотрено много возможностей. Я пока буду ориентироваться только на встроенные возможности - никаких сторонних библиотек. А значит, выбор стоит между объектами библиотек AWT и Swing. Они лучше всего задокументированы и обкатаны. Впоследствии, может быть, рассмотрю другие библиотеки тоже. Пока о различиях между ними заострять внимание не буду. Просто скажу, что Swing современнее и предоставляет программисту больше возможностей - будем ориентироваться сразу на него.

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

Компиляция и запуск кода.
1. Устанавливаем JDK, отыскиваем в нём папку BIN. У меня это C:\Program Files\Java\jdk1.7.0_72\bin.
2.Там создаём файл Game.java, копируем код.
3.Далее две команды:
javac Game.java
java Game

Команды проще вводить, используя файловые менеджеры вроде Far Manager или Total Commander. Первая компилирует код, вторая запускает.

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

Что делает этот код?
Он строит окно.
Это минимальный код для средств Swing. Давайте посмотрим, что он делает.

1. Строки import подключают необходимые нам классы.
- javax.swing.*; - берём все классы Swing, они находятся в пакете javax.
- import java.awt.*; - аналогично подключаем все классы библиотеки AWT. Теперь вопрос - зачем нам эта устаревшая библиотека? А затем, что Swing построен на базе AWT. Да, в этой библиотеке решили главные недостатки предшественницы, но полностью заменить не вышло.

2. public class Game < >
Язык Java весь заморочен на классах и объектах. В языках Бейсик, Паскаль, Си классов нет, и маленькие программы в них пишутся достаточно быстро. Даже в Delphi новички часто не задумываются о классах и объектах. Кидают на форму кнопку, потом обрабатывают клик по ней, получая нужный результат. Просто и удобно. А попробуйте написать большую игру? С разрастанием кода программирование превращается в блуждание по тёмному лесу. Начинают появляться ошибки, которые очень трудно отловить, или задачи, которые не удаётся решить.

В программах Java даже если нет такой нужды - всегда создаётся минимум один класс.

Классы и объекты на самом деле сильно упрощают разработку серьёзных программ. В приведённом выше коде создаётся класс Game. "public" - это "видимость" класса, в нашем случае - он виден везде. Открывающаяся и закрывающаяся фигурные скобки формируют блок, это "тело" класса. Если класс пустой, код сократится до следующего: public class Game <>.

3. public static void main(String[] args) Заметили, перед этой строчкой есть пара пробелов? Они добавлены для наглядности. Если используется несколько вложенных блоков - такая разметка позволяет легче понимать код и проставлять закрывающиеся фигурные скобки.

Метод main, принимающий параметры String[] args всегда должен присутствовать в программе, с него начинается выполнение. Он пишется только так, поэтому надо просто запомнить. В его блоке поместим исполняемый код:

4. JFrame game = new JFrame("Game");
Создаём объект с именем "game". Объект game является экземпляром класса JFrame. Что это значит? Чтобы упростить жизнь программиста в Java описано множество разнообразных классов. Класс это своего рода образец, трафарет, форма, на основе которой создаётся объект. Объект получает от класса все свойства, методы и другие характеристики, то есть, имея в качестве образца класс, можно наплодить на его основе сколько угодно объектов, не описывая каждый из них в отдельности. Удобно, а?

В нашем случае на базе класса JFrame создаётся объект, который представляет собой "физическую" реализацию класса JFrame. А это окно с рамкой и строкой заголовка, то есть, то, что нам было нужно. В строке заголовка, кстати, будет написано слово "Game".

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

5. game.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Наше окно ещё надо настроить. Придать ему индивидуальность. Например, окну можно поменять имя. Но в этом пока нет надобности, нам бы просто запустить его.
Приведённый выше код модифицирует объект game следующим образом: при закрытии окна выполнение программы прекращается. Эта строка необходима. Идём далее.

6. game.setSize(640, 480);
Задаём размеры окна: ширина=640, высота=480. Если этого не сделать - размер окна будет 0x0, нас это не устраивает.

7. game.setVisible(true);
После настройки окна его нужно отобразить, верно?

Часть вторая. Рисование.

Логично было бы предположить, что рисование будет тоже в методе main. Код будет выглядеть примерно так:
game.fillRoundRect(320, 240, 10, 10, 5, 5);
Увы, всё несколько сложнее. Необходимо получить графический контекст нужного нам объекта. Что это такое - не спрашивайте, пока не сформулирую. Надо получить - думаем как.
Получить графический контекст можно во встроенном методе paint. А для этого надо создать свой класс, имеющий все характеристики JFrame, переопределив в нём метод paint. Давайте модифицируем наш код.

public class Game extends JFrame public void paint(Graphics g) g.fillRoundRect(320, 240, 10, 10, 5, 5);
>

1. Слова "extends JFrame" для тех, кто знает английский в объяснениях не нуждаются. Мы расширяем класс JFrame - наследуем все его характеристики, меняя нужные нам. Наследование - один из трёх китов ООП - Объектно Ориентированного Программирования. Только что мы научились этому!!
2. public void paint(Graphics g)
Переопределяем встроенный класс paint. Переменная "g" типа "Graphics" и есть необходимый графический контекст.
3. g.fillRoundRect(320, 240, 10, 10, 5, 5);
На нём мы и рисуем прямоугольник с закруглёнными краями. Числа по порядку: Координаты левого верхнего угла прямоугольника, затем ширина и высота, затем радиусы скругления углов. У меня он рисуется корявым, тут дело в сглаживании, пока сделаю вид, что такой прямоугольник мне нравится.

Но этого недостаточно.

Нам надо создать экземпляр только что созданного класса Game.
Game game = new Game();
Обратите внимание на все эти "game" с большой и маленькой буквы. Регистр буквы имеет значение. В этой строке мы создаём экземпляр класса Game, он описан выше. Ссылаться на него будет переменная game, то есть мы будем работать не с классом Game а с его конкретной реализацией - объектом game. Результат ниже:


Данный код работает, но в сети я не видел, чтобы кто-то рисовал прямо на окне. Обычно для этих целей используются производные от класса JPanel. Почему так делается? Некоторые ответы нашёл, но экспериментировать не хочу. Скажем так. JFrame спроектирован для отображения окна, а вот JPanel для всего остального. Например, на него можно набросать много различных визуальных компонентов и сгруппировать их нужным образом. И наверно логично разделить работу кода, отвечающего за окна от остального кода.

В это коде класс Game наследуется от JPanel. В методе main мы его создаём и бросаем на окно с именем "game" - всё это делается в единственной строке game.add(new Game());

Часть третья. Реакция на события.

Игра обязательно требует взаимодействия со стороны пользователя - будь то нажатия клавиш или движение мышкой. Эти события нужно каким-то образом научиться получать и обрабатывать. Я дописал код, который это демонстрирует. Теперь наше окно реагирует на нажатия "стрелок" на клавиатуре:

Давайте разберёмся в нём.
1. Обратите внимание на строки import java.awt.event.KeyAdapter; и import java.awt.event.KeyEvent; - без них теперь никуда.
2. int x=320; и int y=240; - две переменные типа int (32 бита со знаком), которым сразу же присваиваются начальные значения. Это координаты объекта, который мы будем двигать. То есть, когда мы создадим экземпляр класса Game - в нём уже будут две эти переменные, имеющие начальные значения.
3. конструктор public Game() <> выполняется при создании любого экземпляра класса Game. Строки addKeyListener(new KeyAdapter() и ниже пока не комментирую, слишком много информации. По-сути, добавляется "слушатель". Он получает все нажатия клавиш, но в нашем случае реагирует только на 4 из них, меняя координаты объекта. Чтобы "слушатель" мог слышать, необходима строчка setFocusable(true). Обратите внимание на метод repaint(). Он принудительно вызывает метод paint, рисуя прямоугольник в новых координатах.

Нажимая кнопки стрелок мы будем двигать прямоугольник. Но почему-то, он размазывается.
Обратите внимание на следующий закомментированный код: super.paint(g). Он вызывает метод paint родительского класса, который отвечает за то, чтобы нарисовать объект класса JPanel. Если убрать комментарий, мы получим то, ради чего и была затеяна эта писанина - скруглённый прямоугольник будет двигаться на светлом фоне.

Промежуточные выводы.

Получен игровой движок. Увы, у него есть недостатки и достаточно сильные ограничения:
1. Нет возможности двигать объект по диагонали.
2. Низкая скорость перемещения, даже если зажимать клавишу в нужном направлении.

Результат неудовлетворительный. Скорость перемещения можно увеличить, заменив строки x-=1 на x-=10, но при этом теряется плавность перемещения.

Движок такого класса реализует игровой экран и обрабатывает нажатия клавиш. Его вполне достаточно для создания таких игр, как 2048, Simon Says, Tetris, то есть в любых играх, где точное позиционирование не нужно.

А давайте используем найденный эффект для создания одной простенькой игры с платформы Fairchild Channel F - Doodle. Это очень примитивный графический редактор. Естественно, имея в распоряжении мощь современных машин было бы неразумно ей не воспользоваться.

Реализация несколько неуклюжая.
Во-первых, переменные x, y, c, f, size описывают свойства одного и того же объекта. Грамотный программист создаст класс, имеющий следующие поля, и назовёт их так, чтобы при чтении было понятно что выполняет та или другая переменная.
Во-вторых, "слушателя" можно вынести из класса Game в какой-то другой класс. К тому же, менять значения полей в "слушателе" не совсем корректно.
В-третьих - инкремент можно написать по-человечески, ++.
В-четвёртых, как-то нелогично, что в коде панели запускается главный поток. Для этого нужен свой класс.
И последнее - надо же как-то назвать нашу игру.

Кратко про этот код.
1. Класс Figure описывает нашу фигуру. Теперь все её поля закрыты (private). Это значит, что из других объектов к ним напрямую уже не обратиться. Отличная защита от несанкционированного доступа. По-умному это называется инкапсуляция - в создаваемые объекты уже не залезть, работать с ним можно только через открытые методы. Инкапсуляция - второй принцип ООП, читатель, почувствуй себя почти гуру.
2. Весь код, связанный с фигурой так же заключён в пределах одного класса. А это значит, что переписывая методы класса можно менять поведение фигуры, при этом остальной код трогать нет необходимости. Например, можно увеличить шаг перемещения, изменить порядок цветов, инвертировать направление движения, итд.
3. В классе Figure можно увидеть два перегруженных конструктора. Так же в нём есть и перегруженные методы resize. Что это значит? А это значит, что вызывая один и тот же метод с различными параметрами или без них, можно добиться выполнения разных участков кода. Конструктор с параметрами, например, в начале своей работы вызывает конструктор без параметров: this(), чтобы не дублировать код.

Третий принцип ООП - полиморфизм в этих примерах не использовался, может как-то в другой раз.

На этом пока всё.

Ниже окно получившейся программы. Там нарисован смайлик, если кто не понял

Эта статья рассчитана на новичков в программировании. Её цель — объяснить азы языка Java (классы, методы, компиляция, байт-код, JVM, переменные, условия, циклы, импорт). Этот материал поможет:

Java Development Kit (JDK)

JDK содержит много утилит, но нам потребуется только компилятор (javac) и виртуальная машина Java — JVM (java).

Проверить правильность установки и настройки можно в командной строке (на Windows: Win + R → cmd) или в терминале (Linux, Mac), набрав следующие команды:

В качестве альтернативы можно использовать онлайн-JDK вместе с редактором, например на сайте Repl.it.

Написание кода

Писать исходный код можно в любом текстовом редакторе. А компиляцию и запуск проводить в командной строке (терминале). Но удобнее будет работать в редакторе с подсветкой синтаксиса и плагином, автоматизирующим компиляцию и запуск.

Hello, world!

После имени в фигурных скобках записывается тело класса. Оно может содержать поля, методы и другие классы. Поля хранят данные. Они подобны переменным, однако в Java это несколько иная сущность. Методы содержат набор команд или код. Имена методов (как и полей, переменных) принято писать в стиле camelCase, со строчной буквы.

Наш метод main() содержит лишь одну строку, которая выводит в консоль текст "Hello, world!".

Перед компиляцией сохраняем написанный код в файл. Имя файла должно соответствовать имени класса с точностью до регистра символов (Java — регистрозависимый язык). Затем открываем командную строку (или терминал) и вызываем сначала компилятор (javac), а потом виртуальную машину JVM (java).

Переменные

Переменные хранят данные (числа, строки, логические значения и другие). Они похожи на коробочки: надписи на них — это имя и тип переменной, а внутри находится значение. При этом возможны две операции:

  • запись значения в переменную (или присвоение значения);
  • чтение значения из переменной.

В Java перед использованием переменную нужно обязательно объявить, указав тип и имя, поскольку Java — язык со строгой и статической типизацией. Попытка использовать переменную без объявления приведёт к ошибке компиляции. По типу переменные могут быть простыми (числа, символы, логические значения) или ссылочными (массивы, строки, любые другие объекты). В Java есть восемь простых типов (byte, int, short, long, float, double, boolean, char) и бесконечное количество ссылочных.

В примере ниже мы видим объявление двух переменных целого типа (int). Причём переменная second инициируется при объявлении. Затем переменной first присваивается результат выражения, в котором присутствует переменная second. В результате выполнения программы в консоль будут выведены значения обеих переменных: 35 и 10.

Имя переменной может содержать буквы и цифры, знак подчёркивания и $. Имя не должно начинаться с цифры. В профессиональной разработке в именах переменных используют только буквы. Имя должно явно указывать на назначение переменной. Например: countString — счётчик строк, errorSign — признак ошибки. Рекомендуется избегать однобуквенных имён — за исключением временных переменных (существующих в рамках цикла или небольшого кодового блока).

Проверка условий

Любой язык программирования высокого уровня позволяет изменять порядок выполнения программы в зависимости от заданного условия. В Java для этого используется конструкция if. После этого ключевого слова в скобках записывается логическое выражение, затем в фигурных скобках — группа команд. Если результат логического выражения — true (истина), то эта группа команд выполняется, если false (ложь) — нет.

Результат этого примера — строка “i = 10” в консоли, так как результат логического выражения (проверка на равенство) будет true.

В качестве знаков сравнения допустимы: <, <=, >, >=, ==, !=. Добавив ключевое слово else, получаем полную форму оператора сравнения.

Циклы

Циклы предназначены для повторения группы команд. Java позволяет использовать два вида циклов:

  • с определённым количеством итераций: for;
  • без определенного количества итераций: while и do-while.

Запустив этот пример, мы увидим в консоли колонку чисел от 0 до 4. Это результат работы классического цикла for со счётчиком. В круглых скобках три параметра цикла, разделённые точкой с запятой: объявление и инициализация счётчика, проверка условия продолжения цикла, действие после каждой итерации. В фигурных скобках — тело цикла. В нашем случае это команда, выводящая значение счётчика i в консоль.

Когда будем писать игру, используем циклы while и do-while — там и увидим их работу на практике. Пока достаточно сказать, что их синтаксис проще for, а тело цикла повторяется до тех пор, пока логическое выражение в круглых скобках после while возвращает true.

Пример ниже иллюстрирует вторую форму цикла for — без счётчика. Такой вариант удобен при переборе элементов массива или списка.

Импорт и использование классов

Один из важных принципов программирования — DRY: Don’t Repeat Youself (не повторяйся). Разработчик должен уметь использовать то, уже создано, отлажено и работает.

В игре нам потребуется случайное число от 0 до 9. Писать генератор случайных чисел незачем, так как в пакете java.util есть готовый класс Random. Чтобы использовать класс из пакета, его нужно импортировать. Строки с директивами импорта располагаются в самом начале файла класса.

Создадим объект на основании класса, чтобы можно было вызвать нужный метод. Слева от знака присваивания (=) объявляем ссылочную переменную (объект) random типа Random. Справа создаём объект с помощью директивы new.

Вызываем метод через точку после имени объекта: random.nextInt(10). Цифра 10 ограничивает диапазон генерируемых чисел (от 0 до 9). В результате получим строку из 30 случайных чисел. Запустите программу несколько раз и обратите внимание, что последовательность чисел не повторяется.

Создадим класс GuessTheNumber с методом main(), импортируем нужные нам классы и добавим соответствующие объекты. Класс Scanner обеспечит чтение чисел с консоли (System.in — консоль).

Объявим и инициируем три переменные: счётчик попыток count, для чтения числа с консоли — guess, для хранения загаданного числа — number.

Опишем основной игровой цикл, используя while. В цикле запрашиваем число с консоли, сравниваем с загаданным. В случае несовпадения выводим подсказку и увеличиваем счётчик попыток на 1.

Тело цикла while повторяется, пока логическое значение в скобках возвращает true. Таким образом наш цикл будет повторяться, пока значение счётчика попыток меньше 3 и число не отгадано. Обратите внимание на конструкцию, которая позволяет выбрать одно из двух значений согласно условию в скобках. Это тернарный оператор. Если условие в скобках true, то возвращается значение слева от двоеточия, если false — справа.

Остаётся добавить строку с выводом результата игры (победа или проигрыш) после цикла — тут снова используется тернарный оператор. Текст работающей программы выглядит так:

Сохраняем программу в файл GuessTheNumber.java, компилируем (javac), вызываем JVM (java) — и пробуем выиграть у компьютера.

Добавим заключительный штрих: используя цикл do-while, позволим пользователю повторять сеанс игры без перезапуска программы. В приведённом ниже коде комментарий нужно заменить на соответствующий фрагмент из предыдущей программы. Попробуйте сделать это самостоятельно.

Обратите внимание, что тело цикла do-while повторяется на тех же условиях, что и тело цикла while: логическое выражение в скобках должно быть true.

Заключение

Если язык Java вас заинтересовал — приглашаем на факультет Java-разработки. Если ещё не совсем уверены — посмотрите истории успеха наших Java-выпускников:


Эта статья рассчитана на новичков в программировании. Её цель — объяснить азы языка Java (классы, методы, компиляция, байт-код, JVM, переменные, условия, циклы, импорт). Этот материал поможет:

Java Development Kit (JDK)

JDK содержит много утилит, но нам потребуется только компилятор (javac) и виртуальная машина Java — JVM (java).

Проверить правильность установки и настройки можно в командной строке (на Windows: Win + R → cmd) или в терминале (Linux, Mac), набрав следующие команды:

В качестве альтернативы можно использовать онлайн-JDK вместе с редактором, например на сайте Repl.it.

Написание кода

Писать исходный код можно в любом текстовом редакторе. А компиляцию и запуск проводить в командной строке (терминале). Но удобнее будет работать в редакторе с подсветкой синтаксиса и плагином, автоматизирующим компиляцию и запуск.

Hello, world!

После имени в фигурных скобках записывается тело класса. Оно может содержать поля, методы и другие классы. Поля хранят данные. Они подобны переменным, однако в Java это несколько иная сущность. Методы содержат набор команд или код. Имена методов (как и полей, переменных) принято писать в стиле camelCase, со строчной буквы.

Наш метод main() содержит лишь одну строку, которая выводит в консоль текст "Hello, world!".

Перед компиляцией сохраняем написанный код в файл. Имя файла должно соответствовать имени класса с точностью до регистра символов (Java — регистрозависимый язык). Затем открываем командную строку (или терминал) и вызываем сначала компилятор (javac), а потом виртуальную машину JVM (java).

Переменные

Переменные хранят данные (числа, строки, логические значения и другие). Они похожи на коробочки: надписи на них — это имя и тип переменной, а внутри находится значение. При этом возможны две операции:

  • запись значения в переменную (или присвоение значения);
  • чтение значения из переменной.

В Java перед использованием переменную нужно обязательно объявить, указав тип и имя, поскольку Java — язык со строгой и статической типизацией. Попытка использовать переменную без объявления приведёт к ошибке компиляции. По типу переменные могут быть простыми (числа, символы, логические значения) или ссылочными (массивы, строки, любые другие объекты). В Java есть восемь простых типов (byte, int, short, long, float, double, boolean, char) и бесконечное количество ссылочных.

В примере ниже мы видим объявление двух переменных целого типа (int). Причём переменная second инициируется при объявлении. Затем переменной first присваивается результат выражения, в котором присутствует переменная second. В результате выполнения программы в консоль будут выведены значения обеих переменных: 35 и 10.

Имя переменной может содержать буквы и цифры, знак подчёркивания и $. Имя не должно начинаться с цифры. В профессиональной разработке в именах переменных используют только буквы. Имя должно явно указывать на назначение переменной. Например: countString — счётчик строк, errorSign — признак ошибки. Рекомендуется избегать однобуквенных имён — за исключением временных переменных (существующих в рамках цикла или небольшого кодового блока).

Проверка условий

Любой язык программирования высокого уровня позволяет изменять порядок выполнения программы в зависимости от заданного условия. В Java для этого используется конструкция if. После этого ключевого слова в скобках записывается логическое выражение, затем в фигурных скобках — группа команд. Если результат логического выражения — true (истина), то эта группа команд выполняется, если false (ложь) — нет.

Результат этого примера — строка “i = 10” в консоли, так как результат логического выражения (проверка на равенство) будет true.

В качестве знаков сравнения допустимы: , >=, ==, !=. Добавив ключевое слово else, получаем полную форму оператора сравнения.

Циклы

Циклы предназначены для повторения группы команд. Java позволяет использовать два вида циклов:

  • с определённым количеством итераций: for;
  • без определенного количества итераций: while и do-while.

Запустив этот пример, мы увидим в консоли колонку чисел от 0 до 4. Это результат работы классического цикла for со счётчиком. В круглых скобках три параметра цикла, разделённые точкой с запятой: объявление и инициализация счётчика, проверка условия продолжения цикла, действие после каждой итерации. В фигурных скобках — тело цикла. В нашем случае это команда, выводящая значение счётчика i в консоль.

Когда будем писать игру, используем циклы while и do-while — там и увидим их работу на практике. Пока достаточно сказать, что их синтаксис проще for, а тело цикла повторяется до тех пор, пока логическое выражение в круглых скобках после while возвращает true.

Пример ниже иллюстрирует вторую форму цикла for — без счётчика. Такой вариант удобен при переборе элементов массива или списка.

Импорт и использование классов

Один из важных принципов программирования — DRY: Don’t Repeat Youself (не повторяйся). Разработчик должен уметь использовать то, уже создано, отлажено и работает.

В игре нам потребуется случайное число от 0 до 9. Писать генератор случайных чисел незачем, так как в пакете java.util есть готовый класс Random. Чтобы использовать класс из пакета, его нужно импортировать. Строки с директивами импорта располагаются в самом начале файла класса.

Создадим объект на основании класса, чтобы можно было вызвать нужный метод. Слева от знака присваивания (=) объявляем ссылочную переменную (объект) random типа Random. Справа создаём объект с помощью директивы new.

Вызываем метод через точку после имени объекта: random.nextInt(10). Цифра 10 ограничивает диапазон генерируемых чисел (от 0 до 9). В результате получим строку из 30 случайных чисел. Запустите программу несколько раз и обратите внимание, что последовательность чисел не повторяется.

Создадим класс GuessTheNumber с методом main(), импортируем нужные нам классы и добавим соответствующие объекты. Класс Scanner обеспечит чтение чисел с консоли (System.in — консоль).

Объявим и инициируем три переменные: счётчик попыток count, для чтения числа с консоли — guess, для хранения загаданного числа — number.

Опишем основной игровой цикл, используя while. В цикле запрашиваем число с консоли, сравниваем с загаданным. В случае несовпадения выводим подсказку и увеличиваем счётчик попыток на 1.

Тело цикла while повторяется, пока логическое значение в скобках возвращает true. Таким образом наш цикл будет повторяться, пока значение счётчика попыток меньше 3 и число не отгадано. Обратите внимание на конструкцию, которая позволяет выбрать одно из двух значений согласно условию в скобках. Это тернарный оператор. Если условие в скобках true, то возвращается значение слева от двоеточия, если false — справа.

Остаётся добавить строку с выводом результата игры (победа или проигрыш) после цикла — тут снова используется тернарный оператор. Текст работающей программы выглядит так:

Сохраняем программу в файл GuessTheNumber.java, компилируем (javac), вызываем JVM (java) — и пробуем выиграть у компьютера.

Добавим заключительный штрих: используя цикл do-while, позволим пользователю повторять сеанс игры без перезапуска программы. В приведённом ниже коде комментарий нужно заменить на соответствующий фрагмент из предыдущей программы. Попробуйте сделать это самостоятельно.

Обратите внимание, что тело цикла do-while повторяется на тех же условиях, что и тело цикла while: логическое выражение в скобках должно быть true.

Заключение

Если язык Java вас заинтересовал — приглашаем на факультет Java-разработки. Если ещё не совсем уверены — посмотрите истории успеха наших Java-выпускников:

Сегодня игрушку можно наваять на любом ЯП, и JS не исключение. Разработка игр по своей природе сложная задача – мы подскажем, с чего начать.

Разработка игр на JavaScript: реально и безболезненно

Масса людей думает, что все крутые игры (God Of War, Assassin's Creed, Skyrim, добавь по вкусу) созданы на C++. Это отчасти так. В проекте принимают участие сотни специалистов из разных отраслей, в том числе и разработчики, юзающие другой язык – обычная распространенная практика.

Некоторые классные игры написаны на “непопулярных” языках программирования, и это нормально. Если ты работаешь с JavaScript, то не нужно после этой статьи бросаться изучать “плюсы”, оставайся с JavaScript.

Существуют Unity, Unreal Engine, CryEngine и прочие классные решения для создания игрушек, и если тебе удобно развлекаться с ними – пожалуйста. Поэтому нет никакой разницы, на чем ты будешь кодить, но в нашем случае речь пойдет о JS-фреймворках.

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

Не нужно забывать о творении команды Khronos Group. WebGL – это веб-версия спецификации OpenGL ES, позволяющая разработчикам общаться с видеокартой через браузер (поверь, лучше не знать, как это работает).

Таким образом, можно создавать 2D и 3D сцены на GPU (что эффективнее, чем на CPU). Супер! Но если взглянуть на код JavaScript, использующий эти технологии, тебе поплохеет.

Поэтому давай разбираться с фреймворками, оберегающими нас от canvas и абстрагирующими от WebGL.

Разработка игр на JavaScript: реально и безболезненно

PixiJS

Этот инструмент можно назвать 2D-рендером WebGL. Это означает, что данная библиотека включает в себя множество функций, предназначенных для эффективной отрисовки 2D-сцен и объектов. Так проще сосредоточиться на создании программного кода, а хардкорные “низкоуровневые” вещи оставить разработчикам PixiJS.

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

Если ты планируешь создать что-то большее, чем анимация, то поищи дополнительные библиотеки для других частей игровой разработки (физика, масштабирование, tilemaps и т. д.).

ExcaliburJS

Здесь у нас полноценный игровой фреймворк, написанный на Typescript. Полная система сцен и камер, спрайты и анимации, звуки, физика и т. д. – все, что пожелаешь. Многим очень нравится API, предоставляемый ExcaliburJS, т. к. с ним уютнее.

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

ImpactJS

ImpactJS начал свой путь со звания “Первый фреймворк для веб-игр”. Большинство фреймворков, рассмотренных ранее, были просто экспериментами, а не коммерческим продуктом. Этот опенсорсный претендент распространяется бесплатно и поставляется с хорошим редактором уровней.

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

CreateJS

CreateJS – это набор модульных библиотек и HTML5-инструментов, работающих асинхронно или параллельно в зависимости от ситуации.

Инструмент предоставляет все, что нужно для создания игры с нуля, с помощью отдельного модуля языка JavaScript. Например, для рендеринга можно взять PixiJS, а для работы со звуковыми материалами SoundJS и т. д.

PhaserJS

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

Разработка игр на JavaScript: реально и безболезненно

ThreeJS

ThreeJs – самая популярная 3D-библиотека. Она предлагает наборы функций для выполнения общих операций, которые должны происходить в 3D-сцене. Все мероприятия происходят на более высоком уровне, чем raw WebGL, и не надо заморачиваться с горой низкоуровневых действий.

BabylonJS

Этот фреймворк похож на предыдущий, но имеются различия:

  • API меняется каждые 3 месяца, что помогает при поиске старых решений в интернете;
  • активное и полезное сообщество;
  • продуктивные и отзывчивые разработчики (у Three.js самый старый баг на GitHub датируется 2013 годом, в Babylon.js отмечен два дня назад);
  • The playground – это отличный инструмент для быстрого “опробования” кода, объяснения проблемы и оказания помощи.

Как в любом уважающем себя мануале, далее идет подборочка книг по теме.

Кстати, у нас есть очень крутая статья по книгам для геймдэва – рекомендуем!

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

Закрыт. На этот вопрос невозможно дать объективный ответ. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы на него можно было дать ответ, основанный на фактах и цитатах.

Закрыт 2 года назад .

А в каком движке нужно работать, чтобы создавать игры на Java?


2 ответа 2

Все движки, рассмотренные здесь, распространяются бесплатно

3D Движки

jMonkey Engine. Отличная производительность, кроссплатформенность, свой SDK+редакторы, дружелюбное сообщество (вот только англоязычное). Частые обновления и отличная поддержка со стороны разрабов самого движка не может не радовать. Есть модификация версии от 2009 года, её авторы гордо именуют свой мод отдельным движком - Ardor3D (но вот только проект загнулся, какая досада). Даже официальный сайт модификации уже не работает, а перенаравляет на личный блог разработчиков. "Под капотом" стоит LWJGL (Light-Weight JavaGL), поддержка OpenGL v2+ и шейдеров. Плюшки - поддержка всякой лабуды типа Oculus Rift; возможна разработка Android-приложений.

Мой вывод: если готовы приступить к более-чем-любительской разработке серьёзных проектов, то jME - ваш выбор.

Bonzai Engine. Великолепные утилиты для разработки, но нет как и документации, так и сообщества. Немного отойду от темы и проведу небольшое сравнение сообществ движков jME и Bonzai Engine: в одном только Твиттере у jMonkey Engine 1725 подписчиков, а у Bonzai Engine всего 12. Продолжу: кроссплатформенность (Windows/Linux/Android), OpenGL v2+. Плюшки: редакторы есть даже на Android. Также движок обещает поддержку большого количества форматов моделей.

Апдейт: документация внезапно появилась (просто я полтора года назад изучал этот движок, но документации не было вообще). Достойных (да и просто) проектов на этом движке я пока не встречал.

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

Приложения на Bonzai Engine: .

jPCT. Врядли библиотеку размером в 300 кб можно назвать движком, но всё же это лёгкий инструмент для создания простейших приложений. Есть неофициальный редактор, куча подробной документации и довольно большое дружелюбное(!) сообщество (был случай, что на форуме мне помогал сам создатель движка). Также есть поддержка Android (версия jPCT-AE). За "плечами" движка имеется куча приложений, созданных пользователями (лично я сам залипаю в одну игрушку). Прошу учесть, что такой "движок" не даст такую великолепную картинку, как, например, jME и Bonzai Engine, но тут FPS держится выше и стабильнее. Плюшки: поддержка скелетной анимации.

Мой вывод: "дёшево и сердито".

2D Движки

Slick2D. Хороший производительный движок с открытым исходным кодом (лицензия BSD). Кроссплатформенность (Windows/Linux/Mac), поддержка OpenGL v2+. Плюшки: модуль физики jBox2D; легко делается GUI.

Golden T Game Engine. Движок уже стар (2004), но всё же имеет право на существование. По аналогии с jPCT сгодится для простейших приложений. Поддержка OpenGL v1+. Несмотря на то, что движку уже 11й год, его форумы и поддержка всё ещё работают.

PulpCore. Open-source движок с неплохой производительностью. Как я понял, работает только в плагинах, но планируется сделать этот движок рабочим и на десктопах. Плюшки: тонна туториалов; движок заточен для работы с анимацией.

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