Can you create games with java

Создание игры на Java без сторонних библиотек, часть первая

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

Почему Java?

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

IDE

Начнем с выбора IDE. Я являюсь фанатом Eclipse и посоветую вам его.
Если же почему-то вам он не понравился, вы можете использовать NetBeans, Intellij IDEA или командную строку и ваш любимый редактор.

JDK

И скачаем JDK последней версии: JDK 7u4

Скорее всего проблем с установкой IDE у вас не возникнет, а если у вас 64-битная система, все же посоветую устанавливать 32-битный Eclipse, так как иногда бывают ошибки и Eclipse у вас просто не запустится.

Под катом мы приступим к созданию игры.

Класс Game

Итак, создаем проект, в нем класс Game(попутно создав в нем точку входа). Данный класс должен наследовать класс Canvas и реализовать интерфейс Runnable:

public class Game extends Canvas implements Runnable < private static final long serialVersionUID = 1L; public void run() < //функция run появляется после того, как мы добавили "implements Runnable" >public static void main(String[] args) < >> 

Создадим переменную running типа Boolean, которая, как вы уже догадались будет показывать нам запущена ли игра, или нет.

Создадим функцию start() и в ней мы будем создавать новый поток и переводить running в true:

Создадим три функции — update(long delta), render() и init(). Я надеюсь что их значение вам понятно. В функции run() создадим главный игровой цикл, перед ним будем вызывать init(), а в нем самом render() и update(). Так же мы будем вычислять разницу между кадрами(delta time).

public void run() < long lastTime = System.currentTimeMillis(); long delta; init(); while(running) < delta = System.currentTimeMillis() - lastTime; lastTime = System.currentTimeMillis(); update(delta); render(); >> public void init() < >public void render() < >public void update(long delta)

Пока поработаем над функцией render().

public void render() < BufferStrategy bs = getBufferStrategy(); if (bs == null) < createBufferStrategy(2); //создаем BufferStrategy для нашего холста requestFocus(); return; >Graphics g = bs.getDrawGraphics(); //получаем Graphics из созданной нами BufferStrategy g.setColor(Color.black); //выбрать цвет g.fillRect(0, 0, getWidth(), getHeight()); //заполнить прямоугольник g.dispose(); bs.show(); //показать > 

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

public static int WIDTH = 400; //ширина public static int HEIGHT = 300; //высота public static String NAME = "TUTORIAL 1"; //заголовок окна public static void main(String[] args) < Game game = new Game(); game.setPreferredSize(new Dimension(WIDTH, HEIGHT)); JFrame frame = new JFrame(Game.NAME); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //выход из приложения по нажатию клавиши ESC frame.setLayout(new BorderLayout()); frame.add(game, BorderLayout.CENTER); //добавляем холст на наш фрейм frame.pack(); frame.setResizable(false); frame.setVisible(true); game.start(); >

Примерно вот так выглядит наш класс Game сейчас.

Класс Sprite

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

import java.awt.Graphics; import java.awt.Image; public class Sprite < private Image image; //изображение public Sprite(Image image) < this.image = image; >public int getWidth() < //получаем ширину картинки return image.getWidth(null); >public int getHeight() < //получаем высоту картинки return image.getHeight(null); >public void draw(Graphics g,int x,int y) < //рисуем картинку g.drawImage(image,x,y,null); >> 

Сразу же проверим работоспособность. Возьмем эту картинку и скопируем ее в папку с нашим классом Sprite. Добавим функцию getSprite() в класс Game(временно).

public Sprite getSprite(String path) < BufferedImage sourceImage = null; try < URL url = this.getClass().getClassLoader().getResource(path); sourceImage = ImageIO.read(url); >catch (IOException e) < e.printStackTrace(); >Sprite sprite = new Sprite(Toolkit.getDefaultToolkit().createImage(sourceImage.getSource())); return sprite; > 

Добавим нашу картинку в папку assets(папку создать в корне проекта), саму папку надо добавить в build path.

Далее создаем переменную hero типа Sprite. В функции init() инициализируем ее. В Функции render() рисуем:

//в "шапку" public static Sprite hero; //в init() hero = getSprite("man.png"); //в render() после g.fillRect(0, 0, getWidth(), getHeight()); hero.draw(g, 20, 20); 

Input

Для обработки инпута мы создадим класс, наследующий KeyAdapter:

private class KeyInputHandler extends KeyAdapter

Тут же и объявим две переменных в шапке класса Game:

private boolean leftPressed = false; private boolean rightPressed = false; 

Внутри класса KeyInputHandler создадим две функции:

public void keyPressed(KeyEvent e) < //клавиша нажата if (e.getKeyCode() == KeyEvent.VK_LEFT) < leftPressed = true; >if (e.getKeyCode() == KeyEvent.VK_RIGHT) < rightPressed = true; >> public void keyReleased(KeyEvent e) < //клавиша отпущена if (e.getKeyCode() == KeyEvent.VK_LEFT) < leftPressed = false; >if (e.getKeyCode() == KeyEvent.VK_RIGHT) < rightPressed = false; >> 

Теперь в функции init() добавим следующее:

addKeyListener(new KeyInputHandler()); 

Создадим переменные x и y для героя(так как пока что мы еще не написали класс Entity). Сделаем чтобы герой всегда рисовался на этих координатах.

private static int x = 0; private static int y = 0; hero.draw(g, x, y); 

А теперь в функции update() будем проверять нажаты ли клавиши и изменять x-координату.

public void update(long delta) < if (leftPressed == true) < x--; >if (rightPressed == true) < x++; >> 

Источник

Пишем 2d-игру на Java

В этой статье будет описываться создание 2D игры на Java. Сразу предупреждаю, вы должны хотя бы базово знать язык Java, поскольку на подробное объяснение каждой строки у меня нету времени. И очень прошу вас, не списывать просто код, а пытаться понять что означает каждая строка, и писать со смыслом. И еще, я использую Eclipse, но вы можете использовать любой IDE.

Задача:

Я планирую создать игру, напоминающую шутер с видом от 3 лица.

Начало:

Для начала создадим проект. Назовем его «Just game». И сразу создаем класс Display.java. В него пишем:

public static void main(String[] args) < JFrame frame = new JFrame(/* название нашей игры */); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setUndecorated(true); frame.setVisible(true); >
JFrame frame = new JFrame(/*название нашей игры*/);

мы создаем рамку, которая и будет отображаться при запуске нашей игры

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

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

frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setUndecorated(true);

устанавливаем нашей рамке максимальные размеры, убираем декорации(кнопки свернуть, закрыть, уменьшить/увеличить и т.п.), т.е. делаем игру на весь экран. Если вы хотите, чтобы игра не была бы на весь экран, то используйте:

frame.setSize(/*ширина*/,/*высота*/); frame.setResizable(false); //false чтобы нельзя было бы поменять размеры рамки, true -можно

Только не забудьте, все настройки рамки надо писать до того, как вы сделаете её видимой

Ну чтож, теперь нажимаем «Run» и пробуем запустить нашу игру. Если все написано правильно, у вас не должны возникать ошибки и должно появиться пустое, серое окно.

Серое окно… Как скучно… Давайте создадим что-нибудь поинтереснее.

Создадим новый класс, под названием «Main». Main класс у нас будет являться панелью, которую мы вставим в рамку, по этому он должен расширять JPanel. (Для тех, кто не знает, расширять пишется как extends после названия класса)

Возвращаемся в класс Display и после настроек рамки, но перед установлением её видимости, пишем:

Вы спросите — «Ну и зачем мы это сделали?». Представьте себе картину. Эта картина и является конечная наша игра. А теперь представьте рамку. Без ничего внутри, просто пустую рамку. На ней ничего нельзя нарисовать, она бесполезна. Для этого, мы вставили в картину пустой лист, на котором программа в дальнейшем может рисовать картину. На этом закончим наше лирическое отступление и вернемся к классу Main.

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

public void paint(Graphics g) < //отрисовка всех объектов >

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

Теперь запускаем программу, и видим:

image

Давайте отрисуем какую-нибудь картинку. Например эту:

image

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

Image img = new ImageIcon("2.png").getImage();

(предварительно надо в наш проект скинуть картинку и назвать ее 2.png)

После этого удаляем строчку отрисовки линии, а вместо нее в метод paint пишем:

Разберемся поближе с методом drawImage, так как мы будем часто его затрагивать.

drawImage(картинка которую мы будем рисовать, которую мы объявили раннее, координата X с которой будет рисоваться картинка, координата Y с которой будет рисоваться картинка, paint);

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

Теперь запускаем программу, и видим:

image

Чего-то она маленькая, не правда ли? Давайте научимся увеличивать её размеры. Добавляем к drawImage() параметры так, чтобы вышло:

g.drawImage(img, 0, 0, 1920, 1080, null);

Что мы сейчас добавили? Эти два параметра растягивают картинку, до координат 1920 и 1080. Получается, что картинка на весь экран. Давайте запустим программу и это проверим.

image

Ну наконец-то. Теперь мы умеем любые картинки растягивать на весь экран. Но вот проблема. Метод paint вызывается только один раз. И как же его обновлять постоянно? Для этого существует очень полезная вещь — таймер. Давайте создадим его.

Timer timer = new Timer(20, this);

(20 это частота с которой обновляется таймер, this- где выполнять метод при обновлении таймера
Это мы должны вписать сразу после строки определения класса, т.е. после:

public class Main extends JPanel

Также, надо дополнить строку определения класса таким образом:

public class Main extends JPanel implements ActionListener

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

@Override public void actionPerformed(ActionEvent e) < // TODO Auto-generated method stub >

Этот метод будет выполняться при обновлении таймера. В него мы должны написать repaint(); чтобы при каждом обновлении таймера у нас все элементы бы стирались, и нарисовывались заново.

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

После этого, можете не запускать программу, ведь в ней ничего не изменится. Давайте заменим текстуру домика на нормальную текстуру карты. Её вы можете нарисовать сами, либо скопировать у меня пробную:

image

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

И перед конструктором добавим:

И сходим еще в класс Display.java и там немного изменяем метод frame.add:

Таким образом, наша рамка будет передаваться в класс Main.java. Переходим в этот класс, и там где у нас метод paint() меняем строку drawImage() на:

g.drawImage(img, 0, 0,frame.getWidth(), frame.getHeight(), null);

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

image

На сегодня все. Оставляю код, для тех, кто запутался:

Display.java

import javax.swing.JFrame; public class Display < public static void main(String[] args) < JFrame frame = new JFrame("JustGame"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setUndecorated(true); frame.add(new Main(frame)); frame.setVisible(true); >> 

Main.java

import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class Main extends JPanel implements ActionListener < Image img = new ImageIcon("2.png").getImage(); Timer timer = new Timer(20, this); JFrame frame; public Main(JFrame frame) < this.frame = frame; >public void paint(Graphics g) < g.drawImage(img, 0, 0,frame.getWidth(), frame.getHeight(), null); >@Override public void actionPerformed(ActionEvent e) < // TODO Auto-generated method stub repaint(); >>

Источник

Читайте также:  Не удалось получить html
Оцените статью