Добавлен Doc,
опубликован
XGMWar
Содержание:
В этой статье мы создадим активное окно, в котором будет происходить действие и попробуем нарисовать в нем графические примитивы.
Создание проекта и первая программа
Для начала создайте новый проект и назовите его XGMWar (Этот процесс подробно описан в данной статье). Создайте новый Package (Правый клик по папке проекта слева -> New -> Package) и назовите его core.main. Создайте еще один Package с названием game.main. Их предназначение я подробнее опишу в следующей статье.
Создайте новый Class в game.main (Правый клик по нужному Package -> New -> Class). Назовите его Init и поместите внутрь класса следующий код:
public static void main(String args[]){
System.out.println("Hello, World!");
}
Разъяснение кода
Этот код объявляет главную точку входа в наше приложение - метод main. Единственный его аргумент - массив строк args, который передается приложению системой.
Вторая строка использует стандартный выходной поток класса System для вывода сообщения в консоль.
Вторая строка использует стандартный выходной поток класса System для вывода сообщения в консоль.
Нажмите зеленую кнопку Run вверху. В консоли внизу вы увидите надпись "Hello, World!". Наша первая программа готова.
Создание окна
Для создания окна мы будем использовать класс JFrame.
Поместите в класс Init следующий код:
private JFrame mainFrame;
public Init(){
mainFrame = new JFrame();
mainFrame.setTitle("XGMWar");
mainFrame.setSize(800, 600);
mainFrame.setResizable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
public static void main(String args[]){
new Init();
}
Разъяснение кода
Первая строка когда объявляет аттрибут класса Init - объект mainFrame типа JFrame (класс, использующийся для создания окон). В конструкторе класса Init мы сначала создаем JFrame и присваиваем его аттрибуту mainFrame, а далее устанавливаем его заголовок, размеры, запрещаем эти размеры изменять и устанавливаем действие при нажатии на кнопку закрытия окна - выход из программы. Далее мы показываем это окно пользователю.
Если мы сейчас запустим нашу программу, то увидим пустое окно, с параметрами заданными в коде. При нажатии на кнопку выхода процесс программы прекратит свое существование.
Подготавливаем "холст"
Добавим еще один класс в пакет game.main и назовем его GameGraphics.
Его код будет выглядеть примерно так:
Его код будет выглядеть примерно так:
package game.main;
import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class GameGraphics extends Canvas{
private static final long serialVersionUID = 1L;
private Thread threadMain;
private BufferStrategy bufferStrategy;
public GameGraphics(JFrame frameMain){
frameMain.setIgnoreRepaint(true);
frameMain.getContentPane().add(this);
frameMain.setVisible(true);
this.createBufferStrategy(2);
bufferStrategy = this.getBufferStrategy();
threadMain = new Thread(){
public void run(){
Graphics2D g2;
while(true){
try{
Thread.yield();
g2 = (Graphics2D) bufferStrategy.getDrawGraphics();
// Здесь отрисовка
if(!bufferStrategy.contentsLost())
bufferStrategy.show();
} catch (Exception e){
}
}
}
};
threadMain.start();
}
}
Разъяснение кода
Как видите, этот класс наследует другой класс, именуемый Canvas, а значит он наследует и все его свойства. Главное свойство класса Canvas состоит в том, что он позволяет реализовывать внутри себя отрисовку графического буфера (Сам буфер определяется классом Graphics, или его более совершенным дочерним классом Graphics2D, который мы и будем использовать). Именно из-за этого свойства мы наследовали класс Canvas. Как видите, членами класса являются long serialVersionUID (Это нам не нужно, сейчас оно скорее для того, чтобы не ругался компилятор), Thread threadMain (Поток, в котором будет производиться отрисовка) и BufferStrategy bufferStrategy (Специальный класс, позволяющий производить в графический буфер отрисовку с двойной буферизацией). В конструкторе класса, принимающем JFrame как аргумент (Ведь Canvas необходимо куда-то поместить, не так ли?), мы запрещаем этому JFrame автоматическую отрисовку, добавляем этот самый Canvas в JFrame и показываем этот JFrame пользователю (Строчку, которая показывает JFrame пользователю в классе Init мы потом заменим на создание GameGraphics). Далее мы инициализируем BufferStrategy и, наконец, создаем анонимный класс, наследующий класс Thread и запускаем его. В теле этого класса находится метод run (Он будет исполняться, когда мы запустим поток), а внутри этого метода бесконечный цикл, который для начала ждет завершения других потоков, затем получает графический буфер g2, рисует что-то в него (Этот код мы добавим позже), а потом с помощью bufferStrategy показывает нарисованное пользователю.
Не торопитесь запускать программу, на данный момент ничего нового вы не увидите. Перейдем к отрисовке графических примитивов.
Рисуем!
Правильным архитектурным решением, по моему мнению, будет создание нового класса, отвечающего за отрисовку.
Создадим пакет core.graphics, а в нем новый класс, который назовем Graph. Поместим в тело класса следующий код:
Создадим пакет core.graphics, а в нем новый класс, который назовем Graph. Поместим в тело класса следующий код:
public void draw(Graphics2D g){
g.setColor(Color.black);
g.fillRect(0, 0, 800, 600);
g.setColor(Color.red);
g.fillOval(50, 50, 20, 10);
g.setColor(Color.green);
g.drawLine(10, 80, 305, 90);
g.setColor(Color.blue);
g.drawRect(10, 10, 770, 550);
}
Разъяснение кода
Код простейший. Это метод, который принимает графический буфер и отрисовывает в него различные графические примитивы различных цветов по заданным координатам.
Заменим в класс Init строчку
mainFrame.setVisible(true);
на
new GameGraphics(mainFrame, new Graph());
Не обращайте внимания на ошибки, переходите к классу GameGraphics. Нужно добавить к членам класса экземпляр Graph, в аргументы конструктора класса ссылку на Graph, а также присваивание атрибуту класса этой ссылки так, чтобы получился следующий код:
private BufferStrategy bufferStrategy;
private Graph graph;
public GameGraphics(JFrame frameMain, Graph g){
graph = g;
frameMain.setIgnoreRepaint(true);
И ,естественно, в цикл отрисовки добавляем использование graph, чтобы получился такой код:
g2 = (Graphics2D) bufferStrategy.getDrawGraphics();
graph.draw(g2);
Первая и последняя строчки кода не изменились, я добавил их, чтобы вам было проще сориентироваться.
Запустим нашу программу. Если вы видите черное окно с линией, кругом и квадратом - я вас поздравляю, мы заложили основы графики! Если же нет, значит что-то пошло не так и вам стоит свериться с кодом статьи. Исходный код статьи можно скачать из этого поста. В следующей статье мы погрузимся в архитектуру нашей будущей игры и настроим классы, с которыми будем работать в дальнейшем.
Скриншоты
Содержание
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Только немного не так.
Ладно, раз кто-то читает надо таки продолжать писать.