2016-09-28 2 views
-1

Also ich versuche, Snake auf einem JFrame zu programmieren und alle grafischen Sachen (Bewegen der "Schlange", zufällige Lebensmittelgeneration usw.) auf einem JPanel. Ich bin am Anfang, also versuche ich gerade ein schwarzes Quadrat mit den Pfeiltasten auf meinem Rahmen zu bewegen. Meine while-Schleife in der Panel-Klasse wird nicht durch einen Tastendruck in der Snake-Klasse unterbrochen. Gibt es also eine Möglichkeit, JPanel-Grafiken aus derselben Klasse mit all meinem anderen Code zu bearbeiten?Wie kann ich JPanel Graphics in einer Klasse bearbeiten?

Hier ist der gesamte Code. Meine Panel-Klasse am Ende folgt der Vorlage, die ich hier gefunden habe.

public class Snake { 

    // panel width and height 
    static int pW; 
    static int pH; 

    static int x = 10; 
    static int y = 10; 

    static int k; 

    static JFrame frame = new JFrame("SNAKE"); 

    // getters for panel class 
    public int getPW() { return pW; } 
    public int getPH() { return pH; } 
    public int getX() { return x; } 
    public int getY() { return y; } 

    public static void main(String[] args) { 

     // get screen dimensions 
     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
     int sH = (int) screenSize.getHeight(); 
     int sW = (int) screenSize.getWidth(); 

     pW = (int) sW/2; 
     pH = (int) sH/2; 

     // initialize frame 
     frame.setSize (pW/1,pH/1); 
     frame.setLocation(pW/2,pH/2); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.addKeyListener(new KeyAdapter() { 

      public void keyPressed(KeyEvent e) { 

       k = e.getKeyCode(); 

       switch(k) { 

       case 38: /* y -= square size */ break; // up 
       case 40: /* y += square size */ break; // down 
       case 37: /* x -= square size */ break; // left 
       case 39: /* x += square size */ break; // right 
       case 27: System.exit(0); 

       } 

      } 
     }); 

     Panel panel = new Panel(); 

     frame.add(panel); 

     frame.setVisible(true); 

    } 

} 

class Panel extends JPanel { 

    Snake snake = new Snake(); 

    //square size and separation between squares 
    int sep = 0; 
    int size = 50; 

    // initial location of square on the panel/frame 
    int x = sep + size; 
    int y = sep + size; 

    // holding values to check if x or y have changed 
    int xH = x; 
    int yH = x; 

    public void paint(Graphics g) { 

     int pW = snake.getPW(); 
     int pH = snake.getPH(); 

     int i; int o; 

     Color on = Color.BLACK; 
     Color off = Color.GRAY; 

     // gray background 
     g.setColor(Color.GRAY); 
     g.fillRect(0,0,pW,pH); 

     // black square initialization 
     g.setColor(Color.BLACK); 
     g.fillRect(x, y, size, size); 

     /* this loop is supposed to check if the black 
     * rectangle has moved by repeatedly grabbing x & y 
     * values from the Snake class. When a key is pressed 
     * and the values change, a gray rectangle is placed at the old location 
     * and a black one is placed at the new location. 
     * 
     * When I run the program, I get stuck in this while loop. 
     * If I had the while loop in the same class I check for keys, 
     * I don't think I would have this problem 
     */ 

     while(true) { 

      x = snake.getX(); 
      y = snake.getY(); 

      if(x != xH || y != yH) { 

      g.setColor(off); 
      g.fillRect(xH, yH, size, size); 
      g.setColor(on); 
      g.fillRect(snake.getX(), snake.getY(), size, size); 

      xH = x; 
      yH = y; 

     }} 

    } 
} 

Antwort

2

Sie sollten nie eine while(true) Schleife in einer Malweise haben. Dies verursacht nur eine Endlosschleife und Ihre GUI kann nicht auf Ereignisse reagieren.

Stattdessen müssen Sie Ihrer Schlangenklasse Methoden hinzufügen, um die Schlange zu bewegen. Wenn Sie also eine der Pfeiltasten drücken, aktualisieren Sie die Startposition der Schlange. Dann ruft die Methode repaint() auf und die Schlange wird neu gezeichnet, wenn die Methode paintComponent() von Swing aufgerufen wird.

Daher sollte Ihr Malcode paintComponent() nicht paint() überschreiben und Sie sollten super.paintComponent(g) als erste Anweisung in der Methode aufrufen.

Nennen Sie nicht Ihre benutzerdefinierte Klasse "Panel", es gibt eine AWT-Klasse mit diesem Namen. Machen Sie Ihren Klassennamen aussagekräftiger.

Verwandte Themen