Пишемо гру на LWJGL

Створення гри на LWJGL #1
Написання гри — складний і цікавий процес, який вимагає багато часу. В даному циклі статей я розповім, як створити просту 3D гру на Java з використання бібліотеки LWJGL.

Для створення своєї гри необхідно наступне:

  • Вміння писати код на Java (необхідний мінімум: розуміння роботи умов, циклів, рядків, масивів, функцій, класів)
  • Середовище розробки (я буду використовувати Eclipse)
  • Бібліотека LWJGL
  • Відеокарта, підтримуюча OpengGL версії не нижче 3.3
  • Вільний час
  • Ідея

Кому цікаво, прошу під кат.

Крок перший: підготовка

Як встановити Eclipse.
Скачати LWJGL 2.9.3, бібліотеку 3D графіки, додати її в свій проект.

Скачати slick-util, бібліотеку, спрощує завантаження текстур, додати її в проект.

Крок другий, перевірка

Першим ділом створимо клас Main в пакеті main, помістимо в нього наступний код:

Якщо рядок з input не підсвічується червоним — значить все ок (на скріні підсвічується жовтою, оскільки дана бібліотека ще не використовується в коді).

Крок третій, дисплей

Наповнимо клас Main наступним кодом:
Початковий код

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class Main {
 static int width = 800, height = 600;
 static DisplayMode mainDisplayMode = new DisplayMode(width, height);
 static boolean running = true;

 static void update() {
 if (Display.wasResized()) {
 width = Display.getWidth();
 height = Display.getHeight();
}
 Display.update(); 
Display.sync(60);

 if (Display.isCloseRequested()) {
 running = false;
}
}

 public static void main(String[] args) {
 try {
Display.setLocation(
 (Display.getDesktopDisplayMode().getWidth() - mainDisplayMode.getWidth()) / 2, 
 Display.getDesktopDisplayMode().getHeight() - mainDisplayMode.getHeight()) / 2);
Display.setResizable(true);
Display.setVSyncEnabled(true);
Display.setDisplayMode(mainDisplayMode);
Display.create();

 } catch (LWJGLException ex) {
System.err.println(ex.getStackTrace().toString());
Display.destroy();
System.exit(1);
}

 while (running) {

update();
}

Display.destroy();
System.exit(0);
}
}

Отже, що тут відбувається:

Display.setLocation(
(Display.getDesktopDisplayMode().getWidth() - mainDisplayMode.getWidth()) / 2, (Display.getDesktopDisplayMode().getHeight() - mainDisplayMode.getHeight()) / 2);

Display.setResizable(true);
Display.setVSyncEnabled(true);
Display.setDisplayMode(mainDisplayMode);
Display.create();

У цих рядках:
1. задається положення дисплея (по центру екрану)
2. дозволяється змінювати його розмір
3. включається вертикальна синхронізація
4. встановлюється DisplayMode в якому зберігаються розміри екрану і деякі інші параметри
5. в останньому рядку дисплей створюється і показується на екрані.

static void update() {
 if (Display.wasResized()) {
 width = Display.getWidth();
 height = Display.getHeight();
}
 Display.update(); 
Display.sync(60);

 if (Display.isCloseRequested()) {
 running = false;
}
}

У функції update, яка викликається в нескінченному циклі:
1. Перевірка зміни розмірів вікна
2. Оновлення дисплея
3. У рядку Display.sync(60) відбувається синхронізація дисплея з 60 герца (якщо у Вас інша частота оновлення екрану, наприклад 59, 76, 120, 144 і т. д., виставите свою частоту).
4. Перевірка закриття вікна

Читайте також  Головоломка «My Test Patience» від Check Point Security Academy

Зауважте, як відбувається завершення роботи програми, коли користувач натиснув на хрестик, прапор закриття вікна, Display.isCloseRequested(), стає true, а змінна running стає false, і при наступній ітерації цикл while(running) не виконається і відбудеться перехід до рядками Display.destroy(), яка знищить дисплей і System.exit(0), виклик якої завершить програму.

Крок четвертий, OpenGL

Щоб ініціалізувати OpenGL у функцію main перед циклом while(running) потрібно додати наступний код:

if (!GLContext.getCapabilities().OpenGL33) {
 System.err.println("Ваша відеокарта не підтримує OpenGL 3.3.");
System.exit(0);
}

Даний код перевіряє, що відеокарта підтримує OpenGL 3.3, якщо відеокарта не підтримує дану версію, спробуйте оновити драйвера або переключитися на іншу відеокарту (якщо у Вас їх більше однієї).

Отже, перевірка зроблена, якщо все добре, відеокарта підтримує OpenGL 3.3, то рухаємося далі. Після коду перевірки, до циклу додамо наступний код:

glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glClearColor(1f, 0f, 0f, 1f);

Даний код налаштує OpenGL наступним чином:
1. Включить в шейдери м’яке освітлення
2. Включить текстури
3. Включить перевірку глибини (щоб ближні об’єкти перекривали далекі)
4. Встановить колір очищення

У цикл while(running), до виклику функції update(), додамо рядок

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Яка буде очищати буфер кольору і буфер глибини при кожному відновленні екрана.

Підсумковий код

Натисніть, щоб подивитися

import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_SMOOTH;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glShadeModel;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GLContext;


public class Main {
 static int width = 800, height = 600;
 static DisplayMode mainDisplayMode = new DisplayMode(width, height);
 static boolean running = true;

 static void update() {
 if (Display.wasResized()) {
 width = Display.getWidth();
 height = Display.getHeight();
}
 Display.update(); 
Display.sync(60);

 if (Display.isCloseRequested()) {
 running = false;
}
}

 public static void main(String[] args) {
 try {
 Display.setLocation((Display.getDesktopDisplayMode().getWidth() - mainDisplayMode.getWidth()) / 2, (Display.getDesktopDisplayMode().getHeight() - mainDisplayMode.getHeight()) / 2);
Display.setResizable(true);
Display.setVSyncEnabled(true);
Display.setDisplayMode(mainDisplayMode);
Display.create();

 } catch (LWJGLException ex) {
System.err.println(ex.getStackTrace().toString());
Display.destroy();
System.exit(1);
}

 if (!GLContext.getCapabilities().OpenGL33) {
 System.err.println("Ваша відеокарта не підтримує OpenGL 3.3.");
System.exit(0);
}

glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
 glClearColor(1f, 0f, 0f, 1f);


 while (running) {
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

update();
}

Display.destroy();
System.exit(0);
}
}

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

You may also like...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *