0

我正在用 Java 制作一个乒乓球游戏来玩这个语言,并且想知道为什么我的重绘方法没有重绘屏幕上的图像。基本上我想要的是当球击中屏幕的任一侧以启动球员得分时,我想在其起始位置重新绘制所有内容以模拟重置。我已经尝试在整个地方重新绘制,但它要么导致一切都锁定,要么游戏继续进行,好像什么都没发生一样。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Rectangle;

import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener
{
    private Timer timer;
    private PlayerOne paddle;
    private PlayerTwo paddle2;
    private Ball ball;
    private boolean ingame = true;
    int playeronescore = 0;
    int playertwoscore = 0;

    public Board()
    {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setDoubleBuffered(true);

        paddle = new PlayerOne();
        paddle2 = new PlayerTwo();
        ball = new Ball();

        timer = new Timer(5, this);
        timer.start();
    }

public void paint(Graphics g)
{
    if(ingame)
    {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(), this);
        g2d.drawImage(paddle2.getImage(), paddle2.getX(), paddle2.getY(), this);
        g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),this);
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }
    else
    {
        restartGame();
        repaint();
    } 
}

public void actionPerformed(ActionEvent e)
{
    paddle.move();
    paddle2.move();
    ball.move();
    checkCollision();
    repaint();
}

private class TAdapter extends KeyAdapter
{
    public void keyPressed(KeyEvent e)
    {
        paddle.keyPressed(e);
        paddle2.keyPressed(e);
    }

    public void keyReleased(KeyEvent e)
    {
        paddle.keyReleased(e);
        paddle2.keyReleased(e);
    }
}
public void restartGame()//resetting the paddles and ball into their initial positions
{
    paddle.setX(0);
    paddle.setY(60);
    paddle2.setX(280);
    paddle2.setY(60);
    ball.setX(140);
    ball.setY(60);

}
public void checkCollision()
{
    Rectangle r1 = paddle.getBounds();
    Rectangle r2 = paddle2.getBounds();
    Rectangle r3 = ball.getBounds();

    if(ball.getX() == 0)
    {
        playeronescore++;
        ingame = false;
    }

    if(ball.getX() == 280)
    {
        playertwoscore++;
        ingame = false;
    }

    if(r3.intersects(r1))
    {
        int paddleLPos = (int)paddle.getBounds().getMinX();
        int ballLPos = (int)ball.getBounds().getMinX();

        int first = paddleLPos + 8;
        int second = paddleLPos + 16;
        int third = paddleLPos + 24;
        int fourth = paddleLPos + 32;

        if (ballLPos < first) {
            ball.setXDir(-1);
            ball.setYDir(-1);
        }

        if (ballLPos >= first && ballLPos < second) {
            ball.setXDir(-1);
            ball.setYDir(-1 * ball.getYDir());
        }

        if (ballLPos >= second && ballLPos < third) {
            ball.setXDir(0);
            ball.setYDir(-1);
        }

        if (ballLPos >= third && ballLPos < fourth) {
            ball.setXDir(1);
            ball.setYDir(-1 * ball.getYDir());
        }

        if (ballLPos > fourth) {
            ball.setXDir(1);
            ball.setYDir(-1);
        }           
    }
    else if(r3.intersects(r2))
    {
        int paddleLPos = (int)paddle2.getBounds().getMinX();
        int ballLPos = (int)ball.getBounds().getMinX();

        int first = paddleLPos + 8;
        int second = paddleLPos + 16;
        int third = paddleLPos + 24;
        int fourth = paddleLPos + 32;

        if (ballLPos < first) {
            ball.setXDir(-1);
            ball.setYDir(-1);
        }

        if (ballLPos >= first && ballLPos < second) {
            ball.setXDir(-1);
            ball.setYDir(-1 * ball.getYDir());
        }

        if (ballLPos >= second && ballLPos < third) {
            ball.setXDir(0);
            ball.setYDir(-1);
        }

        if (ballLPos >= third && ballLPos < fourth) {
            ball.setXDir(1);
            ball.setYDir(-1 * ball.getYDir());
        }

        if (ballLPos > fourth) {
            ball.setXDir(1);
            ball.setYDir(-1);
        }           
    }
}

}

任何帮助,将不胜感激。

4

2 回答 2

1

好的,这里有一些问题。

首先你应该覆盖paintComponentsnot paint

二是repaint()打电话paint。所以你的游戏被锁定的原因是你有效地迫使它进入一个永无止境的循环。 paint被调用,哪个调用repaint哪个调用paint哪个等等等等。

最后,正如 carmickr 在评论中所说,您不应该更改paint方法中的组件属性。

所以。把所有这些放在一起,我建议你重新审视一下actionPerformed逻辑。正如你所说你正在学习我有点讨厌只是给你一堆代码,但有一些提示:

您确定checkCollision是否得分。从那个方法返回一些东西到你的actionPerformed方法怎么样 - 如果已经得分,那么就这样做,如果没有,那么就这样做。最后你需要打电话paintComponent,所以你需要一些标志 - 可能是一个布尔变量 - 告诉paintComponent是否绘制蝙蝠的更新位置或至少初始位置,carmickr 的重置位置的建议,只是有一条路线通过paintComponent是更好的路线。

我希望这有帮助。

于 2013-05-20T01:18:04.437 回答
0

尝试改变

  public void paint(Graphics g)
  {
if(ingame)
{
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(), this);
    g2d.drawImage(paddle2.getImage(), paddle2.getX(), paddle2.getY(), this);
    g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),this);
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}
else
{
    restartGame();
    repaint();
} 

}

 public void paint(Graphics g)
{
if(ingame)
{
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(), this);
    g2d.drawImage(paddle2.getImage(), paddle2.getX(), paddle2.getY(), this);
    g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),this);
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
}
else
{
    restartGame();

} 
  repaint();
}

这实际上将在整个游戏运行时重新绘制屏幕,​​而不是按照您的逻辑进行。

希望这可以帮助!

于 2013-05-19T22:56:03.687 回答