2013-12-13 69 views
0

我想在Java中制作pong游戏,但它不起作用。 我直接做了一些测试,似乎变量更新,但是,当我在做定时器 repaint();actionPerformed(ActionEvent e)不调用paintComponent()方法repaint()不调用paintComponent()

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class PongGame extends JComponent implements ActionListener, MouseMotionListener{ 

    public int state = 1; 
    public int paddleX; 
    public String buttonColor = "blue"; 
    public int mouseX, mouseY; 
    private int ballX = 400; 
    private int ballY = 150; 

    public static void main(String[] args){ 

     JFrame window = new JFrame("Pong"); 
     PongGame game = new PongGame(); 
     window.add(new PongGame()); 
     window.pack(); 
     window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     window.setLocationRelativeTo(null); 
     window.setResizable(false); 
     window.setVisible(true); 

     Timer t = new Timer(20, game); 
     t.start(); 
    } 

    public Dimension getPreferredSize(){ 
     return new Dimension(800, 600); 
    } 

    public void paintComponent(Graphics g){ 
     paddleX = mouseX; 

     g.setColor(Color.WHITE); 
     g.fillRect(0,0, 800, 600); 

     g.setColor(Color.BLACK); 

     g.fillRect(paddleX, 550, 150, 15); 
     g.fillOval(ballX, ballY, 30, 30); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     ballX = ballX + 10; 
     ballY = ballY + 10; 
     System.out.println(ballX + " " + ballY); 

    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
     mouseX = e.getX(); 
     repaint(); 
    } 
} 

回答

0

重绘()不调用paint() 。它调度一个中间方法update()。最后,update()调用paint()(除非你覆盖更新)。

这种复杂性的原因是Java对并发编程的支持。它使用线程来做到这一点。

使用repaint()可能会非常棘手,至少有三个原因。

  1. )重绘(),并通过GUI线程
  2. 是重新绘制的事实(做自发绘画之间的相互作用只是要求线程系统来安排的update()/油漆(),然后退出。 repaint()方法是异步的。
  3. 更新时防止绘图被擦除的问题。

我建议你试试update()。

有用的链接:http://www.scs.ryerson.ca/~mes/courses/cps530/programs/threads/Repaint/index.html

+1

你的建议对于AWT是有好处的,但不适用于不应该调用update()的应用程序,除非它被调用来更新外观和感觉。 –

+0

另请参见:[查看编辑](http://stackoverflow.com/posts/20573439/revisions)以了解如何创建“有序列表”。请在句子开头添加大写字母。还要为单词I使用大写字母,并使用JEE或WAR等缩写词和首字母缩略词。这使人们更容易理解和帮助。 –

+1

有关更多详细信息,请参阅Oracle的文章[使用Swing和AWT绘画](http://www.oracle.com/technetwork/java/painting-140037.html),查看它们为什么陈述'“...原因update()永远不会在Swing组件上调用...“。 –

1

的问题是:

PongGame game = new PongGame(); 
window.add(new PongGame()); 

你有PongGame两个实例。一个添加到框架(new PongGame())和另一个(game)实际上反应到计时器。将此行更改为:

window.add(game); 
1

纠正实际问题。添加一个构造函数(本地测试):

PongGame() { 
    addMouseMotionListener(this); 
} 
+0

但正如其他人所指出的那样,'PongGame game = new PongGame();'是完全多余的。 –

+0

我希望你在公开分享之前回顾一下我告诉你的我的吉夫节目。你会给我你的意见吗? – Sage

+0

*“我希望你回顾一下我的吉夫计划..”*如果你是在OO设计建议之后,我是错误的人要问。你的意思是“普遍”吗?如果是这样,你可以通过gmail的andrewthommo联系我。 –

4
  • 您还没有注册的实施MouseMotionListener任何组件:

    game.addMouseMotionListener(game); 
    
  • 您不添加的PongGame你的第一个创建的实例而是增加了一个新的产生bug:

    PongGame game = new PongGame(); 
        window.add(new PongGame()); // <<--- why creating the new instance ? 
           // it should be window.add(game); 
    
  • 作为一种良好的编程习惯:尝试在组件自己的创建上下文中添加侦听器代码,即在其构造函数中使代码更易读。

相关问题