簡體   English   中英

碰撞游戲錯誤和計時器

[英]Collision Game Errors and Timers

在我的游戲中,我有兩個問題。 首先,我收到了一些我不知道如何解決的錯誤。 其次,我在這個項目中的目標是每 30 秒玩家存活一次就添加一個球。 但是,我嘗試了幾種方法(計時器和 for 循環)。 然而,這些方法導致圖形不出現,但其余功能正常工作(一個看不見的球)。 如果有人能幫我解決這些問題,我將不勝感激。

import java.awt.*;
import java.lang.*;
import java.awt.event.KeyEvent;
import java.util.Formatter;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Polygon;
import java.awt.geom.Area;
public class  Man  implements KeyListener {

private static final int BOX_WIDTH = 640;
private static final int BOX_HEIGHT = 480;
private float ballSpeedX3 = 7;
private float ballSpeedY3 = 7;
private double ball3Radius = 20;
private double ball3X = 320 ;
private double ball3Y = 120 ;
private float ballSpeedX4 = -10;
private float ballSpeedY4 = 10;
private double ball4Radius = 15;
private double ball4X = 600 ;
private double ball4Y = 300 ;
private float ballSpeedX = 0;
private float ballSpeedY = 0;
private double ballRadius = 20;
private double ballX = 120;
private double ballY = 140;
private float ballSpeed1X = 10;
private float ballSpeed1Y = -10;
private double ballRadius1 = 20;
private double ball1X = 320;
private double ball1Y = 340;
private float ballSpeed2X = -3;
private float ballSpeed2Y = -3;
private double ballRadius2 = 50;
private double ball2X = 50;
private double ball2Y = 400;

private static final int UPDATE_RATE = 30;

public Man() {
    this.setPreferredSize(new Dimension(BOX_WIDTH, BOX_HEIGHT));
    Thread gameThread = new Thread() {
        public void run() {
while(true){             

              if ( Math.sqrt(    (Math.pow((ballX- ball1X), 2))    +    Math.pow((ballY-ball1Y), 2)) <= (ballRadius1 + ballRadius)) {
    System.exit(0);}
              if ( Math.sqrt(    (Math.pow((ball4X- ballX), 2))    +    Math.pow((ball4Y-ballY), 2)) <= (ball4Radius + ballRadius)) {
                    System.exit(0);}
              if ( Math.sqrt(    (Math.pow((ball2X- ballX), 2))    +    Math.pow((ball2Y-ballY), 2)) <= (ballRadius2 + ballRadius)) {
                System.exit(0);}        

                  ball4X += ballSpeedX4;
                  ball4Y += ballSpeedY4;
                  if (ball4X - ball4Radius < 0) {
                      ballSpeedX4 = -ballSpeedX4;
                      ball4X = ball4Radius;
                  } else if (ball4X + ball4Radius > BOX_WIDTH) {
                      ballSpeedX4 = -ballSpeedX4;
                      ball4X = BOX_WIDTH - ball4Radius;
                  }
                  if (ball4Y - ball4Radius < 0) {
                      ballSpeedY4 = -ballSpeedY4;
                      ball4Y = ball4Radius;
                  } else if (ball4Y + ball4Radius > BOX_HEIGHT) {
                      ballSpeedY4 = -ballSpeedY4;
                      ball4Y = BOX_HEIGHT - ball4Radius;
                  }

              if ( Math.sqrt(    (Math.pow((ball3X- ballX), 2))    +           Math.pow((ball3Y-ballY), 2)) <= (ball3Radius + ballRadius)) {
                System.exit(0);}


                ball3X += ballSpeedX3;
                ball3Y += ballSpeedY3;
                if (ball3X - ball3Radius < 0) {
                    ballSpeedX3 = -ballSpeedX3;
                    ball3X = ball3Radius;
                } else if (ball3X + ball3Radius > BOX_WIDTH) {
                    ballSpeedX3 = -ballSpeedX3;
                    ball3X = BOX_WIDTH - ball3Radius;
                }
                if (ball3Y - ball3Radius < 0) {
                    ballSpeedY3 = -ballSpeedY3;
                    ball3Y = ball3Radius;
                } else if (ball3Y + ball3Radius > BOX_HEIGHT) {
                    ballSpeedY3 = -ballSpeedY3;
                    ball3Y = BOX_HEIGHT - ball3Radius;
                }

                ballX += ballSpeedX;

                ballY += ballSpeedY;


                if (ballX - ballRadius < 0) {

                    ballX = ballRadius;
                } else if (ballX + ballRadius > BOX_WIDTH) {

                    ballX = BOX_WIDTH - ballRadius;
                }

                if (ballY - ballRadius < 0) {

                    ballY = ballRadius;
                } else if (ballY + ballRadius > BOX_HEIGHT) {

                    ballY = BOX_HEIGHT - ballRadius;
                }

                ball1X += ballSpeed1X;
                ball1Y += ballSpeed1Y;
                if (ball1X - ballRadius1 < 0) {
                    ballSpeed1X = -ballSpeed1X;
                    ball1X = ballRadius1;
                } else if (ball1X + ballRadius1 > BOX_WIDTH) {
                    ballSpeed1X = -ballSpeed1X;
                    ball1X = BOX_WIDTH - ballRadius1;
                }

                if (ball1Y - ballRadius1 < 0) {
                    ballSpeed1Y = -ballSpeed1Y;
                    ball1Y = ballRadius1;
                } else if (ball1Y + ballRadius1 > BOX_HEIGHT) {
                    ballSpeed1Y = -ballSpeed1Y;
                    ball1Y = BOX_HEIGHT - ballRadius1;
                }
                ball2X += ballSpeed2X;
                ball2Y += ballSpeed2Y;
                if (ball2X - ballRadius2 < 0) {
                    ballSpeed2X = -ballSpeed2X;
                    ball2X = ballRadius2;
                } else if (ball2X + ballRadius2 > BOX_WIDTH) {
                    ballSpeed2X = -ballSpeed2X;
                    ball2X = BOX_WIDTH - ballRadius2;
                }

                if (ball2Y - ballRadius2 < 0) {
                    ballSpeed2Y = -ballSpeed2Y;
                    ball2Y = ballRadius2;
                } else if (ball2Y + ballRadius2 > BOX_HEIGHT) {
                    ballSpeed2Y = -ballSpeed2Y;
                    ball2Y = BOX_HEIGHT - ballRadius2;
                }

                repaint();
                try {
                    Thread.sleep(1000 / UPDATE_RATE);

                } catch (InterruptedException ex) { }
            }
        }  
    };
    gameThread.start();

}
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, BOX_WIDTH, BOX_HEIGHT);
    g.setColor(Color.BLUE);
    g.fillOval((int) (ballX - ballRadius), (int) (ballY - ballRadius),
               (int)(2 * ballRadius), (int)(2 * ballRadius));
    g.setColor(Color.RED);
    g.fillOval((int) (ball1X - ballRadius1), (int) (ball1Y - ballRadius1),
               (int)(2 * ballRadius1), (int)(2 * ballRadius1));    
    g.setColor(Color.PINK);
    g.fillOval((int) (ball2X - ballRadius2), (int) (ball2Y - ballRadius2),
               (int)(2 * ballRadius2), (int)(2 * ballRadius2));   
           g.setColor(Color.GREEN);
    g.fillOval((int) (ball3X - ball3Radius), (int) (ball3Y - ball3Radius),
                           (int)(2 * ball3Radius), (int)(2 * ball3Radius));
    g.setColor(Color.YELLOW);
    g.fillOval((int) (ball4X - ball4Radius), (int) (ball4Y - ball4Radius),
                           (int)(2 * ball4Radius), (int)(2 * ball4Radius));


}

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_RIGHT ) {
        ballSpeedX = 5;
    }
    else if (e.getKeyCode() == KeyEvent.VK_LEFT ) {
        ballSpeedX = -5;
    }
    else if (e.getKeyCode() == KeyEvent.VK_UP ) {
        ballSpeedY = -5;
    }
    else if (e.getKeyCode() == KeyEvent.VK_DOWN ) {
        ballSpeedY = 5;
    }
}

public void keyReleased(KeyEvent e) {
     if (e.getKeyCode() == KeyEvent.VK_RIGHT ) {
         ballSpeedX = 0;
     }
     else if (e.getKeyCode() == KeyEvent.VK_LEFT ) {
         ballSpeedX = 0;
     }
     else if (e.getKeyCode() == KeyEvent.VK_UP ) {
         ballSpeedY = 0;
     }
     else if (e.getKeyCode() == KeyEvent.VK_DOWN ) {
         ballSpeedY = 0;

     }  
}
public void keyTyped(KeyEvent e) { }

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            JFrame frame = new JFrame("Collision");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Man man = new Man();
            frame.setContentPane(man);
            frame.pack();
            frame.addKeyListener(man);
            frame.setVisible(true);
        }
    });
}
}

我重新編寫了您的代碼並創建了以下 GUI。

碰撞

紅球擊中粉紅色玩家,動畫結束。

您的所有代碼都在一個大類中。 我很難理解發生了什么,所以我把你的代碼分成 7 個類。 這樣,每個班級都可以做一件事並且做好。 不要害怕使用類和方法來簡化您的代碼並使查找問題更容易。

這是我所做的更改。

  1. 我創建了一個 Player 類來定義播放器。

  2. 我創建了一個 Ball 類來保存 Ball 的值; 球的 X 和 Y 位置、顏色、半徑以及 X 和 Y 速度。

  3. 我創建了一個 GameModel 類來保存 Player 的實例和 Ball 實例的列表。 無論何時創建游戲,都應該使用模型/視圖/控制器模式 這種模式允許您將代碼分開並一次專注於代碼的一部分。

  4. 我將您的 Main 類重命名為 CollisionGame。 CollisionGame 類中剩下的唯一代碼是創建游戲模型、創建 JFrame 和繪圖面板以及啟動動畫的代碼。

  5. 我從 JPanel 創建了一個 DrawingPanel。 您應該始終在 JPanel 上繪圖。 您永遠不應該在 JFrame 上繪圖。

  6. 我把 KeyListener 放在它自己的類中。 我將 KeyListener 添加到 JPanel。 我確保 JPanel 具有焦點。

  7. 我把動畫放在它自己的動畫類中。

這是代碼。 我將所有類放在一個文件中,這樣我就可以更輕松地復制和粘貼。 這些類應該放在單獨的文件中。

package com.ggl.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CollisionGame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new CollisionGame();
            }
        });
    }

    private static final int BOX_WIDTH = 640;
    private static final int BOX_HEIGHT = 480;

    public CollisionGame() {
        GameModel gameModel = new GameModel();

        JFrame frame = new JFrame("Collision");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DrawingPanel drawingPanel = new DrawingPanel(gameModel, BOX_WIDTH,
                BOX_HEIGHT);
        frame.add(drawingPanel);
        frame.pack();
        frame.setVisible(true);

        Animation animation = new Animation(drawingPanel, gameModel, BOX_WIDTH,
                BOX_HEIGHT);
        new Thread(animation).start();
    }

    public class DrawingPanel extends JPanel {
        private static final long serialVersionUID = -8219208002512324440L;

        private int width;
        private int height;

        private GameModel gameModel;

        public DrawingPanel(GameModel gameModel, int width, int height) {
            this.gameModel = gameModel;
            this.width = width;
            this.height = height;

            this.setFocusable(true);
            this.requestFocusInWindow();
            this.addKeyListener(new GameKeyListener(gameModel.getPlayer()));
            this.setPreferredSize(new Dimension(width, height));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, width, height);

            Player player = gameModel.getPlayer();
            g.setColor(player.getColor());
            double playerRadius = player.getRadius();
            double playerDiameter = playerRadius + playerRadius;
            g.fillOval((int) (player.getPositionX() - playerRadius),
                    (int) (player.getPositionY() - playerRadius),
                    (int) (playerDiameter), (int) (playerDiameter));

            for (Ball ball : gameModel.getBalls()) {
                g.setColor(ball.getColor());
                double ballRadius = ball.getRadius();
                double ballDiameter = ballRadius + ballRadius;
                g.fillOval((int) (ball.getPositionX() - ballRadius),
                        (int) (ball.getPositionY() - ballRadius),
                        (int) (ballDiameter), (int) (ballDiameter));
            }
        }
    }

    public class Animation implements Runnable {
        private static final long UPDATE_RATE = 30;

        private boolean running;

        private double width;
        private double height;

        private DrawingPanel drawingPanel;

        private GameModel gameModel;

        public Animation(DrawingPanel drawingPanel, GameModel gameModel,
                double width, double height) {
            this.drawingPanel = drawingPanel;
            this.gameModel = gameModel;
            this.width = width;
            this.height = height;
            this.running = true;
        }

        @Override
        public void run() {
            sleep(1000L);
            long ballTime = System.currentTimeMillis();
            long nextBallTime = 30000L;
            gameModel.addBall();

            while (running) {
                long elapsedTime = System.currentTimeMillis() - ballTime;
                if (elapsedTime >= nextBallTime) {
                    gameModel.addBall();
                    ballTime += nextBallTime;
                }

                movePlayer(gameModel.getPlayer());
                for (Ball ball : gameModel.getBalls()) {
                    moveBall(ball);
                }

                repaint();

                if (isPlayerHit()) {
                    running = false;
                } else {
                    sleep(1000L / UPDATE_RATE);
                }
            }
        }

        private void movePlayer(Player player) {
            player.setPositionX(player.getPositionX() + player.getSpeedX());
            player.setPositionY(player.getPositionY() + player.getSpeedY());

            double radius = player.getRadius();
            if (player.getPositionX() - radius < 0) {
                player.setSpeedX(-player.getSpeedX());
                player.setPositionX(radius);
            } else if (player.getPositionX() + radius > width) {
                player.setSpeedX(-player.getSpeedX());
                player.setPositionX(width - radius);
            }

            if (player.getPositionY() - radius < 0) {
                player.setSpeedY(-player.getSpeedY());
                player.setPositionY(radius);
            } else if (player.getPositionY() + radius > height) {
                player.setSpeedY(-player.getSpeedY());
                player.setPositionY(height - radius);
            }
        }

        private void moveBall(Ball ball) {
            ball.setPositionX(ball.getPositionX() + ball.getSpeedX());
            ball.setPositionY(ball.getPositionY() + ball.getSpeedY());

            double radius = ball.getRadius();
            if (ball.getPositionX() - radius < 0) {
                ball.setSpeedX(-ball.getSpeedX());
                ball.setPositionX(radius);
            } else if (ball.getPositionX() + radius > width) {
                ball.setSpeedX(-ball.getSpeedX());
                ball.setPositionX(width - radius);
            }

            if (ball.getPositionY() - radius < 0) {
                ball.setSpeedY(-ball.getSpeedY());
                ball.setPositionY(radius);
            } else if (ball.getPositionY() + radius > height) {
                ball.setSpeedY(-ball.getSpeedY());
                ball.setPositionY(height - radius);
            }
        }

        private boolean isPlayerHit() {
            Player player = gameModel.getPlayer();
            for (Ball ball : gameModel.getBalls()) {
                double radiusSquared = Math.pow(
                        ball.getRadius() + player.getRadius(), 2D);
                double distanceSquared = Math.pow(
                        (ball.getPositionX() - player.getPositionX()), 2D)
                        + Math.pow(ball.getPositionY() - player.getPositionY(),
                                2D);
                if (distanceSquared <= radiusSquared) {
                    return true;
                }
            }

            return false;
        }

        private void repaint() {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    drawingPanel.repaint();
                }
            });
        }

        private void sleep(long sleepTime) {
            try {
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {

            }
        }
    }

    public class GameKeyListener implements KeyListener {
        private float playerSpeedX;
        private float playerSpeedY;

        private Player player;

        public GameKeyListener(Player player) {
            this.player = player;
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                playerSpeedX = 5;
            } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                playerSpeedX = -5;
            } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                playerSpeedY = -5;
            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                playerSpeedY = 5;
            }

            updatePlayer();
        }

        @Override
        public void keyReleased(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                playerSpeedX = 0;
            } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                playerSpeedX = 0;
            } else if (e.getKeyCode() == KeyEvent.VK_UP) {
                playerSpeedY = 0;
            } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
                playerSpeedY = 0;
            }

            updatePlayer();
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        private void updatePlayer() {
            player.setSpeedX(playerSpeedX);
            player.setSpeedY(playerSpeedY);
        }

    }

    public class GameModel {
        private List<Ball> balls;
        private List<Ball> newBalls;

        private Player player;

        public GameModel() {
            this.balls = new ArrayList<>();
            this.newBalls = createBalls();
            this.player = new Player(Color.PINK, 120, 140, 20, 0, 0);
        }

        private List<Ball> createBalls() {
            List<Ball> balls = new ArrayList<>();
            balls.add(new Ball(Color.BLUE, 320, 120, 20, 7, 7));
            balls.add(new Ball(Color.RED, 600, 300, 15, -10, 10));
            balls.add(new Ball(Color.GREEN, 320, 340, 20, 10, -10));
            balls.add(new Ball(Color.YELLOW, 50, 400, 50, -3, -3));

            return balls;
        }

        public void addBall() {
            if (!newBalls.isEmpty()) {
                balls.add(newBalls.get(0));
                newBalls.remove(0);
            }
        }

        public List<Ball> getBalls() {
            return balls;
        }

        public Player getPlayer() {
            return player;
        }

    }

    public class Player {
        private float speedX;
        private float speedY;
        private double radius;
        private double positionX;
        private double positionY;
        private Color color;

        public Player(Color color, double positionX, double positionY,
                double radius, float speedX, float speedY) {
            this.color = color;
            this.positionX = positionX;
            this.positionY = positionY;
            this.radius = radius;
            this.speedX = speedX;
            this.speedY = speedY;
        }

        public float getSpeedX() {
            return speedX;
        }

        public void setSpeedX(float speedX) {
            this.speedX = speedX;
        }

        public float getSpeedY() {
            return speedY;
        }

        public void setSpeedY(float speedY) {
            this.speedY = speedY;
        }

        public double getRadius() {
            return radius;
        }

        public double getPositionX() {
            return positionX;
        }

        public void setPositionX(double positionX) {
            this.positionX = positionX;
        }

        public double getPositionY() {
            return positionY;
        }

        public void setPositionY(double positionY) {
            this.positionY = positionY;
        }

        public Color getColor() {
            return color;
        }
    }

    public class Ball {
        private float speedX;
        private float speedY;
        private double radius;
        private double positionX;
        private double positionY;
        private Color color;

        public Ball(Color color, double positionX, double positionY,
                double radius, float speedX, float speedY) {
            this.color = color;
            this.positionX = positionX;
            this.positionY = positionY;
            this.radius = radius;
            this.speedX = speedX;
            this.speedY = speedY;
        }

        public float getSpeedX() {
            return speedX;
        }

        public void setSpeedX(float speedX) {
            this.speedX = speedX;
        }

        public float getSpeedY() {
            return speedY;
        }

        public void setSpeedY(float speedY) {
            this.speedY = speedY;
        }

        public double getRadius() {
            return radius;
        }

        public double getPositionX() {
            return positionX;
        }

        public void setPositionX(double positionX) {
            this.positionX = positionX;
        }

        public double getPositionY() {
            return positionY;
        }

        public void setPositionY(double positionY) {
            this.positionY = positionY;
        }

        public Color getColor() {
            return color;
        }

    }
}

您嘗試繪制的 Man 類實際上並不是可顯示的組件。 你還有什么其他錯誤? 他們都可能有關聯。

public class  Man  extends JComponent implements KeyListener {

這將允許顯示球並且游戲開始工作。 至於添加新球,您可能想要創建一個球對象以及繪制方法。 然后,您可以將多個球添加到列表中,然后在每次游戲需要刷新時在列表上繪制每個球。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM