我正在用Java编写一个pong游戏来玩这种语言,并且想知道为什么我的重绘方法没有重新绘制屏幕上的图像。基本上我想要的是当球击中屏幕的任一侧以启动玩家得分时,我想在其起始位置重新绘制所有内容以模拟重置。我试过在整个地方重新粉刷,但它要么导致一切锁定,要么游戏继续进行,好像什么也没发生。
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);
}
}
}
}
任何帮助都将不胜感激。
答案 0 :(得分:1)
好的,这里有一些问题。
首先,您应该覆盖paintComponents
而不是paint
。
其次,repaint()
调用paint
。所以你的游戏锁定的原因是你有效地强迫它进入一个永无止境的循环。调用paint
,调用repaint
调用paint
等等等。
最后,正如carmickr在评论中所说,你不应该在paint
方法中改变组件属性。
因此。把所有这些放在一起,我建议你重新审视actionPerformed
逻辑。正如你所说,你在学习,我有点厌恶你只需要一堆代码,但有一些提示:
您在checkCollision
中确定是否得分。那么从该方法返回一些东西到你的actionPerformed
方法 - 如果一个点得分,那么这样做,如果不是那么那么做。最后,你需要调用paintComponent
,这样你就需要一些标志 - 可能是一个布尔变量 - 告诉paintComponent
是否要绘制蝙蝠的更新位置或者至少初始位置,carmickr建议重置位置,只有一条路线通过paintComponent
是更好的。
我希望这会有所帮助。
答案 1 :(得分: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();
}
当整个游戏运行时,这将基本上重新绘制屏幕,并按照你的逻辑进行操作。
希望这有帮助!