java - Java Pong 游戏中的 KeyListener 和 Timer 问题

标签 java

我目前正在尝试用 Java 构建一个基本的 Pong 游戏,但我在两件事上遇到了困难。首先是我的 Racket 按应有的方式上下移动,但一旦到达拍框边缘,它们就会完全卡住。我不明白为什么。接下来,我不确定如何使用 Timer 或 Thread.sleep 在每次得分后暂时暂停游戏。一旦其中一名球员得分,我希望游戏将球返回到中心,并等待大约 3 秒,然后球再次移动以开始下一分。任何帮助都会很棒。谢谢!

这是我的代码

乒乓球类

import java.awt.*;

import javax.swing.*;


public class Pong extends JFrame{

    public static final int appWIDTH = 500;     //width of jframe
    public static final int appHEIGHT = 500;    //height of jframe
    public final int rWIDTH = 20;               //width of racket
    public final int rHEIGHT = 60;              //height of racket
    PongPanel panel;                            //Jpanel to be added


    /*
     * constructor for a Pong object
     */
    public Pong() {
        setSize(appWIDTH, appHEIGHT);
        setTitle("PONG");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBackground(Color.BLACK);
    }

    /*
     * Starts the application
     */
    public void start() {
        panel = new PongPanel(this);
        add(panel);
        addKeyListener(panel);
        setVisible(true);
        setFocusable(true);
    }

    //Returns a PongPanel
    public PongPanel getPanel() {
        return panel;
    }

    public static void main(String[] args) {
        Pong game = new Pong();
        game.start();
    }
}

面板类

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;


public class PongPanel extends JPanel implements KeyListener {

    private Pong game;
    private Ball ball;
    private Racket p1, p2;
    private int score1, score2;
    Timer timer;

    /*
     * Constructor for a PongPanel which is a JPanel that holds two rackets and a ball
     */
    public PongPanel(Pong game) {
        this.game = game;   
        p1 = new Racket(game, KeyEvent.VK_W, KeyEvent.VK_S, 0);
        p2 = new Racket(game, KeyEvent.VK_UP, KeyEvent.VK_DOWN, game.getWidth() - game.rWIDTH);
        ball = new Ball(game);
        addKeyListener(this);
        setFocusable(true);
        setVisible(true);
    }

    /*
     * Returns the Racket object associated with player 1
     */
    public Racket getRacket1() {
        return p1;
    }

    /*
     * Returns the Racket object associated with player 2
     */
    public Racket getRacket2() {
        return p2;
    }

    //Increases score of the player indicated by the parameter
    public void increaseScore(int playerNo) {
        if(playerNo == 1)
            score1++;
        else
            score2++;
    }

    //Returns the score of the player indicated by the parameter
    public int getScore(int playerNo) {
        if(playerNo == 1)
            return score1;
        else
            return score2;
    }

    public void update() {
        ball.hitBTS();
        p1.move();
        p2.move();
        repaint();
    }

    public void keyPressed(KeyEvent ke) {
        p1.kpressed(ke.getKeyCode());
        p2.kpressed(ke.getKeyCode());
    }

    public void keyReleased(KeyEvent ke){
        p1.krelease(ke.getKeyCode());
        p2.krelease(ke.getKeyCode());
    }

    public void keyTyped(KeyEvent ke) {}

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        ball.paint(g);
        p1.paint(g);
        p2.paint(g);
        update();
    }
}

球类

import java.awt.Graphics;
import java.awt.Rectangle;

import javax.swing.JFrame;
import javax.swing.JOptionPane;


public class Ball {

    private JFrame frame = new JFrame(); 
    private Pong game;
    final int bWIDTH = 30;                  //ball width    
    final int bHEIGHT = 30;                 //ball height
    private int xspeed = 1;                 //horizontal speed of the ball
    private int yspeed = 1;                 //vertical speed of the ball
    int x;                                  //x-coordinate of the ball
    int y;                                  //y-coordinate of the ball


    /*
     * Constructor of a ball object. Sets the ball in the center of frame
     */
    public Ball(Pong game) {
        x = game.getWidth() / 2 - (bWIDTH/2);
        y = game.getHeight() / 2 - (bHEIGHT/2);
        this.game = game;
    }

    /*
     * Checks whether the ball has hit the bottom or top of the frame
     * or if it has reached the left or right edge (score)
     */
    public void hitBTS() {
        x += xspeed;
        y += yspeed;

        if((x + bWIDTH) > game.getWidth()) {
            game.getPanel().increaseScore(1);
            x = game.getWidth() / 2 - (bWIDTH/2);
            y = game.getHeight() / 2 -(bHEIGHT/2);
        }

        else if(x < 0) {
            game.getPanel().increaseScore(2);
            x = game.getWidth() / 2 - (bWIDTH/2);
            y = game.getHeight() / 2 -(bHEIGHT/2);
        }

        else if(y < 0 || (y > game.getHeight() + bHEIGHT)) {
            yspeed = -yspeed;
        }

        checkScore();
        checkCollision();
    }

    //Shows a dialog box indicating the winter if one player reaches 
    //a score of 3
    public void checkScore() {
        if(game.getPanel().getScore(1) == 3) {
            JOptionPane.showMessageDialog(frame, "Player 1 wins");
        }
        else if(game.getPanel().getScore(2) == 3) {
            JOptionPane.showMessageDialog(frame, "Player 2 wins");
        }
    }

    //Checks if the ball has hit a racket
    public void checkCollision() {
                 if(getBallBounds().intersects(game.getPanel().getRacket1().getBounds()) || 
getBallBounds().intersects(game.getPanel().getRacket2().getBounds())) {
            xspeed = -xspeed;
        }
    }

    public Rectangle getBallBounds() {
        return new Rectangle(x, y, bWIDTH, bHEIGHT);
    }   

    public void paint(Graphics g) {
        g.fillRect(x, y, bWIDTH, bHEIGHT);
    }

}

Racket 类别

import java.awt.*;
import java.awt.event.*;

public class Racket {

    private Pong game;
    private int yspeed = 0;     //Number of pixels that the racket moves 
    int x;                      //x-coordinate of racket
    int y;                      //y-coordinate of racket
    int keyUp, keyDown;         //key code associated with the key pressed

    /*
     * Constructor for a racket object. Racket receives a keycode and horizontal 
     * starting position. 
     */
    public Racket(Pong game, int keyUp, int keyDown, int x) {
        this.game = game;
        this.x = x;
        this.keyUp = keyUp;
        this.keyDown = keyDown;
        y = game.getHeight()/2;
    }

    /*
     * Indicates how the racket should move depending on its position.
     */
    public void move() {
        if(y > 0 && y < game.getHeight() - game.rHEIGHT)    
            y += yspeed;
        else if(y <= 0) 
            y = y + 3;
        else if(y == game.getHeight() - game.rHEIGHT)
            y = y - 3;
    }

    /*
     * If key has been pressed, the number of pixels the 
     * racket moves becomes positive or negative
     */
    public void kpressed(int keyCode) {
        if(keyCode == keyUp) {
            yspeed = -3;
        }

        if(keyCode == keyDown) 
            yspeed = 3;
    }

    /*
     * When the key is no longer being pressed, the 
     * racket stops moving.
     */
    public void krelease(int keyCode) {
        if(keyCode == keyUp) 
            yspeed = 0;
        else if (keyCode == keyDown)
            yspeed = 0;
    }

    public Rectangle getBounds() {
        return new Rectangle(x, y, game.rWIDTH, game.rHEIGHT);
    }

    public void paint(Graphics g) {
        g.fillRect(x, y, game.rWIDTH, game.rHEIGHT);
    }
}

最佳答案

要回答您的第一个问题,请更改 Racket 类的 move 方法,如下所示:

public void move() {
    if(y > 0 && y < game.getHeight() - game.rHEIGHT)    
        y += yspeed;
    else if(y <= 0) 
        y = y + 3;
    else if(y >= game.getHeight() - game.rHEIGHT)
        y = y - 3;
}

否则,当 y 变得大于 game.getHeight() - game.rHEIGHT 时,它将卡住,因为它不会再次匹配 move 方法中的 3 个条件中的任何一个。

要回答第二个问题,您可以更改 Ball 类的 checkScore 方法,如下所示:

public void checkScore() {
    if(game.getPanel().getScore(1) == 3) {
        JOptionPane.showMessageDialog(frame, "Player 1 wins");
    }
    else if(game.getPanel().getScore(2) == 3) {
        JOptionPane.showMessageDialog(frame, "Player 2 wins");
    }
    else {
        x = game.getWidth() / 2 - (bWIDTH/2);
        y = game.getHeight() / 2 - (bHEIGHT/2);
        Thread.sleep(3000);
    }
}

关于java - Java Pong 游戏中的 KeyListener 和 Timer 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32192799/

相关文章:

ssl - Java 客户端无法与服务器建立 SSL 握手

java - 如何为开发的eclipse RCP项目制作安装文件?

java - Joda 时间 IllegalArgumentException

java - 在服务层上使用接口(interface)

java - 文件 I/O 遇到一些问题

java - 获取Java内部类的外部类实例的类名

java - 自定义光标图标加载了一个额外的阴影像素

java - 在 "graphView"中标签不是从原点开始

java - 从子元素开始使用 JAXB 解码

java - 应用程序在打开包含 Google map 的页面时崩溃