Simple 2D arcade game in java with source code
Today we are going to see how to create a sample classic arcade video game using only a sample code of java. The object of the game (mini project) is to prevent the ball from falling while moving the cursor left or right. the score increase by +1 point in every touch and best score is displayed when the red ball falls. i have also made a challenge by activating another black ball, the user should avoid it or the game is over. in every +10 point the speed increase x2 to make the game difficult.
Source Code
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.Timer; import javax.swing.WindowConstants; public class RedBall extends JComponent implements ActionListener, MouseMotionListener, KeyListener private int ballx = 150; private int bally = 30; private int ballx1 = 100; private int bally1 = 10; private int paddlex = 0; private int ballySpeed = 7; private int ballxSpeed = 5; private int bally1Speed = 14; private int ballx1Speed = 10; public int score = 0; public int score1 = 0; private int scorefinal; public int bestscore; public int bestscore1; public boolean gameOver, started; public static void main(String[] args) JFrame wind = new JFrame("RedBall/GamePinfo"); RedBall g = new RedBall(); wind.add(g); wind.pack(); wind.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); wind.setLocationRelativeTo(null); wind.setVisible(true); wind.addMouseMotionListener(g); Timer tt = new Timer(17, g); tt.start(); > public void newball(int ballx, int bally, int ballxspeed, int ballyspeed) ballx = 150; bally = 30; ballxspeed = 5; ballyspeed = 7; JOptionPane.showMessageDialog(null, "new ball !"); return; > @Override public Dimension getPreferredSize() return new Dimension(800, 600); > @Override protected void paintComponent(Graphics g) //draw the sky g.setColor(Color.cyan); g.fillRect(0, 0, 800, 600); g.setColor(Color.GREEN); g.fillRect(0, 550, 800, 100); //draw the paddel g.setColor(Color.black); g.fillRect(paddlex, 500, 100, 20); //draw the ball g.setColor(Color.RED); g.fillOval(ballx, bally, 30, 30); //draw the ball_1 if (score >= 5) g.setColor(Color.BLACK); g.fillOval(ballx1, bally1, 30, 30); > //score if (score >= 5) g.setColor(Color.red); g.setFont(new Font("Arial", 8, 50)); g.drawString(String.valueOf(score + score1), 30 / 1 - 15, 80); > else g.setColor(Color.white); g.setFont(new Font("Arial", 8, 50)); g.drawString(String.valueOf(score), 30 / 1 - 15, 80); > // start && gameOver g.setColor(Color.white); g.setFont(new Font("Arial", 8, 50)); if (gameOver) g.drawString(String.valueOf(" Best Score :" + scorefinal), 50 / 1 - 15, 200); > > @Override public void actionPerformed(ActionEvent e) ballx = ballx + ballxSpeed; bally = bally + ballySpeed; // Window Down if (ballx >= paddlex && ballx paddlex + 100 && bally >= 475) ballySpeed = -7; score++; > if (bally >= 700 ) score = 0; bally = 30; gameOver = true; > // Window up if (bally 0) ballySpeed = 7; > // Window right if (ballx >= 775) ballxSpeed = -5; > // Window left if (ballx 0) ballxSpeed = 5; > //********************************************************************** ballx1 = ballx1 + ballx1Speed; bally1 = bally1 + bally1Speed; // Window down if (ballx1 >= paddlex && ballx1 paddlex + 100 && bally1 >= 475) bally1Speed = -14; score1++; > if (bally1 >= 700) score1 = 0; bally1 = 10; > // Window up if (bally1 0) bally1Speed = 14; > // Window right if (ballx1 >= 775) ballx1Speed = -10; > // Window left if (ballx1 0) ballx1Speed = 10; > //********************************************************************** bestscore = score; bestscore1 = score1; if (scorefinal > bestscore) scorefinal = scorefinal; > else scorefinal = bestscore1; scorefinal = score + score1; > if (scorefinal > bestscore) scorefinal = scorefinal; > else scorefinal = bestscore; scorefinal = score + score1; > repaint(); > @Override public void mouseMoved(MouseEvent e) paddlex = e.getX() - 50; repaint(); > @Override public void mouseDragged(MouseEvent e) > @Override public void keyTyped(KeyEvent e) > @Override public void keyPressed(KeyEvent e) > @Override public void keyReleased(KeyEvent e) > >
Создание игры на 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++; >>