10. diel - Programovanie jednoduchých Java GUI hier - Detekcia kolízií 2
Pokračovanie predchádzajúcej lekcie.
Vytvoríme si triedu štvorec.
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.util.Random; public class Ctverec { private final int DELKA_STRANY = 50; private int x, y; private Color barva; public Ctverec(int x, int y) { this.x = x; this.y = y; vyberBarvu(); } public void vykresliSe(Graphics g) { g.setColor(barva); g.drawRect(x, y, DELKA_STRANY, DELKA_STRANY); } private void vyberBarvu() { Random generator = new Random(); int nahodneCislo = generator.nextInt(4); switch (nahodneCislo) { case 0: barva = Color.blue; break; case 1: barva = Color.red; break; case 2: barva = Color.yellow; break; default: barva = Color.green; break; } } public int getX() { return x; } public int getY() { return y; } public Color getBarva() { return barva; } public Rectangle getOkraje() { return new Rectangle(x, y, DELKA_STRANY, DELKA_STRANY); } }
private final int DELKA_STRANY = 50;
Nami vytvorené štvorca budú veľké 50px.
private int x, y; private Color barva;
Deklarujeme premennej x, y, v ktorých bude úložný aktuálnej pozície. V premennej farba bude farba štvorca.
public void vykresliSe(Graphics g) { g.setColor(barva); g.drawRect(x, y, DELKA_STRANY, DELKA_STRANY); }
Metóde vykreslíš () objektu štvorec sa odovzdáva grafický kontext a na neho sa vykreslí aktuálnej štvorec.
private void vyberBarvu() { Random generator = new Random(); int nahodneCislo = generator.nextInt(4); switch (nahodneCislo) { case 0: barva = Color.blue; break; case 1: barva = Color.red; break; case 2: barva = Color.yellow; break; default: barva = Color.green; break; } }
Metóda vyberBarvu () nastaví hodnotu premennej farba na náhodne vybranú farbu (vyberá sa zo štyroch farieb).
public Rectangle getOkraje() { return new Rectangle(x, y, DELKA_STRANY, DELKA_STRANY); }
Metóda getOkraje () vracia oblasť, na ktorej sa nachádza aktuálny objekt štvorec.
Ďalej si vytvoríme triedu stíhača. Je podobná tej z predchádzajúceho príkladu, pribudla metóda getOkraje (), ktorá rovnako vracia oblasť, kde sa nachádza objekt stíhača. Počiatočná hodnota x, y je stanovená napevno a ľahko sa zmenila metóda move ().
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class Chytac implements KeyListener { private Color barva = Color.white; private final int SIRKA = 50; private final int VYSKA = 10; private int x, y, smerX, smerY, rychlost; private MujPanel panel; public Chytac(MujPanel panel) { this.rychlost = 3; this.panel = panel; this.x = 175; this.y = 150; } public void vykresliSe(Graphics g) { g.setColor(barva); g.drawRect(x, y, SIRKA, VYSKA); System.out.println(panel.getWidth()); } public void move() { x += smerX; y += smerY; if ((x >= panel.getSIRKA_PANELU() - (SIRKA + 1)) && (panel.getSIRKA_PANELU() > 0)) { x = panel.getSIRKA_PANELU() - (SIRKA + 1); } if (x <= 0) { x = 0; } if ((y >= panel.getVYSKA_PANELU() - (VYSKA + 1)) && (panel.getVYSKA_PANELU() >0)) { y = panel.getVYSKA_PANELU() - (VYSKA + 1); } if (y <= 0) { y = 0; } } @Override public void keyPressed(KeyEvent e) { int klavesa = e.getKeyCode(); if (klavesa == KeyEvent.VK_LEFT) { smerX = -rychlost; } else if (klavesa == KeyEvent.VK_UP) { smerY = -rychlost; } else if (klavesa == KeyEvent.VK_RIGHT) { smerX = rychlost; } else if (klavesa == KeyEvent.VK_DOWN) { smerY = rychlost; } } @Override public void keyReleased(KeyEvent e) { int klavesa = e.getKeyCode(); if (klavesa == KeyEvent.VK_LEFT) { smerX = 0; } else if (klavesa == KeyEvent.VK_UP) { smerY = 0; } else if (klavesa == KeyEvent.VK_RIGHT) { smerX = 0; } else if (klavesa == KeyEvent.VK_DOWN) { smerY = 0; } } @Override public void keyTyped(KeyEvent e) { } public Rectangle getOkraje() { return new Rectangle(x, y, SIRKA, VYSKA); } }
Nasleduje trieda MujPanel.
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.JPanel; import javax.swing.Timer; public class MujPanel extends JPanel { private final int SIRKA_CTVERCE = 400; private final int VYSKA_CTVERCE = 300; private final int POCET_CTVERCU = 10; private Ctverec[] poleCtvercu; private Chytac chytac; public MujPanel() { this.poleCtvercu = new Ctverec[POCET_CTVERCU]; this.chytac = new Chytac(this); this.setPreferredSize(new Dimension(SIRKA_CTVERCE, VYSKA_CTVERCE)); this.setBackground(Color.black); this.addKeyListener(chytac); this.setFocusable(true); Random generator = new Random(); for (int i = 0; i < poleCtvercu.length; i++) { int x = generator.nextInt(SIRKA_CTVERCE - 50); int y = generator.nextInt(VYSKA_CTVERCE - 50); Ctverec c = new Ctverec(x, y); poleCtvercu[i] = c; } Timer casovac = new Timer(10, new PosluchacCasovace()); casovac.start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < poleCtvercu.length; i++) { if (poleCtvercu[i] != null) { poleCtvercu[i].vykresliSe(g); } } chytac.vykresliSe(g); } private class PosluchacCasovace implements ActionListener { @Override public void actionPerformed(ActionEvent e) { chytac.move(); for (int i = 0; i < poleCtvercu.length; i++) { if (poleCtvercu[i] != null) { // if (chytac.getOkraje().intersects(poleCtvercu[i].getOkraje())) Rectangle okrajeChytace = chytac.getOkraje(); Rectangle okrajeCtverce = poleCtvercu[i].getOkraje(); if (okrajeChytace.intersects(okrajeCtverce)) { poleCtvercu[i] = null; } } } repaint(); } } public int getSIRKA_PANELU() { return this.getWidth(); } public int getVYSKA_PANELU() { return this.getHeight(); } }
Random generator = new Random(); for (int i = 0; i < poleCtvercu.length; i++) { int x = generator.nextInt(SIRKA_CTVERCE - 50); int y = generator.nextInt(VYSKA_CTVERCE - 50); Ctverec c = new Ctverec(x, y); poleCtvercu[i] = c; }
V cykle vytváram objekty typu Cverec a referenciu na ne ukladám do poľa poleCtvercu.
@Override public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < poleCtvercu.length; i++) { if (poleCtvercu[i] != null) { poleCtvercu[i].vykresliSe(g); } } chytac.vykresliSe(g); }
V metóde paintComponent () najskôr volám rodičovskú metódu, ktorá mi vykreslí pozadia. Potom prechádzam poľom, v ktorom mám uložené objekty typu štvorec. Ak je na danom indexe štvorec (index nie je null), zavolám jeho metódu vykreslíš a odovzdám jej grafický kontext. Výsledkom je, že každý štvorec v poli dostane grafický kontext, na ktorý sa vykreslí. Nakoniec volám kresliace metódu objektu stíhača.
private class PosluchacCasovace implements ActionListener { @Override public void actionPerformed(ActionEvent e) { chytac.move(); for (int i = 0; i < poleCtvercu.length; i++) { if (poleCtvercu[i] != null) { // if (chytac.getOkraje().intersects(poleCtvercu[i].getOkraje())) Rectangle okrajeChytace = chytac.getOkraje(); Rectangle okrajeCtverce = poleCtvercu[i].getOkraje(); if (okrajeChytace.intersects(okrajeCtverce)) { poleCtvercu[i] = null; } } } repaint(); } }
Pri každej udalosti ActionEvent, ktorá je vygenerovaná objektom Timer, sa volá metóda actionPerformed objektu PosluchacCasovace. Tá najskôr zavolá metódu move () objektu stíhača, ktorá vykoná zmeny v pozícii stíhača. Potom v cykle prechádzam poľom s uloženými objektmi štvorec a kontoluji, či sa okraje daného štvorca neprekrývajú s okrajmi stíhača. Ak áno, index, na ktorom sa nachádza tento ctverec, zmením na null. Tým pádom štvorec pre mňa prestáva existovať.
Spúšťacie trieda s hlavným oknom programu zostala nezmenená.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 315x (3.08 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java