Mon premier jeu - Arkanoid

Aug 24 2020

Je suis nouveau sur Java et je viens de terminer mon tout premier jeu - Arkanoid. J'apprécierais, si quelqu'un pouvait regarder cela et me dire quelques conseils et astuces comment puis-je optimiser mon code. Merci. :)

J'ai 5 classes - Breaker, BlockBreakerPanel, Ball, Paddle, Block. Regarder:

Voici les principales classes :

public class Breaker {
    private BlockBreakerPanel panel;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Breaker b = new Breaker();
        b.show();
    }

    private void show() {
        JFrame frame = new JFrame("Block Breaker");
        frame.setSize(490, 600);
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        this.panel = new BlockBreakerPanel(this);
        frame.add(this.panel);
        frame.setVisible(true);
    }

    public BlockBreakerPanel getPanel() {
        return this.panel;
    }   
}

class BlockBreakerPanel extends JPanel implements KeyListener, ActionListener 

{

    private ArrayList<Blocks> blocks = new ArrayList<>();
    private final Paddle player;
    private final Ball ball;
    private final Breaker game;
    private boolean gameOver;
    private int score;
    private boolean start;
    
    public BlockBreakerPanel(Breaker game) {
        setBackground(Color.BLACK);
        
        for (int j = 0; j < 3; j++) {
            for (int i = 0; i < 8; i++) {
                this.blocks.add(new Blocks(i * 60 + 2, j * 40 + 5, 50, 30));
            }
        }
        
        this.player = new Paddle(game);
        this.ball = new Ball(game);
        this.gameOver = false;
        this.score = 0;
        this.start = false;
        
        Timer t = new Timer(5, this);
        t.start();
        
        addKeyListener(this);
        setFocusable(true);
        this.game = game;
    }
    
    public void addPoint() {
        this.score++;
    }
    
    public void isGameOver() {
       this.gameOver = true;
    }
    
    public ArrayList<Blocks> getBlocks() {
        return this.blocks;
    }
    public Paddle getPlayer() {
        return this.player;
    }

    public void paint(Graphics g) {
        super.paintComponent(g);
        
        this.blocks.forEach((block) -> {
            block.paint(g);
        });
        
        this.player.paint(g);       
        this.ball.paint(g);
        
        if (!this.start) {
            g.setFont(new Font("Calibri", Font.BOLD, 35));
            g.setColor(Color.WHITE);
            g.drawString("Pressed enter to start a game", 20, 300);
        }
        
        g.setFont(new Font("Calibri", Font.BOLD, 20));
        g.setColor(Color.WHITE);
        g.drawString(String.valueOf(this.score), 450, 540);
        
        if (this.gameOver) {
            g.setFont(new Font("Calibri", Font.BOLD, 80));
            g.setColor(Color.WHITE);
            g.drawString("Game Over", 60, 300);
        } else if (this.blocks.isEmpty()) {
            this.gameOver = true;
            g.setFont(new Font("Calibri", Font.BOLD, 80));
            g.setColor(Color.WHITE);
            g.drawString("You won", 80, 300);
        }
    }
    
    private void update() {
        this.ball.move();
        repaint();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            this.start = true;
        }
        this.player.pressed(e.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (!this.gameOver && this.start) {
            this.update();            
        }   
    }
}
class Blocks {

    private final int x;
    private final int y;
    private final int width;
    private final int height;

    public Blocks(int a, int b, int w, int h) {
        this.x = a;
        this.y = b;
        this.width = w;
        this.height = h;
    }
    
    public void paint(Graphics g) {       
        g.setColor(Color.pink);
        g.drawRect(this.x, this.y, this.width, this.height);
        g.fillRect(this.x, this.y, this.width, this.height);
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

    public int getWidth() {
        return this.width;
    }

    public int getHeight() {
        return this.height;
    }
}

public class Paddle {

    private int x;
    private final int y;
    private final int width;
    private final int height;
    private final int posun;
    private final Breaker game;

    /**
     *
     * @param game
     */
    public Paddle(Breaker game) {
        this.x = 245 - (60/2);
        this.y = 540;
        this.width = 100;
        this.height = 15;
        this.posun = 10;      
        this.game = game;
    }

    public int getWidth() {
        return this.width;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

    public void paint(Graphics g) {
        g.setColor(Color.CYAN);
        g.drawRect(this.x, this.y, this.width, this.height);
        g.fillRect(this.x, this.y, this.width, this.height);
    }

    void pressed(int keyCode) {
        this.collision();
        if (keyCode == KeyEvent.VK_RIGHT) {
            this.x += this.posun;
        } else if (keyCode == KeyEvent.VK_LEFT) {
            this.x -= this.posun;
        }
    }

    private void collision() {
        if ((this.x + this.width) >= 490) {
            this.x = 490 - this.width;
        } else if (this.x <= 0) {
            this.x = 0;
        }
    }

}

public class Ball {

    private final int DIAMETER = 20;
    private int x;
    private int y;
    private int dx;
    private int dy;
    private final Breaker game;
    
    /**
     *
     * @param game
     */
    public Ball(Breaker game) {
        this.x = 245 - (DIAMETER / 2);
        this.y = 500;
        this.dx = 2;
        this.dy = 2;
        this.game = game;
    }

    void paint(Graphics g) {
        g.setColor(Color.PINK);
        g.drawOval(this.x, this.y, DIAMETER, DIAMETER);
        g.fillOval(this.x, this.y, DIAMETER, DIAMETER);
    }
    
    private void checkCollision() {    
        boolean collision = false;
        if (((this.y+DIAMETER) >= this.game.getPanel().getPlayer().getY()) && ((this.x) >= this.game.getPanel().getPlayer().getX()-2) && ((this.x+DIAMETER) <= (this.game.getPanel().getPlayer().getX()+this.game.getPanel().getPlayer().getWidth()+2))) {
            collision = true;
        } else if ((this.y + DIAMETER) >= 560) {
            this.game.getPanel().isGameOver();
            return;
        }
        
        for (Blocks block : this.game.getPanel().getBlocks()) {
            if ((this.y+5 <= (block.getY() + block.getHeight())) && (this.x+5 >= block.getX()) && ((this.x+DIAMETER-5) <= block.getX()+block.getWidth())) {
                this.game.getPanel().getBlocks().remove(block);
                collision = true;
                this.game.getPanel().addPoint();
                break;
            }
        }
                
        if (collision) {
            this.dy = - this.dy;
        }
    }
    public void move() {
        if (this.x <= 0 || this.x >= (460 + DIAMETER)) {
            this.dx = -this.dx;
        } else if (this.y <= 0 || this.y >= (540 + DIAMETER)) {
            this.dy = -this.dy;
        }
        
        this.checkCollision();
               
        this.x += this.dx;
        this.y += this.dy;
    }
    
}

Réponses

1 TorbenPutkonen Aug 26 2020 at 11:31

Sympa, un de mes jeux préférés.

Ce que vous avez maintenant, c'est toutes les responsabilités d'un programme mélangées dans les mêmes classes violant joyeusement le principe de responsabilité unique . Étudiez le modèle MVC . Commencez ensuite par séparer la physique de votre jeu dans son propre ensemble de classes et la représentation graphique dans un autre ensemble. Placez les écouteurs de clé et d'action dans leurs propres classes et créez une classe principale qui relie tous les composants ensemble.

Déplacez tous les nombres magiques (tels que la taille de l'écran) dans des variables afin de pouvoir les modifier facilement. Définissez la taille des objets par rapport à la taille de l'écran afin de pouvoir adapter le jeu à différentes résolutions d'écran. Tenez compte du fait que tous les écrans n'ont pas le même rapport hauteur/largeur.

Évitez les abréviations arbitraires comme posun. Qu'est-ce qu'un posun ?