IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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á.

Detekovanie kolízií objektov v jednoduchej Java hre - Tvorba hier v Java Swing

 

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

 

Predchádzajúci článok
Programovanie jednoduchých Java GUI hier - Detekcia kolízií
Všetky články v sekcii
Tvorba hier v Java Swing
Preskočiť článok
(neodporúčame)
Programovanie jednoduchých Java GUI hier - Zoznamy
Článok pre vás napísal vita
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
vita
Aktivity