IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 10 - Programování jednoduchých Java GUI her - Detekce kolizí 2

V minulé lekci, Programování jednoduchých Java GUI her - Detekce kolizí, jsme si ukázali, jak detekovat kolize objektů pomocí třídy Rectangle a metody Intersect.

Dnes budeme pokračovat tam, kde jsme minule skončili.

Vytvoříme si třídu Ctverec.

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;

Námi vytvořené čtverce budou veliké 50px.

private int x, y;
private Color barva;

Deklarujeme proměnné x, y, ve kterých bude uložna aktuální pozice. V proměnné barva bude barva čtverce.

public void vykresliSe(Graphics g) {
    g.setColor(barva);
    g.drawRect(x, y, DELKA_STRANY, DELKA_STRANY);
}

Metodě vykresliSe() objektu Ctverec se předává grafický kontext a na něj se vykreslí aktuální Ctverec.

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;
    }
}

Metoda vyberBarvu() nastaví hodnotu proměnné barva na náhodně vybranou barvu (vybírá se ze čtyř barev).

public Rectangle getOkraje() {
    return new Rectangle(x, y, DELKA_STRANY, DELKA_STRANY);
}

Metoda getOkraje() vrací oblast, na které se nachází aktuální objekt Ctverec.

Dále si vytvoříme třídu Chytac. Je podobná té z předchozího příkladu, přibyla metoda getOkraje(), která stejně vrací oblast, kde se nachází objekt Chytac. Počáteční hodnota x, y je stanovena napevno a lehce se změnila metoda 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);
    }
}

Následuje třída 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 cyklu vytvářím objekty typu Cverec a referenci na ně ukládám do pole 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 metodě paintComponent() nejdříve volám rodičovskou metodu, která mi vykreslí pozadí. Pak procházím polem, ve kterém mám uloženy objekty typu Ctverec. Pokud je na daném indexu Ctverec (index není null), zavolám jeho metodu vykresliSe a předám jí grafický kontext. Výsledkem je, že každý Ctverec v poli dostane grafický kontext, na který se vykreslí. Nakonec volám kreslící metodu objektu Chytac.

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();
    }
}

Při každé události ActionEvent, která je vygenerovaná objektem Timer, se volá metoda actionPerformed objektu PosluchacCasovace. Ta nejdříve zavolá metodu move() objektu Chytac, která provede změny v pozici chytace. Pak v cyklu procházím polem s uloženými objekty Ctverec a kontoluji, zda se okraje daného Ctverce nepřekrývají s okraji chytace. Pokud ano, index, na kterém se nachází tento ctverec, změním na null. Tím pádem Ctverec pro mne přestává existovat.

Spouštěcí třída s hlavním oknem programu zůstala nezměněna.

Detekování kolizí objektů v jednoduché Java hře - Tvorba her v Java Swing

V příští lekci, Programování jednoduchých Java GUI her - Seznamy, se blíže podíváme na seznamy objektů a uvedeme si třídu ArrayList.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 313x (3.08 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Programování jednoduchých Java GUI her - Detekce kolizí
Všechny články v sekci
Tvorba her v Java Swing
Přeskočit článek
(nedoporučujeme)
Programování jednoduchých Java GUI her - Seznamy
Článek pro vás napsal vita
Avatar
Uživatelské hodnocení:
11 hlasů
vita
Aktivity