0

我正在用 Java 构建一个小“乒乓”游戏。

我正在尝试在顶部添加一个记分员,每次玩家用桨保存球时都会显示更新的分数(+1)。

我正在尝试使用 JLabel,但问题是我想不出一种方法来在每次击球时不断更新 JLabel。

有任何想法吗?

我的代码:

MainPanel 类(带有 Paddle、Ball 和 Label 的类)

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

//import swing.graphics.BounceFrame;
//import swing.graphics.Circle;

public class MainPanel extends JPanel implements ActionListener, KeyListener, Runnable{

    public Paddle paddle;
    public Ball ball;

    public MainPanel(){
        ball = new Ball(50, 50, 10); //centerX, centerY, radius
        setSize(300, 300);
        paddle = new Paddle();
        JLabel scoreKeeper = new JLabel("Score" + ball.getScore());
        add(scoreKeeper);
        Thread thread = new Thread(this);
        thread.start();
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D)g;
        paddle.draw(g2);
        ball.draw(g2);
    }

    public void actionPerformed(ActionEvent e) {
        String direction = e.getActionCommand();

        switch(direction){
            case "left": Paddle.movePaddleLeft(); break;
            case "right": Paddle.movePaddleRight(); break;
        }
        this.repaint();
    }

    public void run() {
        try {
            while(true){
                    ball.move(getBounds());
                repaint();
                Thread.sleep(500/30);
            }
            }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 37){
            Paddle.movePaddleLeft();
        }
        if (e.getKeyCode() == 39){
            Paddle.movePaddleRight();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
}

还有我的 Ball 课:

导入 java.awt.Color;导入 java.awt.Graphics2D;导入 java.awt.geom.Ellipse2D;导入 java.awt.geom.Rectangle2D;导入 java.util.Random;

public class Ball {

    private Ellipse2D ball;
    private double radius;
    private double ballCircumference;
    private Color color;

    private double x;
    private double y;
    private double dx = 5;
    private double dy = 5;

    private int score = 0;
    public int getScore() {
        return score;
    }
    //Boundaries to determine if ball is hit by paddle
    private double criticalBoundaryX;
    private double criticalBoundaryY1; 
    private double criticalBoundaryY2;
    private double paddleHalfwayPoint;
    private boolean inGame = true;
    public void recalculateCriticals(){
        criticalBoundaryX = Paddle.getYPosition() - ballCircumference;
        criticalBoundaryY1 = Paddle.getXPosition()- ballCircumference; //Left boundary
        criticalBoundaryY2 = Paddle.getXPosition()+Paddle.getPaddleWidth()+ballCircumference; //Right Boundary
        paddleHalfwayPoint = (Paddle.getXPosition()+Paddle.getPaddleWidth())/2;
    }

    public Ball(int centerX, int centerY, int radius) {
        this.x = centerX - radius;
        this.y = centerY - radius;
        this.radius = radius;
        ballCircumference = 2*radius;
        Random randomRGB = new Random();
        color = new Color(randomRGB.nextInt(255), randomRGB.nextInt(255), randomRGB.nextInt(255));
        this.ball = new Ellipse2D.Double(x, y, 2*radius, 2*radius);
    }

    public void move(Rectangle2D bounds) {
        recalculateCriticals();
        x += dx;
        y += dy;
        if (x < bounds.getMinX()) {
            x = bounds.getMinX();
            dx = -dx;
        }
        if (x + 2*radius >= bounds.getMaxX()) {
            //System.out.println(bounds.getMaxX());
            x = bounds.getMaxX() - 2*radius;
            dx = -dx;
        }
        if (y < bounds.getMinY()) {
            y = bounds.getMinY();
            dy = -dy;
        }
        if (y > criticalBoundaryX){
             if (x < criticalBoundaryY1 || x > criticalBoundaryY2){
                 inGame = false;
             }
             if (!inGame && hittingEdge(x))
                 dx = -dx;
        }
        if (y > criticalBoundaryX && inGame){ //When it hits the paddle
            changeColor();
            score++;
            y = criticalBoundaryX;
            dy = -dy;
         }
        if (y > bounds.getMaxY()){
            System.out.println("Game Over");
            System.exit(0);
        }
        recalculateCriticals();
        ball.setFrame(x, y, 2*radius, 2*radius);
    }

    public boolean onPaddle(double x){
        return ((x > Paddle.getXPosition()) && (x < Paddle.getXPosition()+Paddle.getPaddleWidth()) && (y > Paddle.getYPosition()-10));
    }
    public boolean hittingEdge(double x){
        return ((x >= criticalBoundaryY1 && x < paddleHalfwayPoint)
                ||
                (x <= criticalBoundaryY1 && x > paddleHalfwayPoint)); //Return true if x is hitting the side edge of the paddle
    }
    public void changeColor(){
        Random randomColor = new Random();
        color = new Color(randomColor.nextInt(255), randomColor.nextInt(255), randomColor.nextInt(255));
    }

    public void draw(Graphics2D g2) {
        g2.setColor(color);
        g2.fill(ball);
    }
}
4

1 回答 1

1

这样做的“Java 方式”是定义一个监听器接口,例如:

public interface BallListener {
  void paddleHit();
}

在 Ball 类中,您应该添加一个字段

private List<BallListener> listeners;

以及方法

public void addBallListener(BallListener l) { listeners.add(l); }
public void removeBallListener(BallListener l) { listeners.remove(l); }

当桨被击中时,你去:

for (BallListener l : listeners)
  l.paddleHit();

主类应该实现BallListener接口,并用球(ball.addBallListener(this))注册自己。

这种方法还使您能够在需要时通知程序的其他部分发生在球上的不同事件(即,BallListener为您要发出信号的每个事件添加一个新方法)。

于 2013-02-05T22:35:42.570 回答