Breakout - Fehlersuche

Monokuma

Aktives Mitglied
Hallo. Also ich hab ein eher großes Problem. Ich habe für jeden meiner Ziele ein Platz im Array definiert. Jedoch funktioniert es nicht ganz, mit der Farbänderung nach einem Treffer und auch mit der Entfernung des Ziels, dass nach dem zweiten Treffer zerstört ist. Der Ball prallt trotzdem an dem nicht sehbaren Ziel ab. Ich bräuchte wirklich dringend Hilfe damit.

 

Monokuma

Aktives Mitglied
Java:
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;


public class Breakout extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    private static final int width = 700;
    private static final int height = 900;
    private boolean gameStarted;
    private int durch = 10;
    private int paddleW = 50;
    private int paddleH = 10;
    private int ballYPos = width / 2;
    private int ballXPos = height / 2;
    private int paddleXpos = width / 2;
    private int paddleYpos = height - 100;
    private int ballXSpeed = 2;
    private int ballYSpeed = 2;
    private int paddleDeltaX = 0;
    private int score = 0;
    private int brickH = 15;
    private int brickW = 80;
    private int startX = 50;
    private int startY = 20;
    private int gapX = 130;
    private int gapY = 20;
    private int col = 1;
    private int row = 1;
    private int maxRow = 1;
    private int maxCol = 3;
    private int[][] hit = new int[maxRow][maxCol];

    @Override
    public void start(Stage primaryStage) throws Exception {
        Canvas canvas = new Canvas(width, height);
        GraphicsContext bg = canvas.getGraphicsContext2D();
        GraphicsContext ball = canvas.getGraphicsContext2D();
        GraphicsContext paddle = canvas.getGraphicsContext2D();
        GraphicsContext targets = canvas.getGraphicsContext2D();
        Timeline t = new Timeline(new KeyFrame(Duration.millis(10), e -> mainGame(bg, ball, paddle, targets)));
        t.setCycleCount(Timeline.INDEFINITE);
        canvas.setOnMouseClicked(e -> gameStarted = true);
        Scene scene = new Scene(new StackPane(canvas));
        /**
         * KeyHandler für das betätigen der Tasten zur Steuerung des Schlägers
         */
        scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                switch (event.getCode()) {
                    case A:
                    case LEFT:
                        paddleDeltaX = -4;
                        break;
                    case D:
                    case RIGHT:
                        paddleDeltaX = 4;
                        break;
                }
            }
        });
        scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                paddleDeltaX = 0;
            }
        });
        primaryStage.setTitle("Breakout");
        primaryStage.setScene(scene);
        primaryStage.show();
        t.play();
    }

    /**
     *Erkennung der Kollision an der oberen Seite des Ziels
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetUp() {
        boolean erg = false;
        if ((ballXPos + (durch / 2)) >= (col * gapX + startX) && (ballXPos + (durch / 2)) <= (col * gapX + startX) + brickW && ballYPos + durch == row * gapY + startY) {
            erg = true;
        }
        return erg;
    }

    /**
     *Erkennung der Kollision an der unteren Seite des Ziels
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetDown() {
        boolean erg = false;
        if ((ballXPos + (durch / 2)) >= (col * gapX + startX) && (ballXPos + (durch / 2)) <= (col * gapX + startX) + brickW && ballYPos == (row * gapY + startY) + brickH) {
            erg = true;
        }
        return erg;
    }

    /**
     *Erkennung der Kollision an der linken Seite des Ziels
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetLeft() {
        boolean erg = false;
        if (ballYPos + (durch / 2) >= (row * gapY + startY) && ballYPos + (durch / 2) <= (row * gapY + startY) + brickH && ballXPos + durch == (col * gapX + startX)) {
            erg = true;
        }
        return erg;
    }

    /**
     *Erkennung der Kollision an der rechten Seite des Ziels
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetRight() {
        boolean erg = false;
        if (ballYPos + (durch / 2) >= (row * gapY + startY) && ballYPos + (durch / 2) <= (row * gapY + startY) + brickH && ballXPos == (col * gapX + startX) + brickW) {
            erg = true;
        }
        return erg;
    }

    public void mainGame(GraphicsContext bg, GraphicsContext ball, GraphicsContext paddle, GraphicsContext targets) {
        /**
         * Start des Spiels nach Mausclick
         */
        if (gameStarted) {
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            paddleXpos += paddleDeltaX;
            ballYPos += ballYSpeed;
            ballXPos += ballXSpeed;
            paddle.setFill(Color.BLUE);
            paddle.fillRect(paddleXpos, paddleYpos, paddleW, paddleH);
            ball.setFill(Color.GREEN);
            ball.fillOval(ballXPos, ballYPos, durch, durch);
            targets.setFill(Color.RED);
            for (row = 1; row <= maxRow; row++) {
                for (col = 1; col <= maxCol; col++) {
                    if (hit[row - 1][col - 1] == 0) {
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        hit[row - 1][col - 1] += 1;
                    }
                    if (hit[row - 1][col - 1] == 1){
                        targets.setFill(Color.YELLOW);
                    }
                    if (hit[row - 1][col - 1] == 2) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                }
            }
        } else {
            /**
             * Startbildschirm
             */
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            bg.setFont(Font.font("Impact", 130));
            bg.setFill(Color.YELLOW);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("BREAKOUT!!!", width / 2, 200);
            bg.setFont(Font.font("Arial Black", 50));
            bg.setFill(Color.BLACK);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Click to Start!", width / 2, height / 2);
            bg.setFont(Font.font("Comic Sans", 45));
            bg.setFill(Color.DARKRED);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Have fun!", width / 2, height - 200);
        }
        /**
         * Bewegung des Schlägers
         */
        if (paddleXpos < 0) {
            paddleXpos = 0;
        } else if (paddleXpos > width - paddleW) {
            paddleXpos = width - paddleW;
        }
        /**
         * Ballabpraller an den Rändern
         */
        if (ballXPos == width - durch || ballXPos == 0) {
            ballXSpeed *= -1;
        }
        if (ballYPos == 0) {
            ballYSpeed *= -1;
        }
        /**
         * Abbruchkriterium, wenn der Ball aus dem unteren Bildschirm hinauswandert
         */
        if (ballYPos + durch > height) {
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            bg.setFont(Font.font("Arial Black", 50));
            bg.setFill(Color.BLACK);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Game Over!", width / 2, height / 2);
            bg.setFont(Font.font("Comic Sans", 45));
            bg.setFill(Color.DARKRED);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Your score: " + score, width / 2, height - 200);
        }
        /**
         * Ballbewegung, wenn der Ball den Schläger berührt
         */
        if (ballXPos + durch / 2 >= paddleXpos && ballXPos + durch / 2 <= paddleXpos + paddleW && ballYPos + durch == paddleYpos) {
            ballYSpeed *= -1;
        }

    }

}
 
K

kneitzel

Gast
Deine Logik ist auch extrem schwer zu verstehen!

Variablennamen könnten etwas mehr aussagen. Das Array "hit" sind wohl die Bricks ...

Warum machst Du die Schleife ab 1 um dann immer 1 abzuziehen? Wird doch einfacher, wenn Du es von Anfang an in den richtigen Grenzen laufen lassen würdest und dann nicht immer und überall 1 abziehen müsstest ...

Magic Numbers! Was bedeuten denn 0,1,2, ... in dem hit Array?

Dann die Logik - hier würde ich Dir empfehlen, die einfach etwas aufzuteilen in Methoden. Dann wird es deutlich verständlicher.

Dein Problem ist, dass Du die Ball-Geschwindigkeit immer prüfst - unabhängig vom Wert:
Java:
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }

Lösen könntest Du es mit einer ersten Prüfung: Wenn der Brick nicht da ist: mache nichts. (In einer Methode wäre ein return denkbar. So in den Schleifen ein continue.
 

MoxxiManagarm

Top Contributor
Ich durchblicks nicht ganz, liegt hauptsächlich daran, dass ich nicht fit bin in JavaFX. Was mir aber tendenziell Bauchschmerzen machen würde sind die ganzen if's. Bist du dir sicher, dass es, zumindest teilweise, else-if's sein sollten?
 

Monokuma

Aktives Mitglied
Deine Logik ist auch extrem schwer zu verstehen!

Variablennamen könnten etwas mehr aussagen. Das Array "hit" sind wohl die Bricks ...

Warum machst Du die Schleife ab 1 um dann immer 1 abzuziehen? Wird doch einfacher, wenn Du es von Anfang an in den richtigen Grenzen laufen lassen würdest und dann nicht immer und überall 1 abziehen müsstest ...

Magic Numbers! Was bedeuten denn 0,1,2, ... in dem hit Array?

Dann die Logik - hier würde ich Dir empfehlen, die einfach etwas aufzuteilen in Methoden. Dann wird es deutlich verständlicher.

Dein Problem ist, dass Du die Ball-Geschwindigkeit immer prüfst - unabhängig vom Wert:
Java:
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }

Lösen könntest Du es mit einer ersten Prüfung: Wenn der Brick nicht da ist: mache nichts. (In einer Methode wäre ein return denkbar. So in den Schleifen ein continue.
Die Schleife hab ich jetzt überarbeitet, die läuft jetzt von 0 bis < maxRow.

Das mit den Magic Numbers, da weiß ich jetzt nicht, was du meinst. Ich kann mir nur denken, dass die indexe des Arrays damit gemeint sind.

Die Ballgeschwindigkeit ändere ich nur wenn einer der beiden Bedingungen zutrifft, sprich wenn der Ball da oder dort abprallt.

Und continue kenn ich garnicht
 

MoxxiManagarm

Top Contributor
Das mit den Magic Numbers, da weiß ich jetzt nicht, was du meinst.
Damit ist gemeint, dass wir perse nicht wissen, was 0 1 2 bedeudet. Du hast z.B. einen Vergleich auf hit[x][y] auf 2. Es wäre günstiger die 2 zu "benennen" durch eine statische Variable.

Mittlerweile bin ich mir übrigens ziemlich sicher, die if's sind mit der Vermischung von intersect und hit-count übel. Letztlich willst du ja den intersect ignorieren, falls hit-count 2 ist. Dann mach das doch auch bitte, trenne dafür intersect und hit-count Bedingungen sauber.
 

Monokuma

Aktives Mitglied
Damit ist gemeint, dass wir perse nicht wissen, was 0 1 2 bedeudet. Du hast z.B. einen Vergleich auf hit[x][y] auf 2. Es wäre günstiger die 2 zu "benennen" durch eine statische Variable.

Mittlerweile bin ich mir übrigens ziemlich sicher, die if's sind mit der Vermischung von intersect und hit-count übel. Letztlich willst du ja den intersect ignorieren, falls hit-count 2 ist. Dann mach das doch auch bitte, trenne dafür intersect und hit-count Bedingungen sauber.
0 heißt, dass es gezeichnet werden soll.
1 heißt, dass die Farbe des jeweiligen Rechtecks geändert werden soll
2 heißt, dass es komplett verschwinden soll, da es zerstört ist.

Ich hab die aber jetzt jeweils in Variablen initiiert
Wenn eben ein jeweiliges Rechteck getroffen wurde, soll ich eben der Wert im Array zu dem zugehörigen Rechteck ändern und eben diese Wandlung hervorrufen.
 

Kirby.exe

Top Contributor
Ve
0 heißt, dass es gezeichnet werden soll.
1 heißt, dass die Farbe des jeweiligen Rechtecks geändert werden soll
2 heißt, dass es komplett verschwinden soll, da es zerstört ist.

Ich hab die aber jetzt jeweils in Variablen initiiert
Wenn eben ein jeweiliges Rechteck getroffen wurde, soll ich eben der Wert im Array zu dem zugehörigen Rechteck ändern und eben diese Wandlung hervorrufen.
Verwende für sowas ein Enum ;) Das macht es wesentlich lesbarer ;)
 
K

kneitzel

Gast
Ich würde das gerne mit dem continue umändern, aber ich weiß nicht genau wie. Kann ich ein paar Anhaltspunkte haben?
Java:
if (hit[row - 1][col - 1] == 2) continue;

Das wäre eine erste Bedingung innerhalb Deiner Schleifen, die besagt: Wenn der Wert 2 ist, dann gehe wieder zum Schleifenkopf.

Natürlich ohne Berücksichtigung weiterer Änderungen von Dir (statt 2 ggf. eine Konstante Variable, das -1 brauchst Du ggf. auch nicht mehr ...)
 

Monokuma

Aktives Mitglied
Java:
/**
* @author Matthias Utrata, 3AI
* SEW-Projekt: Breakout
*/

/**
* Benötigte Imports
*/
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
* Breakout-Klasse
*/
public class Breakout extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     * Variablen zur Bestimmung der Größe, des Spielfeldes
     */
    private static final int width = 700;
    private static final int height = 900;

    /**
     * boolean, der beurteilt, ob das Spiel gestartet wurde.
     */
    private boolean gameStarted;

    /**
     * Variablen, die den Durchmesser des Balls, die Breite und Höhe des Schlägers, sowie der Ziele angeben.
     */
    private final int durch = 10;
    private final int paddleW = 50;
    private final int paddleH = 10;
    private final int brickH = 15;
    private final int brickW = 80;

    /**
     * Positionsbestimmung am Anfang des Spiels
     */
    private int ballYPos = width / 2;
    private int ballXPos = height / 2;
    private int paddleXpos = width / 2;
    private final int paddleYpos = height - 100;

    /**
     * Geschwindigkeiten und Geschwindigkeitsveränderung des Balls
     */
    private int ballXSpeed = 2;
    private int ballYSpeed = 2;
    private int paddleDeltaX = 0;

    /**
     * Spielstand
     */
    private int score = 0;

    /**
     * X und Y Koordinaten, wo mit dem zeichnen begiinen werden sollen & der Abstand der Ziele von einander
     */
    private final int startX = 50;
    private final int startY = 20;
    private final int gapX = 130;
    private final int gapY = 20;

    /**
     * Angabe der Reihen und Spalten
     */
    private int col = 0;
    private int row = 0;
    private final int maxRow = 5;
    private final int maxCol = 5;
    private int[][] bricks = new int[maxRow][maxCol];

    /**
     * Variablen für den Treffer
     */
    public final int draw = 0;
    public final int changedColor = 1;
    public final int destryoed = 2;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Canvas canvas = new Canvas(width, height);
        GraphicsContext bg = canvas.getGraphicsContext2D();
        GraphicsContext ball = canvas.getGraphicsContext2D();
        GraphicsContext paddle = canvas.getGraphicsContext2D();
        GraphicsContext targets = canvas.getGraphicsContext2D();
        Timeline t = new Timeline(new KeyFrame(Duration.millis(10), e -> mainGame(bg, ball, paddle, targets)));
        t.setCycleCount(Timeline.INDEFINITE);
        canvas.setOnMouseClicked(e -> gameStarted = true);
        Scene scene = new Scene(new StackPane(canvas));
        /**
         * KeyHandler für das betätigen der Tasten zur Steuerung des Schlägers
         */
        scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                switch (event.getCode()) {
                    case A:
                    case LEFT:
                        paddleDeltaX = -4;
                        break;
                    case D:
                    case RIGHT:
                        paddleDeltaX = 4;
                        break;
                }
            }
        });
        scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                paddleDeltaX = 0;
            }
        });
        primaryStage.setTitle("Breakout");
        primaryStage.setScene(scene);
        primaryStage.show();
        t.play();
    }

    /**
     * Erkennung der Kollision an der oberen Seite des Ziels
     *
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetUp() {
        boolean erg = false;
        if ((ballXPos + (durch / 2)) >= (col * gapX + startX) && (ballXPos + (durch / 2)) <= (col * gapX + startX) + brickW && ballYPos + durch == row * gapY + startY) {
            erg = true;
        }
        return erg;
    }

    /**
     * Erkennung der Kollision an der unteren Seite des Ziels
     *
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetDown() {
        boolean erg = false;
        if ((ballXPos + (durch / 2)) >= (col * gapX + startX) && (ballXPos + (durch / 2)) <= (col * gapX + startX) + brickW && ballYPos == (row * gapY + startY) + brickH) {
            erg = true;
        }
        return erg;
    }

    /**
     * Erkennung der Kollision an der linken Seite des Ziels
     *
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetLeft() {
        boolean erg = false;
        if (ballYPos + (durch / 2) >= (row * gapY + startY) && ballYPos + (durch / 2) <= (row * gapY + startY) + brickH && ballXPos + durch == (col * gapX + startX)) {
            erg = true;
        }
        return erg;
    }

    /**
     * Erkennung der Kollision an der rechten Seite des Ziels
     *
     * @return True oder false, insofern eine Kollision stattfindet
     */
    public boolean intersectsTargetRight() {
        boolean erg = false;
        if (ballYPos + (durch / 2) >= (row * gapY + startY) && ballYPos + (durch / 2) <= (row * gapY + startY) + brickH && ballXPos == (col * gapX + startX) + brickW) {
            erg = true;
        }
        return erg;
    }

    /**
     * Hauptmethode des Spiels
     *
     * @param bg      Hintergrund
     * @param ball    Ball
     * @param paddle  Schläger
     * @param targets Ziele
     */
    public void mainGame(GraphicsContext bg, GraphicsContext ball, GraphicsContext paddle, GraphicsContext targets) {
        /**
         * Start des Spiels nach Mausclick
         */
        if (gameStarted) {
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            paddleXpos += paddleDeltaX;
            ballYPos += ballYSpeed;
            ballXPos += ballXSpeed;
            paddle.setFill(Color.BLUE);
            paddle.fillRect(paddleXpos, paddleYpos, paddleW, paddleH);
            ball.setFill(Color.GREEN);
            ball.fillOval(ballXPos, ballYPos, durch, durch);
            targets.setFill(Color.RED);
            for (row = 0; row < maxRow; row++) {
                for (col = 0; col < maxCol; col++) {
                    if (bricks[row][col] == draw) {
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        bricks[row][col] += 1;
                        continue;
                    }
                    if (bricks[row][col] == changedColor) {
                        targets.setFill(Color.YELLOW);
                    }
                    if (bricks[row][col] == destryoed) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        score+=1;
                    }
                }
            }

        } else {
            /**
             * Startbildschirm
             */
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            bg.setFont(Font.font("Impact", 130));
            bg.setFill(Color.YELLOW);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("BREAKOUT!!!", width / 2, 200);
            bg.setFont(Font.font("Arial Black", 50));
            bg.setFill(Color.BLACK);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Click to Start!", width / 2, height / 2);
            bg.setFont(Font.font("Comic Sans", 45));
            bg.setFill(Color.DARKRED);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Have fun!", width / 2, height - 200);
        }
        /**
         * Bewegung des Schlägers
         */
        if (paddleXpos < 0) {
            paddleXpos = 0;
        } else if (paddleXpos > width - paddleW) {
            paddleXpos = width - paddleW;
        }
        /**
         * Ballabpraller an den Rändern
         */
        if (ballXPos == width - durch || ballXPos == 0) {
            ballXSpeed *= -1;
        }
        if (ballYPos == 0) {
            ballYSpeed *= -1;
        }
        /**
         * Abbruchkriterium, wenn der Ball aus dem unteren Bildschirm hinauswandert
         */
        if (ballYPos + durch > height) {
            bg.setFill(Color.GRAY);
            bg.fillRect(0, 0, width, height);
            bg.setFont(Font.font("Arial Black", 50));
            bg.setFill(Color.BLACK);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Game Over!", width / 2, height / 2);
            bg.setFont(Font.font("Comic Sans", 45));
            bg.setFill(Color.DARKRED);
            bg.setTextAlign(TextAlignment.CENTER);
            bg.fillText("Your score: " + score, width / 2, height - 200);
        }
        /**
         * Ballbewegung, wenn der Ball den Schläger berührt
         */
        if (ballXPos + durch / 2 >= paddleXpos && ballXPos + durch / 2 <= paddleXpos + paddleW && ballYPos + durch == paddleYpos) {
            ballYSpeed *= -1;
        }

    }

}

Hab ich schon geändert
 

MoxxiManagarm

Top Contributor
Java:
                    if (bricks[row][col] == draw) {
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        bricks[row][col] += 1;
                    }
                    if (bricks[row][col] == changedColor) {
                        targets.setFill(Color.YELLOW);
                    }
                    if (bricks[row][col] == destryoed) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        score+=1;
                    }

Aber schau mal, du prüfst die Intersection immernoch bevor zu prüfst, ob der Stein überhaupt noch da ist. Auf die Weise kann er doch nur einen Treffer erkennen. Die Intersection darf nicht überprüft werden im Fall von bricks[row][col] == destroyed
 

Monokuma

Aktives Mitglied
Java:
                    if (bricks[row][col] == draw) {
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        bricks[row][col] += 1;
                    }
                    if (bricks[row][col] == changedColor) {
                        targets.setFill(Color.YELLOW);
                    }
                    if (bricks[row][col] == destryoed) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        score+=1;
                    }

Aber schau mal, du prüfst die Intersection immernoch bevor zu prüfst, ob der Stein überhaupt noch da ist. Auf die Weise kann er doch nur einen Treffer erkennen. Die Intersection darf nicht überprüft werden im Fall von bricks[row][col] == destroyed
Wie sieht das if dann aus? Ich hab keine Ahnung, sorry
 

Monokuma

Aktives Mitglied
Java:
for (row = 0; row < maxRow; row++) {
                for (col = 0; col < maxCol; col++) {
                    if (bricks[row][col] == destryoed) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        score += 1;
                        continue;
                    }
                    if (bricks[row][col] == changedColor) {
                        targets.setFill(Color.YELLOW);
                        continue;
                    }
                    if (bricks[row][col] == draw) {
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        bricks[row][col] += 1;
                    }
                }
            }

Ich hab es jetzt geändert
 
K

kneitzel

Gast
Bei der Logik wie es nun ist, wird
a) ein Stein erst im nächsten Durchlauf entfernt
b) in jedem Durchlauf noch einmal entfernt und der score hoch gezählt, obwohl er bereits entfernt ist.

[CODE lang="java" highlight="3-6,23-27"]for (row = 0; row < maxRow; row++) {
for (col = 0; col < maxCol; col++) {
if (bricks[row][col] == destryoed) {
// Wenn der Stein bereits weg ist, dann mach hier nichts weiter!
continue;
}

if (bricks[row][col] == changedColor) {
targets.setFill(Color.YELLOW);
continue;
}
if (bricks[row][col] == draw) {
targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
}
if (intersectsTargetRight() || intersectsTargetLeft()) {
ballXSpeed *= -1;
}
if (intersectsTargetDown() || intersectsTargetUp()) {
ballYSpeed *= -1;
}
if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
bricks[row][col] += 1;
if (bricks[row][col] == destryoed) {
// Dies wird nur noch ausgeführt, wenn der Stein auch weggenommen wurde!
targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
score += 1;
}
}
}
}[/CODE]
 
K

kneitzel

Gast
Kann ich vielleicht die fertige Lösung davon haben? Ich komm einfach nicht drauf
Vermutlich liegt das einfach daran, dass wir uns bisher nur auf eine Problematik konzentriert haben aber es noch weitere Probleme gibt, die noch nicht angesprochen wurden.

Nur ich habe das auch nicht als Code bei mir, so dass ich das auch nicht direkt ausführen kann. Daher sehe ich nicht, was es da jetzt noch an Problemen gibt und ohne weitere Informationen, was geht oder nicht geht wird es schwer, das nur am Code zu erkennen, zumal die Logik immer noch mangelhaft ist.

Der Code gehört vernünftig aufgeteilt, so dass er einfach zu lesen und zu handhaben ist.

Was ist denn für jeden Stein zu machen?
- Prüfen, ob er existiert -> Wenn er nicht existiert, dann ist nichts weiter zu machen.
- Prüfen, ob er getroffen wurde -> Erfassen der Veränderungen
- Darstellung des Steins, d.h. - Malen in der notwendigen Farbe oder löschen des Steins, so er nun gelöscht werden soll.

Das kann man in der Schleife ggf. alles zusammen machen, aber ich würde das entsprechend in Methoden machen, so dass die Methoden auch von Dir überschaut werden können / die Logik für dich erkennbar ist.

Auch wäre die ganze GUI Entwicklung etwas, das man macht, wenn man objektorientiert entwickeln kann. Dann hat man eine einfache Trennung zwischen Darstellung und der Datenhaltung. Das alles beschränkt sich dann auf zwei Schritte:
- Model aktualisieren
- Model darstellen

Model aktualisieren wäre dann:
- Ball und ggf. Schläger bewegen
- Status prüfen (Ball im Aus? Ball Schläger getroffen? Ball Brick getroffen? Natürlich jeweils mit entsprechenden Veränderungen)

Model darstellen ist dann relativ einfach, denn das Model enthält dann ja alle Daten, die man braucht. Damit muss man das nur noch durchgehen und neu malen.

Wichtig ist, dass man dann generell die Methoden klein hält. Jede Methode hat eine klare Namensgebung, so dass klar ist, was passiert. Und die Methode macht dann auch nur das. Also keine Nebenwirkungen.

Nur eben weiß ich nicht, wie ich Dich in genau diese Richtung puschen kann. Aber das wäre so meine Sicht auf dieses Projekt ...
 

Monokuma

Aktives Mitglied
Java:
for (row = 0; row < maxRow; row++) {
                for (col = 0; col < maxCol; col++) {
                    if (bricks[row][col] == draw) {
                        targets.setFill(Color.RED);
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                    }
                    if (bricks[row][col] == changedColor) {
                        targets.setFill(Color.YELLOW);
                        targets.fillRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        continue;
                    }
                    if (bricks[row][col] == destroyed) {
                        targets.clearRect(col * gapX + startX, row * gapY + startY, brickW, brickH);
                        score += 1;
                        continue;
                    }
                    if (intersectsTargetRight() || intersectsTargetLeft()) {
                        ballXSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetUp()) {
                        ballYSpeed *= -1;
                    }
                    if (intersectsTargetDown() || intersectsTargetLeft() || intersectsTargetRight() || intersectsTargetUp()) {
                        bricks[row][col] += 1;
                    }
                }
            }

Hier wird das 3te if statement garnicht ausgeführt. Nach 2 Treffern wird der Stein nicht entfernt.
 
K

kneitzel

Gast
Die Logik ist so auch falsch. Wenn das Brick changedColor hat, dann wid nichts weiter ausgeführt, da da ja ein continue enthalten ist....
 

Noahscript

Aktives Mitglied
@Monokuma

Ich interessiere mich sehr für grafische Spiele, die mit Java programmiert wurden. Könntest du für uns mehr solcher Spielen für uns programmieren 😁 ?
Ich interessiere mich auch für eintretende Probleme und deren Lösungen (solange meine Kenntnisse dafür ausreichen :(). Aber hier haben sowieso @kneitzel und @MoxxiManagarm das meiste schon getan...
 

Monokuma

Aktives Mitglied
Hallo, irgendwie hab ich noch ein Problem bei meinem Programm, dass ich aber nicht verstehe. Mein Ball prallt am unteren Boden der untersten Steine nicht an. Ich würde mich über Hilfe sehr freuen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J drawImage Fehlersuche AWT, Swing, JavaFX & SWT 5
W Fehlersuche AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben