2016-05-26 22 views
0

Ich arbeite an einem einfachen Spiel, das 1 Spieler (das Quadrat) und einige Feinde, die zufällig im Spielbereich spawnen, erfordert. Ich stoße derzeit auf ein Problem, denn wenn ich mein Programm ausführe, wird durch das Drücken einer beliebigen Pfeiltaste nicht nur der neue Standort des Spielers neu gezeichnet, sondern es werden auch alle Feinde an den neuen Orten neugespawnt.Wie verhindere ich, dass mein KeyEvent beide Objekte neu erstellt?

Ich habe meinen Code ein paar Mal durchlaufen und bin immer noch ratlos, warum das passiert. Jede Hilfe würde sehr geschätzt werden.

P.S. Ich bin kein sehr erfahrener Programmierer, daher kann es sein, dass ein Teil dieses Codes nicht so effizient wie möglich ist und einige Dinge möglicherweise falsch sind. fühlen Sie sich frei, irgendwelche Fehler neben dem vorliegenden Problem aufzuzeigen. Vielen Dank!

Hauptklasse

public class Eat { 

    public static void main(String[] args) { 

     // Creating the main frame 
     JFrame main = new JFrame("Eat 'Em All - Version 1.0.2"); 
     main.setSize(497, 599); 
     main.setLocationRelativeTo(null); 
     main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     main.setResizable(false); 

     // Colours and borders 
     Border areaBorder = new LineBorder(Color.LIGHT_GRAY, 3); 

     // Creating main JPanel 
     JPanel area = new JPanel(); 
     area.setLayout(new BoxLayout(area, BoxLayout.PAGE_AXIS)); 
     area.setBackground(Color.WHITE); 
     main.setContentPane(area); 

     // Creating the drawing/image/player 
     DrawPlayer player = new DrawPlayer(); 
     player.setPreferredSize(new Dimension(497, 539)); 
     player.setOpaque(false); 

     // Enemies 
     DrawEnemy enemy = new DrawEnemy(); 
     enemy.setPreferredSize(new Dimension(497, 539)); 
     enemy.setBackground(Color.WHITE); 

     // Creating the control panel for buttons, etc 
     JPanel control = new JPanel(); 
     control.setPreferredSize(new Dimension(497, 60)); 
     control.setLayout(new GridLayout(1, 2, 0, 0)); 
     control.setBorder(areaBorder); 

     JLabel welcome = new JLabel(" Welcome to Eat 'Em All |--| Press 'Start'"); 
     JButton start = new JButton("Start"); 

     // Adding it all to the frame 
     main.add(enemy); 
     enemy.add(player); 
     control.add(welcome); 
     control.add(start); 
     area.add(control); 

     // Adding keylistener and making button false 
     player.addKeyListener(player); 
     player.setFocusable(true); 
     start.setFocusable(false); 
     enemy.setFocusable(false); 

     // Bring frame to front and visible 
     main.toFront(); 
     main.setVisible(true); 

     System.out.println(player.getWidth()/2); 
     System.out.println(player.getHeight()/2); 

    } 

} 

Zeichnung Spieler Klasse

public class DrawPlayer extends JPanel implements KeyListener { 

    long xPosition = 0; 
    long yPosition = 0; 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     // Making loop to get points and move it 
     // Center of area is x: 245 y: 255 
     int xPoints[] = {235, 255, 255, 235, 235, 255}; 
     int yPoints[] = {265, 265, 245, 245, 265, 245}; 
     for (int i = 0; i < xPoints.length; i++) { 
      xPoints[i] += xPosition; 
      yPoints[i] += yPosition; 
     } 

     g.setColor(Color.BLUE); 
     g.drawPolygon(xPoints, yPoints, xPoints.length); 
    } 

    public void keyPressed(KeyEvent e) { 
     switch (e.getKeyCode()) { 
      case KeyEvent.VK_DOWN: 
       if (yPosition == 245) { 
        yPosition -= 5; 
       } else { 
        yPosition += 5; 
       } 
       break; 
      case KeyEvent.VK_UP: 
       if (yPosition == -245) { 
        yPosition += 5; 
       } else { 
        yPosition -= 5; 
       } 
       break; 
      case KeyEvent.VK_LEFT: 
       if (xPosition == -235) { 
        xPosition += 5; 
       } else { 
        xPosition -= 5; 
       } 
       break; 
      case KeyEvent.VK_RIGHT: 
       if (xPosition == 235) { 
        xPosition -= 5; 
       } else { 
        xPosition += 5; 
       } 
       break; 
     } 
     repaint(); 
    } 

    public void keyReleased(KeyEvent e) { 

    } 

    public void keyTyped(KeyEvent e) { 

    } 
} 

Zeichnung Enemies Klasse

public class DrawEnemy extends JPanel { 

    public void paintComponent(Graphics f) { 
     super.paintComponent(f); 

     for (int i = 0; i < 10; i++){ 
      f.setColor(Color.RED); 
      f.drawOval((int)(Math.random() * ((440 - 0) + 0) + 0), (int)(Math.random() * ((500 - 0) + 0) + 0), 50, 50); 
     } 
    } 
} 

Antwort

1

Sie haben ein Problem hier:

public void paintComponent(Graphics f) { 
    super.paintComponent(f); 

    for (int i = 0; i < 10; i++){ 
     f.setColor(Color.RED); 
     f.drawOval((int)(Math.random() * ((440 - 0) + 0) + 0), (int)(Math.random() * ((500 - 0) + 0) + 0), 50, 50); 
    } 
} 

Sie Programmlogik innerhalb eines Gemäldes Methode haben, etwas, das Sie nie tun sollten, da man nie die volle Kontrolle darüber hat, wann oder sogar ob ein Gemälde Methode aufgerufen wird . Die Lösung, erhalten Sie die Randomisierung der paintComponent-Methode und in seine eigene separate Methode, eine, die Sie aufrufen, wenn und nur wenn Sie die Feinde randomisieren möchten, und nicht jedes Mal, wenn Sie neu streichen.

Weitere Themen:

  • Separate Programmlogik von Ihrem GUI.
  • Zum Beispiel sollten Sie eine Nicht-GUI-Feind-Klasse haben, eine, die Felder für ihre eigene Position, ihre Größe, ihre Bewegung, vielleicht eine move() Methode, vielleicht eine collision(Player p) Methode hat.
  • Sie sollten nur eine JPanel, die Zeichnung und das sollte seine einzige Aufgabe sein.
  • Wieder binden Sie keine Bewegung von etwas an die Malmethode.
  • Sie möchten eine Spielschleife, vielleicht einen Swing Timer. Dadurch werden regelmäßig verstreute Ticks erzeugt, die Gegner und Spieler dazu bringen, sich zu bewegen.
  • Entfernen Sie den KeyListener-Code und favorisieren Sie Key Bindings. Letzteres ist weniger kludrig, wenn es um Komponentenfokussierung geht. Überprüfen Sie das Tutorial dafür.
+0

Wie würde ich das tun? Ich habe gerade Ihren Vorschlag ausprobiert, aber ich kann es mir nicht vorstellen. (Tut mir leid, wenn es so aussieht, als ob ich die Antwort mit einem Löffel gefüttert haben möchte, es ist sehr spät hier und ich versuche, das zu beheben, haha.) – jxshu

+0

@jzbakos: Hör zu, du hast eine Menge Code gepostet, ich bin ein müder Freiwilliger, und ich werde Ihnen empfehlen, weiter daran zu arbeiten. Was hast du probiert? Warum funktioniert es nicht? Weiter versuchen. –

+0

Ich habe die for-Schleife in der paintComponent-Methode eigentlich nur komplett entfernt, so dass jetzt nur noch 1 Gegner gezogen wird. Das Drücken der Tasten wird jedoch immer noch aus irgendeinem Grund neu gestartet. – jxshu