2014-01-05 41 views
0

我是Java的新手,我正在尝试做一个简单的蛇游戏,但paint方法只会被调用一次,永远不会再次运行,即使线程仍在运行。我尝试了另一个修复这个网站,使用另一个类,但没有奏效。重画不能在线程中工作

public class Snake extends JPanel implements Runnable { 

boolean gamerunning = true; 
    int snake_x = 50, snake_y = 50, snake_dir = 2; //for snake_dir 1=up 2=right 3=down 4=left 
    int[] snake_xt, snake_yt; 

    public static void main(String args[]) { 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(600,600); 
     frame.setVisible(true); 
     frame.add(new Snake()); 

     (new Thread(new Snake())).start(); 
     System.out.println("Running"); 
    } 

    @Override 
    public void run() { 
     try { 
      while (gamerunning) { 
       Thread.sleep(500); 
       System.out.println(snake_x); 
       tick(); 
       repaint(); 
      } 
     } catch (InterruptedException e) {} 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     System.out.println("painting"); 
     g.setColor(Color.black); 
     g.fillRect(snake_x, snake_y, 10,10); 
    } 

    public void tick() { 
     System.out.println("tick"); 
     switch(snake_dir) { 
      case 1: 
       snake_y -= 10; 
       break; 
      case 2: 
       snake_x += 10; 
       break; 
      case 3: 
       snake_y += 10; 
       break; 
      case 4: 
       snake_x -= 10; 
       break; 
     } 
    } 
} 
+1

对这种类型的模型很熟悉。在更新其依赖的值时,组件可能正在被绘制过程中...... – MadProgrammer

+0

您的设置不正确:必须在EDT上访问摆动组件**的属性 - 该规则适用于自定义属性(如snake_x/y)与“普通”属性(如背景)相同。从另一个线程调用tick()违反了规则。 – kleopatra

回答

1

你的问题是:你没有添加相同的蛇你正在绘制!

frame.add(new Snake()); 

(new Thread(new Snake())).start(); 

每一行都会创建一个新的Snake,第一个被绘制,第二个被移动。

尝试

Snake s = new Snake(); 
frame.add(s); 

(new Thread(s)).start(); 

代替。

+3

即使它在此修复程序后正常工作,仍然是解决方案的误导性方法。这里应该使用一个Swing'Timer'。 –

+0

好吧,还有很多其他问题,例如空的catch块,方向的幻数,使用int []而不是Point,...但是由于OP是java的新手,它可能不是一个坏东西想法,做一些很好的旧尝试和错误。 –

+1

我留下了评论,希望引起OP的兴趣:) –