intro Java Spiel K6 vasabii_Fotolia_70882828

Java Spiel Programmieren Tutorial – Teil 6: Die gegnerischen Panzer des Java Spiels programmieren


Nun wünschen wir euch viel Spaß beim sechsten Teil unseres Java Spiel Programmieren Tutorials. Los geht’s!

1. Erstellen der EnemyTank-Klasse, den gegnerischen Panzern unseres Java Spiels

Android Apps Programmieren Online-Kurs

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Wir werden nun eine weitere Klasse unserem Java Projekt hinzufügen. Die neue Klasse wird den Namen EnemyTank tragen und den Bauplan für die gegnerischen Panzer in unserem Java Spiel bereitstellen.

Um die EnemyTank-Klasse zu erstellen, werden wir die folgenden beiden Arbeitsschritte ausführen:

  1. Anlegen der Klassendatei in NetBeans – Zuerst erstellen wir mit Hilfe der Entwicklungsumgebung NetBeans IDE die Klasse EnemyTank.

  2. Definieren der EnemyTank-Klasse – Im zweiten Schritt programmieren wir die neu erstellte Klasse aus. Die EnemyTank-Klasse ist nicht sehr groß, da sie die meisten Eigenschaften und Fähigkeiten von der Tank-Klasse erbt. In ihr werden wir eine neue Fähigkeit diesem speziellen Spielobjekt hinzufügen, das automatische Zielen und Schießen auf den Spielerpanzer.

Beginnen wir nun mit dem ersten Arbeitsschritt, dem Anlegen der EnemyTank.java Klassendatei.


1.1 Anlegen der Klassendatei EnemyTank.java in NetBeans

Die Klasse EnemyTank legen wir wie folgt an:

  1. Wir klicken mit der rechten Maustaste auf den Haupt-Packagenamen in der Projektleiste.
  2. Danach auf den New-Eintrag im Kontextmenü klicken.
  3. Anschließend auf den Eintrag Java Class... klicken.
java spiel k6 neue klasse anlegen

Eine neue Klasse unserem Java Projekt in NetBeans hinzufügen

Daraufhin öffnet sich der New Java Class-Dialog von NetBeans. In diesem Dialog geben wir als Namen der zu erstellenden Klasse EnemyTank ein.

Alle anderen Einstellungen lassen wir unverändert und bestätigen den Dialog mit einem Klick auf Finish.

java spiel k6 neue klasse enemytank

Der New Java Class Dialog von NetBeans

Jetzt generiert NetBeans eine neue Java-Datei mit dem Namen EnemyTank.java und fügt sie in das Hauptpaket unseres Java Projekts ein. Dies sollte bei euch wie folgt aussehen:

java spiel k6 neue klasse enemytank start

Die neu erstellte Java Klasse EnemyTank – Sie stellt den Bauplan für die gegnerischen Panzer im Spiel bereit

Die neue Klasse EnemyTank ist momentan noch leer. Das werden wir nun ändern und sie mit Quellcode füllen.

1.2 Definieren der EnemyTank-Klasse

Die Klassendatei EnemyTank.java haben wir nun mit Hilfe von NetBeans in unserem Java Projekt angelegt. Als Nächstes werden wir die EnemyTank-Klasse ausprogrammieren, also den Klassenbereich mit Variablen und Methoden füllen.

Dazu fügen wir den folgenden Quellcode in die EnemyTank-Klasse ein und ersetzen damit den generierten Code:

EnemyTank.java

package de.programmierenlernenhq.panzerhq;

import java.awt.Color;

public class EnemyTank extends Tank{
    
    private Tank playersTank; 
    private boolean targetLocked = false;
    

    public EnemyTank(Coordinate position, double width, double height, double movingAngle, double movingDistance, Tank playersTank) {
        super(position, width, height, movingAngle, movingDistance);        
        this.playersTank = playersTank;
        
        setTurningVelocity(TURNING_VELOCITY/10 + Math.random() * 0.01);
        setDrivingVelocity(DRIVING_VELOCIY/10 + Math.random() * 1.0);
        setLoadingTime(AMMO_LOADING_TIME*2);                
        setTurretColor(new Color (190,124,68));
        
        int enemyTankEnergy = (int)(width/10 + Math.random()*5);
        setEnergy(enemyTankEnergy);
        setEnergyStart(enemyTankEnergy);
        
        accelerateTank();
    }
    
    
    public Tank getPlayersTank() {
        return playersTank;
    }
    public void setPlayersTank(Tank playersTank) {
        this.playersTank = playersTank;
    }

    public boolean isTargetLocked() {
        return targetLocked;
    }
    public void setTargetLocked(boolean targetLocked) {
        this.targetLocked = targetLocked;
    }
    
    
    @Override
    public void makeMove() {
        
        if (getObjectPosition().getX() > 800 || getObjectPosition().getY() < 200) {
            stopTank();
        }        
        aimAtPlayer();  
        
        super.makeMove();        
    }    
    
    public void aimAtPlayer() {
        
        // Die Position des Mittelpunkts des Spielerpanzers auf der Spielfläche 
        double playersTankCenterX = playersTank.getObjectPosition().getX() + playersTank.getWidth()/2;
        double playersTankCenterY = playersTank.getObjectPosition().getY() + playersTank.getHeight()/2;
        
        // Die Position des Mittelpunkts des gegnerischen Panzers auf der Spielfläche
        double enemyTankCenterX = getObjectPosition().getX() + getWidth()/2;
        double enemyTankCenterY = getObjectPosition().getY() + getHeight()/2;
        
        // Berechnung des Winkels vom gegnerischen Panzer zum Spielerpanzer
        double x = playersTankCenterX - enemyTankCenterX;
        double y = playersTankCenterY - enemyTankCenterY;
        double angleToPlayer = Math.atan2(y, x);
        if (angleToPlayer < 0) angleToPlayer = angleToPlayer + 2 * Math.PI;  
        
        // Winkel in den die Kanone des gegnerischen Panzers zeigt
        double absoluteCannonAngle = getAngleCannon() + getMovingAngle();        
        if (absoluteCannonAngle > 2 * Math.PI) absoluteCannonAngle = absoluteCannonAngle - 2 * Math.PI;

        // Wie weit weicht der Kanonenwinkel von der Position des Spielerpanzers ab
        double deltaAngle = angleToPlayer - absoluteCannonAngle; 
        
        if (Math.abs(deltaAngle) <= 0.01) {
            setTargetLocked(true);
            stopTurningCannon();
        }
        else {
            setTargetLocked(false);
            if (deltaAngle < 0.01) {
                turnCannonLeft();
                if (Math.abs(deltaAngle) > Math.toRadians(180)) {
                    turnCannonRight();
                }
            }
            if (deltaAngle > 0.01) {
                turnCannonRight();
                if (Math.abs(deltaAngle) >  Math.toRadians(180)) {
                    turnCannonLeft();
                }
            }
        }
    }        
}

Die Klasse EnemyTank leiten wir in Zeile 5 von der Klasse Tank ab. Dadurch erbt die neue Klasse alle Eigenschaften und Fähigkeiten von der Klasse Tank und auch der Klasse GameObject, von der sich die Tank-Klasse wiederum ableitet.

Die beiden Membervariablen definieren wir in den Zeilen 7 und 8. Wir verwenden sie, um auf den Spielerpanzer zielen zu können. Aus der Variable playersTank lesen wir die Position des Spielerpanzers auf dem Spielfeld aus. Mit der Variable targetLocked halten wir fest, ob die Kanone auf den Spielerpanzer zeigt und somit das Ziel erfasst ist.

In den Zeilen 11 bis 25 definieren wir den Konstruktor der EnemyTank-Klasse, in dem wir hauptsächlich die Eigenschaften des zu erzeugenden gegnerischen Panzerobjekts vorgeben. Die Werte für Fahrgeschwindigkeit, Drehgeschwindigkeit und Nachladedauer vergeben wir zufällig mit Hilf der Methode Math.random(). Abschließend geben wir den accelerateTank(), wodurch der gegnerische Panzer in Bewegung gesetzt wird.

In den Zeilen 28 bis 40 definieren wir die Getter– und Setter-Methoden der beiden Klassenattribute. Anschließend überschreiben wir die makeMove() Methode mit den Zeilen 44 bis 52.

Die makeMove() jedes Spielobjekts wird pro Spielzyklus einmal von dem GamePanel-Objekt aufgerufen. In ihr führen wir den Spielzug des jeweiligen Spielobjekts aus. In diesem Fall stoppen wir den gegnerischen Panzer, sobald er seine Zielposition erreicht hat. Außerdem lassen wir ihn nach dem Spielerpanzer zielen. Mit dem Aufruf der makeMove() Methode der Superklasse Tank, delegieren wir das tatsächliche Bewegen des Panzers und seiner Kanone an die Implementierung der Vaterklasse.

Schließlich definieren wir die aimAtPlayer() Methode mit den Zeilen 54 bis 96. Diese Methode sieht auf den ersten Blick etwas komplex aus, ist aber relativ einfach, wenn man die zugrunde liegende Mathematik verstanden hat. Wie der Methodenname erwarten lässt, ist die Aufgabe dieser Methode den gegnerischen Panzer auf den Spielerpanzer zielen zu lassen.

Dazu wird zuerst die der Mittelpunkt des Spielerpanzers auf der Spielfläche bestimmt und danach die des gegnerischen Panzers. Durch Subtraktion dieser beiden Koordinatenpaare erhalten wir einen Vektor der in Richtung des Spielerpanzers, vom gegnerischen Panzer aus betrachtet, zeigt. Mit Hilfe der Arkustangensfunktion Math.atan2() von Java können wir aus den Komponenten des berechneten Richtungsvektors den entsprechenden Richtungswinkel berechnen.

Zieht man von diesem Richtungswinkel den Kanonenwinkel des gegnerischen Panzers ab, dann erhält man als resultierenden Winkel die Abweichung vom Ziel. Also wie viel Grad die Kanone des gegnerischen Panzer vom Ziel, dem Spielerpanzer, abweicht. Diesen Wert speichern wir in der Variabel deltaAngle.

Nimmt diese einen Wert kleiner gleich 0,01 an, gilt das Ziel als erfasst und wir setzen die Variable targetLocked auf true. Ist der Wert von deltaAngle größer als 0,01 oder kleiner als -0,01, lassen wir die Kanone in Richtung des Ziels drehen.

Dabei behandeln wir auch den Sonderfall, wenn der Spielerpanzer sich im Rücken des gegnerischen Panzers befindet. Sobald der Spielerpanzer genau hinter der gegnerischen Kanonenrichtung ist, lassen wir die Kanone in die Richtung der kürzeren Strecke drehen. Solange die Kanone den Spielerpanzer mit einer Drehbewegung verfolgt, ist die Variable targetLocked auf false gesetzt.

Weitere Informationen über die Arkustangensfunktion allgemein und die Math.atan2() Methode könnt ihr über folgende Links finden:

In NetBeans sollte die EnemyTank-Klasse nun wie folgt aussehen:

java spiel k6 neue klasse enemytank end

Die Klasse EnemyTank mit dem eingefügten Quellcode

In der oberen Abbildung haben wir einige Markierungen vorgenommen. Wir möchten damit auf einige wichtige Bestandteile der EnemyTank-Klasse hinweisen:

  • A: Die Membervariablen mit ihren Getter/Setter-Methoden – Die beiden Variablen playersTank und targetLocked verwenden wir in der Methode aimAtPlayer(), um den Spielerpanzer anzuvisieren.
  • B: Der Konstruktor der EnemyTank-Klasse – Mit dem Konstruktor erzeugen wir das EnemyTank-Objekt. Dabei nutzen wir auch den Konstruktor der Superklasse Tank mit Hilfe des Schlüsselworts super.
  • C: Die Methoden makeMove() und aimAtPlayer() – Wir überschreiben die Methode makeMove() und führen mit ihr den Spielzug des gegnerischen Panzers aus. Dabei rufen wir auch die makeMove() Methode der Superklasse Tank mit der Anweisung super.makeMove() auf. Mit der Methode aimAtPlayer() lassen wir den gegnerischen Panzer auf den Spielerpanzer zielen.

Mit dem Anlegen der EnemyTank-Klasse haben wir nun die Möglichkeit gegnerische Panzer in unserem Java Spiels anzulegen. Im nächsten Abschnitt werden wir ein Objekt vom Typ EnemyTank erzeugen und es gegen den Spielerpanzer kämpfen lassen.

2. Anpassen der GamePanel-Klasse und Erzeugen eines gegnerischen Panzers

Wir werden nun ein EnemyTank-Spielobjekt erzeugen und dieses über die virtuelle Spielfläche fahren lassen. Es wird den Spielerpanzer ins Visier nehmen und nach ihm feuern. Natürlich können wir den gegnerischen Panzer auch selbst bekämpfen.

Um das EnemyTank-Spielobjekt zu erzeugen, nehmen wir folgende Änderungen an der GamePanel-Klasse vor:

  1. Deklarieren des EnemyTank-Objekts als Membervariable der GamePanel-Klasse.
  2. Instanziieren des EnemyTank-Objekts in der createGameObjects() Methode.
  3. Ausführen des Spielzugs des gegnerischen Panzers durch Aufrufen seiner makeMove() Methode in der doOnTick() Methode.
  4. Zeichnen des EnemyTank-Objekts durch Aufrufen seiner paintMe() Methode in der paintComponent() Methode.

Wie zu sehen ist, werden wir den Quellcode der GamePanel-Klasse an vier Stellen erweitern. Es werden nur kleine Änderungen sein. Wichtig ist, dass diese an der korrekte Stelle der GamePanel-Klasse vorgenommen werden.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Wir öffnen nun die Klassendatei GamePanel.java im Editorfenster von NetBeans und fügen die markierten Zeilen in den bereits vorhandenen Quellcode ein:

GamePanel.java

package de.programmierenlernenhq.panzerhq;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import static java.awt.event.KeyEvent.*;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GamePanel extends JPanel{
    
    private Missile testMissileOne;
    private Missile testMissileTwo;    
    
    // In Lektion 5 eingefügt
    private Tank testTank;
    
    // In Lektion 6 eingefügt
    private EnemyTank testEnemyTank;

    public static final String IMAGE_DIR = "images/";
    
    private final Dimension prefSize = new Dimension(1180, 780);
    
    private ImageIcon backgroundImage;
    private final String[] backgroundImages= new String [] {"bg_mud.jpg", 
                                                            "bg_snow.jpg", 
                                                            "bg_sand.jpg"};
    
    private boolean gameOver = false;
    private int tanksDestroyedCounter = 0;
    
    private Timer t;  
    
    
    public GamePanel() {        
        setFocusable(true);
        setPreferredSize(prefSize);
        
        initGame();         
        startGame();
    }
    
    
    public boolean isGameOver() {
        return gameOver;
    }

    public void setGameOver(boolean gameOver) {
        this.gameOver = gameOver;
    }
    
    private void initGame () {
        setBackgroundImage(1);
        createGameObjects();
        
        // In Lektion 5 eingefügt
        initPlayersTank();
        
        t = new Timer(20, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                doOnTick();     
            }
        });
        
        // In Lektion 5 Kapitel 2 eingefügt
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                
                switch(e.getKeyCode()) {
                    case VK_SPACE: 
                        if (testTank.isAbleToShoot()) {
                            testMissileOne = testTank.shoot();    
                        }                            
                        break;
                        
                    case VK_DOWN:                         
                    case VK_UP: testTank.stopTank(); break;
                        
                    case VK_LEFT:
                    case VK_RIGHT: testTank.stopTurningTank(); break;
                        
                    case VK_W:
                    case VK_E: testTank.stopTurningCannon(); break;
                }
            }
            
            @Override
            public void keyPressed(KeyEvent e) {
                switch(e.getKeyCode()) {                    
                    case VK_LEFT: testTank.turnTankLeft(); break;
                    case VK_RIGHT: testTank.turnTankRight(); break;
                        
                    case VK_UP: testTank.accelerateTank(); break;
                    case VK_DOWN: testTank.decelerateTank(); break;
                        
                    case VK_W: testTank.turnCannonLeft(); break;
                    case VK_E: testTank.turnCannonRight(); break;
                }
            }
        });
    }
    
    private void createGameObjects() {
        // hier werden wir später die Spielobjekte erzeugen
        testMissileOne = new Missile(new Coordinate(200,100), 9, Math.toRadians(45), 5);
        testMissileTwo = new Missile(new Coordinate(200,609), 9, Math.toRadians(-45), 5);
        
        // In Lektion 6 eingefügt
        testEnemyTank = new EnemyTank(new Coordinate(40,600), 80, 50, Math.toRadians(-20), 0, testTank);
    }
    
    private void initPlayersTank() {        
        // hier werden wir den Panzer des Spielers initialisieren
        
        // In Lektion 5 eingefügt
        testTank = new Tank(new Coordinate(630,260), 70, 45, Math.toRadians(270), 0);
        
        // In Lektion 5 Kapitel 2 auskommentiert
        //testTank.accelerateTank();
        //testTank.turnTankLeft();
        //testTank.turnCannonRight();
        //testMissileOne = testTank.shoot();
    }
    
    public void setBackgroundImage(int imageNumber) {
        String imagePath = IMAGE_DIR + backgroundImages[imageNumber];
        URL imageURL = getClass().getResource(imagePath);        
        backgroundImage = new ImageIcon(imageURL);
    }
    
    private void startGame() {
        t.start();
    }
    
    public void pauseGame() {
        t.stop();
    }
    
    public void continueGame() {
        if (!isGameOver()) t.start();
    }
    
    public void restartGame() {
        tanksDestroyedCounter = 0;
        setGameOver(false);
        createGameObjects();
        startGame();
    }
    
    private void endGame() { 
        setGameOver(true);
        pauseGame();
    }
    
    private void doOnTick() {        
        tanksDestroyedCounter++;
        if (tanksDestroyedCounter > 2015) endGame();
        
        testMissileOne.makeMove();
        testMissileTwo.makeMove();  
        
        // In Lektion 5 auskommentiert
        //if (testMissileOne.touches(testMissileTwo)) endGame();
        
        // In Lektion 5 eingefügt
        testTank.makeMove();
        if (testTank.touches(testMissileTwo)) endGame();                
        
        // In Lektion 5 Kapitel 2 auskommentiert
        //if (testTank.isAbleToShoot()) testMissileOne = testTank.shoot();
        
        
        
        // In Lektion 6 auskommentiert
        //if(testMissileTwo.getRange() < 1) testMissileTwo = new Missile(new Coordinate(200,609), 9, Math.toRadians(-45), 5);
        
        // In Lektion 6 eingefügt 
        testEnemyTank.setPlayersTank(testTank);
        testEnemyTank.makeMove();
        if (testEnemyTank.isTargetLocked() && testEnemyTank.isAbleToShoot()) testMissileTwo = testEnemyTank.shoot();
        if (testEnemyTank.touches(testMissileOne)) endGame();
        
        repaint();
    }
    
    @Override
    public void paintComponent (Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
           
        backgroundImage.paintIcon(null, g, 0, 0); 
                
        g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 19));            
        g.setColor(Color.BLUE);
        g.drawString("Tanks destroyed: " + tanksDestroyedCounter, 22 , prefSize.height - 5);        
                
        if (isGameOver()) {
            g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 50));
            g.setColor(Color.RED);
            g.drawString("GAME OVER!", prefSize.width/2 - 130, prefSize.height/5);
        }      
        
        // In Lektion 5 eingefügt
        testTank.paintMe(g);
        
        // In Lektion 6 eingefügt
        testEnemyTank.paintMe(g);
                
        testMissileOne.paintMe(g);
        testMissileTwo.paintMe(g); 
    }
        
}

Die im oberen Quellcode vorgenommenen Änderung sind sehr einfach. Besonders aufpassen muss man bei den Änderungen in der Methode doOnTick(). In dieser Methode muss neben dem Einfügen von vier neuen Zeilen Quellcode auch eine bereits vorhandene Zeile auskommentiert werden.

Dabei handelt es sich um die Anweisung in Zeile 187, die nicht mehr benötigt wird und daher auskommentiert werden muss.

In NetBeans sollte der Quellcode der GamePanel.java Klassendatei nun wie folgt aussehen:

java spiel k6 klasse gamepanel

Die Klasse GamePanel mit dem zusätzlich eingefügten Quellcode

In der oberen Abbildung haben wir die in den Quellcode der GamePanel-Klasse neu eingefügten Anweisungen jeweils mit einem blauen Rahmen markiert:

  • A: Deklaration der Membervariable vom EnemyTank-Datentyp – Zu Testzwecken legen wir einen gegnerischen Panzer als Attribute der GamePanel-Klasse an.
  • B: Instanziieren des EnemyTank-Objekts – In der createGameObjects() Methode erzeugen wir das EnemyTank-Objekt und weisen es der Membervariablen zu.
  • C: Ausführen des Spielzugs des Spielobjekts durch Aufrufen der makeMove() Methode, Schießen und Prüfen auf Kollision – Mit dem Aufruf der makeMove() Methode lassen wir das Spielobjekt seinen Spielzug durchführen. Außerdem lassen wir den gegnerischen Panzer schießen und prüfen, ob er von einem Geschoss getroffen wurde. Ist dies der Fall, beenden wir das Java Spiel und lassen GAME OVER! anzeigen.
  • D: Zeichnen des Spielobjekts durch Aufrufen der paintMe() Methode – Damit der gegnerische Panzer auf der Spielfläche auch zu sehen ist, müssen dieser gezeichnet werden. Das Zeichnen lassen wir vom Spielobjekt selbst ausführen, durch Aufrufen der paintMe() Methode.

2.1 Die Klassendateien unseres Java Projekts zum Download

Somit haben wir alle Änderungen am Quellcode unseres Java Spiels für diese Lektion vorgenommen. Diesmal haben wir eine neue Klassen angelegt und an einer bestehenden Klasse Änderungen vorgenommen. Damit es nicht zu Missverständnissen kommt, haben wir unten alle Klassendateien zum Download bereitgestellt.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Ihr solltet noch einmal in Ruhe den kompletten Quellcode der aufgelisteten Klassendateien unseres Java Spiels anschauen und mit eurem vergleichen:

PanzerHQ.java
GameWindow.java
GamePanel.java
Coordinate.java
GameObject.java
Missile.java
Tank.java
EnemyTank.java

Als Nächstes werden wir unser Java Spiel starten und das erste Mal gegen einen gegnerischen Panzer antreten.

3. Testen unseres Java Spiels und des gegnerischen Panzers

Wir führen nun unser Java Projekt mit einem Klick auf das Run Project-Symbol aus.

java spiel entwickeln projekt starten

Starten unseres Java Projekts über den Run Projekt Button

Im Hintergrund wird jetzt unser Java Spiel von der NetBeans IDE erstellt und anschließend ausgeführt.

Diesmal begegnen wir unseren ersten Gegner. Der gegnerische Panzer fährt über die Spielfläche und zielt automatisch auf unseren Panzer. Wir können den Spielerpanzer mit den Pfeiltasten steuern. Den Panzerturm können wir mit den Tasten W und E nach links bzw. rechts drehen. Geschosse werden mit der Leertaste abgefeuert.

java spiel k6 enemytank

Das Spielfenster unseres Java Spiels jetzt mit einem gegnerischen Panzer der uns angreift

In der oberen Abbildung ist der Spielerpanzer am rechten Spielfeldrand zu sehen. Wir hatten gerade ein Geschoss abgefeuert und damit den Nachladevorgang gestartet. Dies erkennt man an dem schmalen grauen Balken über der Energieanzeige des Panzers.

Von der linken Seite nähert sich der gegnerische Panzer, der den Spielerpanzer bereits als Ziel erfasst hat und eifrig Geschosse in seine Richtung abfeuert.

3.1 Video – Funktionspräsentation unseres Java Spiels

In dem unteren Video ist das Spielfenster unseres selbst programmierten Java Spiels zu sehen. Wir sind in der Lage den Spielerpanzer selbst über die Spielfläche zu steuern. Auch die verbesserte Kollisionsabfrage ist jetzt implementiert, mit deren Hilfe wir Panzerabschüsse exakter erkennen können.

Neu hinzugekommen ist ein gegnerischer Panzer der von links nach rechts über das Spielfeld fährt. Der gegnerische Panzer zielt selbständig auf den Spielerpanzer und eröffnet das Feuer, sobald er ihn ins Visier genommen hat.

Die neuen Funktionen unseres Java Spiels haben wir im unteren Video vorgeführt:

Zu Beginn des Videos erklären wir noch einmal die Steuerung des Spielerpanzers. Dabei werden wir von einem generischen Spielerpanzer unter Beschuss genommen. Wir weichen einigen gegnerischen Geschossen aus, bis wir den final Schuss abgeben.

Als der gegnerische Panzer von unserem Geschoss getroffen wird, detektiert unser Java Spiel den Abschuss und endet unmittelbar danach. Zu Testzwecken geben wir dann GAME OVER! in dem Spielfenster aus.

Zusammenfassung

In der sechsten Lektion unseres Java Spiel Programmieren Tutorials haben wir die Klasse EnemyTank erstellt. Die EnemyTank-Klasse repräsentiert die gegnerischen Panzer in unserem Java Spiel.

Die neue Klasse haben wir von der Tank-Klasse abgeleitet und dadurch die grundlegenden Eigenschaften von Spielobjekten und Panzern geerbt. Zusätzlich haben wir neue spezielle Eigenschaften und Fähigkeiten, wie das automatische Zielen und Schießen auf den Spielerpanzer, in ihr der EnemyTank-Klasse realisiert.

Um gegnerische Panzer auf der Spielfläche zu erzeugen, haben wir einige Änderungen an der GamePanel-Klasse vorgenommen. Wir haben zu Testzwecken einen gegnerischen Panzer von links nach rechts über das Spielfeld fahren lassen.

Dabei hat der gegnerische Panzer den Spielerpanzer selbständig ins Visier genommen und nach ihm geschossen. Das Spielgeschehen haben wir zur besseren Veranschaulichung in einem kleinen Video festgehalten.

In der nächsten Lektion unseres Java Spiel Programmieren Tutorials werden wir die Spiellogik des Panzer-Shooters implementieren. Dazu werden wir die GamePanel-Klasse aufräumen und von ihrem Testcode befreien.



Comments 5

  1. Super Tutorial, vielen Dank dafür!

    Hat mir als Java- Anfänger einen grosser Ansporn geliefert,mich mehr mit Java zu befassen.

    Noch ein kleiner Hinweis: Im Code hat sich ein Tippfehler eingeschlichen (hat mir ganz schön Kopfzerbrechen bereitet :’D): In der Aufgabe „1.2 Definieren der EnemyTank-Klasse“ auf der Zeile 16 fehlt ein T bei setDrivingVelocity(DRIVING_VELOCIY/10 + Math.random() * 1.0); .

    Liebe Grüsse,
    Patricia

    1. Post
      Author

      Hallo Patricia,

      vielen Dank für’s Lob und deinen Hinweis!

      Ich habe den Tippfehler überprüft. Er befindet sich schon in der Klasse Tank.java. Daher müssen die beiden Klassen Tank.java und EnemyTank.java von dem Tippfehler bereinigt werden. Ich werde den Fehler bei der Aktualisierung dieses Tutorials beseitigen.

      Viele Grüße und nochmals vielen Dank für deinen Hinweis, Chris

  2. Pingback: Java Spiel Programmieren Tutorial - Das Java Projekt anlegen

  3. Vielen Dank für das Tutorial!
    Habe jetzt beide Android sowie das Java Tutorial durchgearbeitet und muss echt sagen – klasse Arbeit! Alles ist stets ausführlich erklärt, auch wenn man als Anfänger nicht alles immer versteht 😀

    Freue mich auf die nächste Lektion des Panzer Tutorials und auf weitere Android Fortsetzungen / Tutorials? 🙂

    Gerade als Anfänger ist es immer schwer etwas zu programmieren, da man ständig kleine Fehler macht und teilweise Stunden braucht, bis man den Fehler gefunden hat – oder gänzlich verzweifelt. Deshalb habe ich mit großer Freude deine Tutorials durchgemacht.
    Großes Lob, mach weiter so!

    1. Post
      Author

      Hallo Tobias,

      danke für Dein Lob! Es ist immer eine große Hilfe für uns Feedback über die Tutorials zu erhalten. Dadurch erfahren wir, ob die Inhalte für die Leser verständlich sind oder ob Probleme auftreten. Danke nochmals für dein Feedback!

      Viele Grüße, Chris

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.