Upload
mario-jorge-pereira
View
663
Download
5
Embed Size (px)
Citation preview
LABS.DGTI: JOGOS EM JAVA DESENVOLVIMENTO DE JOGOS EM JAVA 2D.
MINILABS: JOGOS EM JAVA
MARIO JORGE PEREIRA
▸ Desde 2002 desenvolvendo com softwares com Java. Certificado de Programador Java (SCJP) em 2005. Desenvolvimento JSE, JEE e JME.
▸ Atualmente Analista de Tecnologia da Informação (IFBaiano), Docente (UCSal) e Artesão de Software (Dev)
MINILABS: JOGOS EM JAVA
AGENDA
▸ Conceitos Básicos
▸ Animação
▸ Sprites
▸ Colisões
MINILABS: JOGOS EM JAVA
AGENDA
▸ Conceitos Básicos
▸ Animação
▸ Sprites
▸ Colisões
"A GAME IS A SYSTEM IN WHICH PLAYERS ENGAGE IN AN ARTIFICIAL CONFLICT, DEFINED BY RULES, THAT RESULTS IN A QUANTIFIABLE OUTCOME.
Salen e Zimmerman (Rules of play, 2004)
MINILABS: JOGOS EM JAVA
MINILABS: JOGOS EM JAVA
GAME LOOP
CARREGAR LOAD
ENTRADAS INPUTS
ATUALIZAR UPDATE
APRESENTAR RENDER
DESCARREGAR UNLOAD
BASIC0
Versão 1
MINILABS: JOGOS EM JAVA
SWING
▸ conjunto de componentes para a construção de interfaces gráficas de usuário (GUIs)
▸ funcionalidade gráficos ricos e interatividade aos aplicativos Java.
▸ Os componentes Swing são implementados inteiramente na linguagem de programação Java.
MINILABS: JOGOS EM JAVA
COMPONENTES E CONTAINERS
▸ JFrame
▸ JPanel
▸ JButtons
▸ JLabel
▸ JTable
MINILABS: JOGOS EM JAVA
Jogo.java
import javax.swing.JPanel;
public class Jogo extends JPanel {
public Jogo() {
}
}
MINILABS: JOGOS EM JAVA
Aplicacao.java
import java.awt.EventQueue;import javax.swing.JFrame;
public class Principal extends JFrame {
public Principal() {initUI();
}
private void initUI() {...}public static void main(String[] args) {...}
}
MINILABS: JOGOS EM JAVA
MÉTODOS BÁSICOS
▸ add(new Jogo());
▸ Adiciona o local do jogo / tabuleiro ▸ setSize(300, 300);
▸ Define o tamanho da Janela ▸ setTitle(“Aplicação");
▸ Titulo da Janela ▸ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
▸ Define que ao clicar no botão fechar da janela ele vai fechar a aplicação. ▸ setLocationRelativeTo(null);
▸ Faz com que a aplicação inicie no centro da tela
MINILABS: JOGOS EM JAVA
Application.java
private void initUI() {add(new Jogo());setSize(300, 300);setTitle("Aplicação");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);}
MINILABS: JOGOS EM JAVA
SWING VS. THREAD-SAFE
▸ A api Swing não é thread-safe
▸ Event-Dispatch Thread (EDT)
▸ SwingUtilities.invokeLater(Runnable) ou EventQueue.invokeLater(Runnable)
▸ Recomendação: Java 5
MINILABS: JOGOS EM JAVA
Application.java
public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {@Overridepublic void run() {Aplicacao ex = new Aplicacao();ex.setVisible(true);
}});
}
BASICO
Versão 2
MINILABS: JOGOS EM JAVA
DESENHANDO
▸ void paintComponent(Graphics g) {…}
▸ Método que desenha o componentes
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import java.awt.geom.*;import javax.swing.JPanel;import static java.awt.RenderingHints.*;
public class Jogo extends JPanel {
public void paintComponent(Graphics g) {...}
private void desenhar(Graphics g) {...}
}
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void paintComponent(Graphics g) {super.paintComponent(g);desenhar(g);}
MINILABS: JOGOS EM JAVA
DESENHANDO
▸ Graphics2D
▸ RenderingHints
▸ Dimension
▸ Ellipse2D
▸ AffineTransform
MINILABS: JOGOS EM JAVA
Jogo.java (basico)
private void desenhar(Graphics g) {Graphics2D g2d = (Graphics2D) g;Dimension size = getSize();double w = size.getWidth();double h = size.getHeight();Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);for (double deg = 0; deg < 360; deg += 5) {AffineTransform at = AffineTransform.getTranslateInstance(w / 2, h / 2);at.rotate(Math.toRadians(deg));g2d.draw(at.createTransformedShape(e));
}}
MINILABS: JOGOS EM JAVA
Jogo.java (com perfumaria)
private void desenhar(Graphics g) {Graphics2D g2d = (Graphics2D) g;RenderingHints rh = new RenderingHints(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);rh.put(KEY_RENDERING, VALUE_RENDER_QUALITY);g2d.setRenderingHints(rh);Dimension size = getSize();double w = size.getWidth();double h = size.getHeight();Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);g2d.setStroke(new BasicStroke(1));g2d.setColor(Color.gray);for (double deg = 0; deg < 360; deg += 5) {
AffineTransform at = AffineTransform.getTranslateInstance(w / 2, h / 2);at.rotate(Math.toRadians(deg));g2d.draw(at.createTransformedShape(e));
}}
BASICO
Versão 3
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import javax.swing.*;
public class Jogo extends JPanel { private Image imagem;
public Jogo() { initJogo(); } private void initJogo() {...} private void carregaImagem() {...} public void paintComponent(Graphics g) {…} private void desenhar(Graphics g) {...}}
MINILABS: JOGOS EM JAVA
Jogo.java
private void initJogo() { carregaImagem(); int w = imagem.getWidth(this); int h = imagem.getHeight(this); setPreferredSize(new Dimension(w, h)); }
MINILABS: JOGOS EM JAVA
CARREGANDO IMAGEM
▸ Image imagem
▸ ImageIcon imageIcon
▸ g.drawImage(imagem, 0, 0, null);
MINILABS: JOGOS EM JAVA
Jogo.java
private void carregaImagem() { ImageIcon ii = new ImageIcon(getClass().getResource("salvador.png")); imagem = ii.getImage(); }@Overridepublic void paintComponent(Graphics g) {
super.paintComponent(g);desenhar(g);
}private void desenhar(Graphics g) { g.drawImage(imagem, 0, 0, null);}
MINILABS: JOGOS EM JAVA
Aplicacao.java
private void initUI() {add(new Jogo());pack();setTitle("Aplicação");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);}
MINILABS: JOGOS EM JAVA
AGENDA
▸ Conceitos Básicos
▸ Animação
▸ Sprites
▸ Colisões
MINILABS: JOGOS EM JAVA
PROCESSOS E THREADS
▸ Processo
▸ ambiente de execução auto-suficiente.
▸ cada processo tem seu próprio espaço de memória.
▸ Thread
▸ processos leves.
▸ criação de um novo segmento requer menos recursos do que a criação de um novo processo.
MINILABS: JOGOS EM JAVA
THREADS
ANIMAÇÃO
Versão 4
MINILABS: JOGOS EM JAVA
REDIMENSIONAMENTO
▸ setResizable ()
▸ define se o JFrame pode ser redimensionado.
▸ pack()
▸ redimensiona o JFrame para ajustar ao tamanho ideal.
▸ Note que a ordem pela qual estes dois métodos são chamados é importante.
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import java.awt.event.*;import javax.swing.*;
public class Jogo extends JPanel implements ActionListener {private final int B_WIDTH = 350;private final int B_HEIGHT = 350;private final int INITIAL_X = -40;private final int INITIAL_Y = -40;private final int DELAY = 25;private Image imagem;private Timer timer;private int x, y;
...}
MINILABS: JOGOS EM JAVA
Jogo.java
public class Jogo extends JPanel implements ActionListener {public Jogo() {...}private void carregaImagem() {...}private void initJogo() {...}public void paintComponent(Graphics g) {...}private void desenhar(Graphics g) {...}public void actionPerformed(ActionEvent e) {...}
}
MINILABS: JOGOS EM JAVA
Jogo.java
public Jogo() {initJogo();}
private void carregaImagem() {ImageIcon ii = new ImageIcon("estrela.png");imagem = ii.getImage();}
MINILABS: JOGOS EM JAVA
DOUBLEBUFFER
▸ setDoubleBuffered(true);
▸ O componente JPanel vai usar um Buffer para apresentar.
▸ Significa que todos os desenhos serão feitos na memória primeiro.
▸ O buffer fora da tela será copiado para a tela.
MINILABS: JOGOS EM JAVA
Jogo.java
private void initJogo() {setBackground(Color.BLACK);setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));setDoubleBuffered(true);carregaImagem();x = INITIAL_X;y = INITIAL_Y;timer = new Timer(DELAY, this);timer.start();
}
MINILABS: JOGOS EM JAVA
TIMER
▸ timer = new Timer(DELAY, this);
▸ timer.start();
▸ TimerSwing e chamar o método start ().
▸ A cada ciclo (DELAY) de tempo o temporizador irá chamar o método actionPerformed().
▸ Para utilizar o método actionPerformed (), que deve implementar a interface ActionListener.
MINILABS: JOGOS EM JAVA
TOOLKIT.GETDEFAULTTOOLKIT
▸ no desenhar() chamamos a imagem na janela utilizando o método drawImage().
▸ o Toolkit.getDefaultToolkit (). Sync ()
▸ sincroniza a parte gráfica
▸ protege os eventos gráficos
▸ Sem essa linha, a animação pode não ser suave no Linux.
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void paintComponent(Graphics g) {super.paintComponent(g);desenhar(g);
}
private void desenhar(Graphics g) {g.drawImage(imagem, x, y, this);Toolkit.getDefaultToolkit().sync();
}
MINILABS: JOGOS EM JAVA
ACTION PERFORMED
▸ actionPerformed()
▸ é chamado pelo timer repetidamente
▸ Dentro do método, alteramos os valores x e y do objeto estrela
▸ repaint ()
▸ Faz com que o método paintComponent () seja chamado
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void actionPerformed(ActionEvent e) {x += 1;y += 1;if (y > B_HEIGHT) {y = INITIAL_Y;x = INITIAL_X;
}repaint();
}
ANIMAÇÃO
Versão 5
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import javax.swing.*;import java.util.TimerTask;import java.util.Timer;
public class Jogo extends JPanel { private final int B_WIDTH = 350;
private final int B_HEIGHT = 350; private final int INITIAL_X = -40; private final int INITIAL_Y = -40; private final int INITIAL_DELAY = 100; private final int PERIOD_INTERVAL = 25; private Image star; private Timer timer; private int x, y; ...}
MINILABS: JOGOS EM JAVA
UTILITY TIMER
▸ Usamos o java.util.Timer em vez do javax.Swing.Timer
▸ Para os jogos Java Swing desta forma deve ser mais preciso
▸ timer = new Timer();
▸ timer.scheduleAtFixedRate(new ScheduleTask(), INITIAL_DELAY, PERIOD_INTERVAL);
▸ executa o metodo run do ScheduleTask a cada intervalo
MINILABS: JOGOS EM JAVA
Jogo.java
private void initJogo() { setBackground(Color.BLACK); setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); setDoubleBuffered(true); carregaImagem();
x = INITIAL_X; y = INITIAL_Y; timer = new Timer(); timer.scheduleAtFixedRate(new ScheduleTask(), INITIAL_DELAY, PERIOD_INTERVAL); }
MINILABS: JOGOS EM JAVA
Jogo.java
private class Tarefa extends TimerTask { @Override public void run() { x += 1; y += 1; if (y > B_HEIGHT) { y = INITIAL_Y; x = INITIAL_X; } repaint(); } }
ANIMAÇÃO
Versão 6
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import javax.swing.*;
public class Jogo extends JPanel implements Runnable {
private final int B_WIDTH = 350;private final int B_HEIGHT = 350;private final int INITIAL_X = -40;private final int INITIAL_Y = -40;private final int DELAY = 25;private Image star;private Thread thread;private int x, y;
...}
MINILABS: JOGOS EM JAVA
THREAD
▸ O método run () é chamado apenas uma vez.
▸ loop chamamos de cycle() and the repaint()
▸ addNotify()
▸ executado após o JPanel foi adicionado ao componente JFrame.
▸ Este método é muitas vezes usado para diversas tarefas de inicialização.
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void addNotify() {super.addNotify();thread = new Thread(this);thread.start();
}
private void ciclo() {x += 1;y += 1;if (y > B_HEIGHT) {y = INITIAL_Y;x = INITIAL_X;
}}
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void run() {
long beforeTime, timeDiff, sleep;beforeTime = System.currentTimeMillis();while (true) {
ciclo();repaint();timeDiff = System.currentTimeMillis() - beforeTime;sleep = DELAY - timeDiff;if (sleep < 0) {
sleep = 2;}try {
Thread.sleep(sleep);} catch (InterruptedException e) {
System.out.println("Interrupted: " + e.getMessage());}beforeTime = System.currentTimeMillis();
}}
MINILABS: JOGOS EM JAVA
AGENDA
▸ Conceitos Básicos
▸ Animação
▸ Sprites
▸ Colisões
SPRITES
Versão 7
MINILABS: JOGOS EM JAVA
Aplicacao.java (Sem mudanças)
import java.awt.EventQueue;import javax.swing.JFrame;public class Aplicacao extends JFrame {private static final long serialVersionUID = 1L;public Aplicacao() {initUI();
}private void initUI() {...}public static void main(String[] args) {...}
}
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import java.awt.event.*;import javax.swing.*;
public class Jogo extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;private Timer timer;private Nave nave;private final int DELAY = 10;
public Jogo() {initJogo();
}...}
MINILABS: JOGOS EM JAVA
Jogo.java
private void initJogo() {addKeyListener(new TAdapter());setFocusable(true);setBackground(Color.BLACK);nave = new Nave();timer = new Timer(DELAY, this);timer.start();
}
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void paintComponent(Graphics g) {super.paintComponent(g);desenhar(g);Toolkit.getDefaultToolkit().sync();
}
private void desenhar(Graphics g) {Graphics2D g2d = (Graphics2D) g;g2d.drawImage(nave.getImage(), nave.getX(), nave.getY(), this);
}
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void actionPerformed(ActionEvent e) {nave.move();repaint();
}
private class TAdapter extends KeyAdapter {@Overridepublic void keyReleased(KeyEvent e) {nave.keyReleased(e);
}@Overridepublic void keyPressed(KeyEvent e) {nave.keyPressed(e);
}}
MINILABS: JOGOS EM JAVA
Nave.java
import java.awt.Image;import java.awt.event.KeyEvent;import javax.swing.ImageIcon;
public class Nave {private int dx;private int dy;private int x;private int y;private Image image;
public Nave() {initNave();
}...}
MINILABS: JOGOS EM JAVA
Nave.java
private void initNave() {ImageIcon ii = new ImageIcon("nave.png");image = ii.getImage();x = 40;y = 60;
}public void move() {x += dx;y += dy;
}public int getX() { return x; }public int getY() { return y; }public Image getImage() {return image; }
MINILABS: JOGOS EM JAVA
Nave.java
public void keyPressed(KeyEvent e) {int key = e.getKeyCode();if (key == KeyEvent.VK_LEFT) {dx = -1;
}if (key == KeyEvent.VK_RIGHT) {dx = 1;
}if (key == KeyEvent.VK_UP) {dy = -1;
}if (key == KeyEvent.VK_DOWN) {dy = 1;
}}
MINILABS: JOGOS EM JAVA
Nave.java
public void keyReleased(KeyEvent e) {int key = e.getKeyCode();if (key == KeyEvent.VK_LEFT) {dx = 0;
}if (key == KeyEvent.VK_RIGHT) {dx = 0;
}if (key == KeyEvent.VK_UP) {dy = 0;
}if (key == KeyEvent.VK_DOWN) {dy = 0;
}}
SPRITES
Versão 8
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import java.awt.event.*;import java.util.*;import javax.swing.*;public class Jogo extends JPanel implements ActionListener {private final int ICRAFT_X = 40;private final int ICRAFT_Y = 60;private final int DELAY = 10;private Timer timer;private Nave nave;
public Jogo() {initJogo();
}...}
MINILABS: JOGOS EM JAVA
Jogo.java
private void initJogo() {addKeyListener(new TAdapter());setFocusable(true);setBackground(Color.BLACK);setDoubleBuffered(true);nave = new Nave(ICRAFT_X, ICRAFT_Y);timer = new Timer(DELAY, this);timer.start();
}
MINILABS: JOGOS EM JAVA
Jogo.java
private void desenhar(Graphics g) {Graphics2D g2d = (Graphics2D) g;g2d.drawImage(nave.getImage(), nave.getX(), nave.getY(), this);ArrayList<?> ms = nave.getMissiles();for (Object m1 : ms) {Missil m = (Missil) m1;g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
}}
MINILABS: JOGOS EM JAVA
Jogo.java
@Overridepublic void actionPerformed(ActionEvent e) {updateMissiles();updateCraft();repaint();
}
MINILABS: JOGOS EM JAVA
Jogo.java
private void updateMissiles() {ArrayList<?> ms = nave.getMissiles();for (int i = 0; i < ms.size(); i++) {Missil m = (Missil) ms.get(i);if (m.isVisible()) {m.move();
} else {ms.remove(i);
}}
}
MINILABS: JOGOS EM JAVA
Jogo.java
private void updateCraft() {nave.move();
}
private class TAdapter extends KeyAdapter {@Overridepublic void keyReleased(KeyEvent e) {nave.keyReleased(e);
}@Overridepublic void keyPressed(KeyEvent e) {nave.keyPressed(e);
}}
MINILABS: JOGOS EM JAVA
Sprite.java
import java.awt.Image;import javax.swing.ImageIcon;
public class Sprite {
protected int x;protected int y;protected int width;protected int height;protected boolean vis;protected Image image;
public Sprite(int x, int y) {this.x = x;this.y = y;vis = true;
}...}
MINILABS: JOGOS EM JAVA
Sprite.java
protected void carregarImagem(String imageName) {
ImageIcon ii = new ImageIcon(imageName);image = ii.getImage();
}
protected void getImageDimensions() {
width = image.getWidth(null);height = image.getHeight(null);
}
MINILABS: JOGOS EM JAVA
Sprite.java
public Image getImage() {return image;
}
public int getX() {return x;
}
public int getY() {return y;
}
public boolean isVisible() {return vis;
}
public void setVisible(Boolean visible) {vis = visible;
}
MINILABS: JOGOS EM JAVA
Missil.java
public class Missil extends Sprite {
private final int BOARD_WIDTH = 390; private final int MISSILE_SPEED = 2;
public Missil(int x, int y) { super(x, y); initMissil(); } private void initMissil() { carrregarImagem("missil.png"); getImageDimensions(); } public void move() { x += MISSILE_SPEED; if (x > BOARD_WIDTH) { vis = false; } }}
MINILABS: JOGOS EM JAVA
Nave.java
import java.awt.event.KeyEvent;import java.util.ArrayList;
public class Nave extends Sprite { private int dx; private int dy; private ArrayList<Missil> missiles;
public Nave(int x, int y) { super(x, y); initNave(); }...}
MINILABS: JOGOS EM JAVA
Nave.java
private void initNave() { missiles = new ArrayList<Missil>(); carrregarImagem("nave.png"); getImageDimensions(); }
public void move() { x += dx; y += dy; }
MINILABS: JOGOS EM JAVA
Nave.java
public ArrayList<Missil> getMissiles() { return missiles; }
public void atira() { missiles.add(new Missil(x + width, y + height / 2)); }
MINILABS: JOGOS EM JAVA
Nave.java
public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_SPACE) { atira(); } if (key == KeyEvent.VK_LEFT) { dx = -1; } if (key == KeyEvent.VK_RIGHT) { dx = 1; } if (key == KeyEvent.VK_UP) { dy = -1; } if (key == KeyEvent.VK_DOWN) { dy = 1; } }
MINILABS: JOGOS EM JAVA
Nave.java
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) { dx = 0; }
if (key == KeyEvent.VK_RIGHT) { dx = 0; }
if (key == KeyEvent.VK_UP) { dy = 0; }
if (key == KeyEvent.VK_DOWN) { dy = 0; } }
MINILABS: JOGOS EM JAVA
AGENDA
▸ Conceitos Básicos
▸ Animação
▸ Sprites
▸ Colisões
COLISÃO
Versão 9
MINILABS: JOGOS EM JAVA
Inimigo.java
public class Inimigo extends Sprite { private final int INITIAL_X = 400;
public Inimigo(int x, int y) { super(x, y); initInimigo(); }
private void initInimigo() { carregaImagem("alien.png"); getImageDimensions(); }
public void move() { if (x < 0) { x = INITIAL_X; } x -= 1; }}
MINILABS: JOGOS EM JAVA
Sprite.java
public Rectangle getBounds() {return new Rectangle(x, y, width, height);
}
MINILABS: JOGOS EM JAVA
Jogo.java
import java.awt.*;import java.awt.event.*;import java.util.ArrayList;import javax.swing.*;
public class Jogo extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;private Timer timer;
private Nave nave; private ArrayList<Inimigo> aliens; private boolean ingame; private final int ICRAFT_X = 40; private final int ICRAFT_Y = 60; private final int B_WIDTH = 400; private final int B_HEIGHT = 300; private final int DELAY = 15;...}
MINILABS: JOGOS EM JAVA
Jogo.java
private final int[][] pos = { {2380, 29}, {2500, 59}, {1380, 89}, {780, 109}, {580, 139}, {680, 239}, {790, 259}, {760, 50}, {790, 150}, {980, 209}, {560, 45}, {510, 70}, {930, 159}, {590, 80}, {530, 60}, {940, 59}, {990, 30}, {920, 200}, {900, 259}, {660, 50}, {540, 90}, {810, 220}, {860, 20}, {740, 180}, {820, 128}, {490, 170}, {700, 30} };
MINILABS: JOGOS EM JAVA
Jogo.java
public Jogo() { initJogo(); }
private void initJogo() { addKeyListener(new TAdapter()); setFocusable(true); setBackground(Color.BLACK); ingame = true; setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); nave = new Nave(ICRAFT_X, ICRAFT_Y); initAliens(); timer = new Timer(DELAY, this); timer.start(); }
MINILABS: JOGOS EM JAVA
Jogo.java
public void initAliens() { aliens = new ArrayList<>(); for (int[] p : pos) { aliens.add(new Inimigo(p[0], p[1])); } }
MINILABS: JOGOS EM JAVA
Jogo.java
@Override public void paintComponent(Graphics g) { super.paintComponent(g); if (ingame) { drawObjects(g); } else { drawGameOver(g); } Toolkit.getDefaultToolkit().sync(); }
MINILABS: JOGOS EM JAVA
Jogo.java
private void drawObjects(Graphics g) { if (nave.isVisible()) { g.drawImage(nave.getImage(), nave.getX(), nave.getY(), this); } ArrayList<Missil> ms = nave.getMissiles(); for (Missil m : ms) { if (m.isVisible()) { g.drawImage(m.getImage(), m.getX(), m.getY(), this); } } for (Inimigo a : aliens) { if (a.isVisible()) { g.drawImage(a.getImage(), a.getX(), a.getY(), this); } } g.setColor(Color.WHITE); g.drawString("Inimigos restantes: " + aliens.size(), 5, 15); }
MINILABS: JOGOS EM JAVA
Jogo.java
private void drawGameOver(Graphics g) {
String msg = "Game Over"; Font small = new Font("Helvetica", Font.BOLD, 14); FontMetrics fm = getFontMetrics(small);
g.setColor(Color.white); g.setFont(small); g.drawString(msg, (B_WIDTH - fm.stringWidth(msg)) / 2, B_HEIGHT / 2); }
MINILABS: JOGOS EM JAVA
Jogo.java
@Override public void actionPerformed(ActionEvent e) { inGame(); updateNave(); updateMissils(); updateInimigo(); checkCollisions(); repaint(); }
MINILABS: JOGOS EM JAVA
Jogo.java
private void inGame() { if (!ingame) { timer.stop(); } }
private void updateNave() { if (nave.isVisible()) { nave.move(); } }
MINILABS: JOGOS EM JAVA
Jogo.java
private void updateMissils() {
ArrayList<Missil> ms = nave.getMissiles();
for (int i = 0; i < ms.size(); i++) {
Missil m = ms.get(i);
if (m.isVisible()) { m.move(); } else { ms.remove(i); } } }
MINILABS: JOGOS EM JAVA
Jogo.java
private void updateInimigos() {
if (aliens.isEmpty()) {
ingame = false; return; }
for (int i = 0; i < aliens.size(); i++) {
Inimigo a = aliens.get(i); if (a.isVisible()) { a.move(); } else { aliens.remove(i); } } }
MINILABS: JOGOS EM JAVA
Jogo.java public void checkCollisions() { Rectangle r3 = nave.getBounds(); for (Inimigo alien : aliens) { Rectangle r2 = alien.getBounds(); if (r3.intersects(r2)) { nave.setVisible(false); alien.setVisible(false); ingame = false; } } ArrayList<Missil> ms = nave.getMissiles(); for (Missil m : ms) { Rectangle r1 = m.getBounds(); for (Inimigo alien : aliens) { Rectangle r2 = alien.getBounds(); if (r1.intersects(r2)) { m.setVisible(false); alien.setVisible(false); } } } }
MINILABS: JOGOS EM JAVA
Jogo.java
private class TAdapter extends KeyAdapter {
@Override public void keyReleased(KeyEvent e) { nave.keyReleased(e); }
@Override public void keyPressed(KeyEvent e) { nave.keyPressed(e); } }
REFERENCIAS
▸ http://www.javaworld.com/article/2077754/core-java/swing-threading-and-the-event-dispatch-thread.html
▸ http://www.oracle.com/technetwork/articles/java/index-jsp-135444.html
▸ http://zetcode.com
▸ Salen. Katie; Zimmerman, Eric. Rules of Play: Game Design Fundamentals. MIT PRESS, 2004