2016-05-13 11 views
1

Ich habe versucht, die Grafiken für mein Spiel anzuzeigen, aber keine der Grafiken werden auf dem Panel angezeigt.Java-Grafiken werden nicht angezeigt

Folgendes ist mein Code. Die Hauptklasse ruft die Paint-Methoden der anderen beiden Klassen auf.

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Simulator extends JFrame implements KeyListener, Runnable, ActionListener { 

    private final int WIDTH, HEIGHT; 
    private Boolean right; 
    private int xMotion; 
    public Salt salt; 
    public Player playR; 
    Boolean running = false; 
    private Thread thread; 
    public static int score, highScore; 
    private int saltSpeed; 

    public Simulator(int width, int height) { 
     JPanel panel = new JPanel(); 
     JFrame frame = new JFrame(); 
     frame.setResizable(false); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     frame.setSize(width, height); 
     panel.setBackground(Color.BLACK); 
     frame.add(panel); 

     playR = new Player(); 


     this.HEIGHT = height; 
     this.WIDTH = width; 
     int xCordSalt = (int) (Math.random() * 631); 
     saltSpeed = 1; 

     salt = new Salt(saltSpeed); 
     right = true; 
     running = true; 

    } 


    public static void main(String[] args) { 
     Simulator game = new Simulator(640, 480); 

     game.start(); 
    } 

    public void paintComponent(Graphics g) 
    { 


     salt.paint(g); 
     playR.paint(g); 



    } 

    public void start() { 

     running = true; 
     thread = new Thread(this); 
     thread.start(); 
     repaint(); 
     tick(); 
     run(); 


    } 

    public void stop() { 
     running = false; 
     System.exit(0); 
    } 


    @Override 
    public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_D) { 
      right = true; 
     } else if (e.getKeyCode() == KeyEvent.VK_A) { 
      right = false; 

     } 

    } 

    public void tick() { 
     salt.tick(this, playR); 
     playR.tick(); 

    } 

    @Override 
    public void keyReleased(KeyEvent e) { 


    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     if(e.getKeyCode() == KeyEvent.VK_D) 
     { 
      playR.setDirection(true); 
     } 
     else if(e.getKeyCode() == KeyEvent.VK_A) 
     { 
      playR.setDirection(false); 
     } 

    } 

    @Override 
    public void run() { 
     while (running) { 
      tick(); 
      repaint(); 

      try { 
       thread.sleep(7); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 



    public void incrementScore() { 
     score++; 

    } 


    @Override 
    public void actionPerformed(ActionEvent e) { 
     repaint(); 
     tick(); 

    } 

}

Und hier ist der Code für das Verfahren Salz:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.util.ArrayList; 



public class Salt extends Rectangle{ 

    private final int WIDTH = 10; 
    private final int HEIGHT = 10; 
    public int xCordSalt, yCordSalt; 
    private int speed; 
    Rectangle boundBox; 
    public Salt(int speedx) 
    { 

     xCordSalt = (int)Math.random()*641; 
     yCordSalt = 0; 
     speed = speedx; 
     boundBox = new Rectangle(xCordSalt, yCordSalt, WIDTH, HEIGHT); 
     boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT); 



    } 

    public void tick(Simulator sim, Player playR) 
    { 
     boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT); 

     if(yCordSalt >= 480) 
     { 
      //sim.stop(); 
     } 

     else if(checkCollision(playR)) 
     { 
      sim.incrementScore(); 
      speed++; 
      yCordSalt = -speed; 

     } 


     yCordSalt = yCordSalt + speed; 


    } 




    public boolean checkCollision(Player playR) 
    { 
     if(this.getBoundBox().intersects(playR.getBoundBox())) 
     { 
      return true; 
     } 
     return false; 
    } 

    public void paint(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillRect(xCordSalt, yCordSalt, WIDTH, HEIGHT); 
    } 

    public Rectangle getBoundBox() 
    { 
     return boundBox; 
    } 

    public double getSpeed() 
    { 
     return speed; 
    } 


} 

Und schließlich das Verfahren Spieler, der die ImageIcon-Klasse verwendet, um ein Bild anzuzeigen:

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 

import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

public class Player extends JPanel { 
    private int xCord, yCord; 
    public Rectangle boundBox; 
    private static ImageIcon ryan; 
    boolean isRight; 

    public Player() { 
     ryan = new ImageIcon("E:\ryan.png"); 
     xCord = 640/2; 
     yCord = 460; 
     boundBox = new Rectangle(xCord, yCord, 20, 20); 


    } 

    public static void main(String[] args) { 

    } 

    public void tick() { 

    } 

    public void setDirection(Boolean right) 
    { 
     if(right) 
      isRight = true; 
     else 
      isRight = false; 
    } 


    public void paint(Graphics g) { 
     Graphics2D g2d = (Graphics2D)g; 
     g2d.drawImage(ryan.getImage(), xCord, yCord, null); 


    } 

    public Rectangle getBoundBox() 
    { 
     return boundBox; 
    } 

} 

Jetzt sind einige davon unvollständig, aber ich kann nicht erkennen, warum es überhaupt keine Grafiken anzeigt. Wenn sie ausgeführt wird, erscheint nur ein schwarzer Rahmen/ein schwarzes Feld. Ich habe einige print-Anweisungen zu den tick() - Methoden jeder Klasse, den paint() -Methoden jeder Klasse und der paintComponent() -Methode und der start() -Methode hinzugefügt. Das Spiel wird starten, führen Sie die Tick-Methode jeder Klasse aus, aber paintComponent() oder eine der paint() -Methoden werden immer aufgerufen!

+0

Sie müssen '" E: \ ryan.png "' in '" E: \\ ryan.png "' ändern. Der umgekehrte Schrägstrich (\) ist ein Escape-Zeichen. Um einen tatsächlichen umgekehrten Schrägstrich in eine Zeichenfolge einzufügen, müssen Sie den umgekehrten Schrägstrich mit einem anderen umgekehrten Schrägstrich umgehen. – VGR

+0

@ursinusTheStrong oh man, wie könnte ich über Escape-Sequenzen vergessen! Danke, dass du mich erinnert hast! –

+0

JFrame hat keine paintComponent-Methode, daher wird sie nie aufgerufen. Deshalb sollten Sie @Override verwenden. Erstellen Sie eine Klasse, die von einem JPanel ausgeht, überschreiben Sie ihre paintComponent-Methode und führen Sie dort ein angepasstes Keeping aus. Stellen Sie sicher, dass Sie zuerst super.paintComponent aufrufen. Eine Idee ist es, eine Entity zu erstellen, die ein Element in deinem Spiel beschreibt, high do "stuff" eines dieser Elemente wäre dann "paintable", welches eine Methode hat, an die du eine Referenz von Graphics übergeben kannst und die sich selbst zeichnet So, alles, was Sie tun müssen, ist eine Liste von Entitäten zu pflegen, aktualisieren Sie die und malen sie – MadProgrammer

Antwort

0

Zuerst Sie einen Rahmen über die Erstellung - die Klasse selbst ist ein Rahmen, so dass keine Notwendigkeit für mehr:

setSize(width, height); 
    setVisible(true); 

Zweite Sie ein Panel hinzufügen, auf sie: die alles abdecken wird;

Dritte JFrame hat keine paintComponent - stattdessen verwenden Sie paint().

Viertens, beim Starten des Threads durch Aufruf von start() wird die run() -Methode automatisch aufgerufen - kein Aufruf von run().

Hier ist meine Arbeits Konstruktor und paint-Methode:

public Simulator(int width, int height) { 
    setSize(width, height); 
    panel.setBackground(Color.BLACK); 
    setVisible(true); 

    try { 
     bim=ImageIO.read(new File(.....)); 
    } 
    catch (Exception ex) { ex.printStackTrace(); } 


    this.HEIGHT = height; 
    this.WIDTH = width; 
    int xCordSalt = (int) (Math.random() * 631); 
    saltSpeed = 1; 

    right = true; 
    running = true; 

} 


public void paint(Graphics g) 
{ 

    g.setColor(Color.magenta); 
    g.fillRect(0, 0, 100, 100); 
    g.drawImage(bim, 100, 0, null); 

} 
+0

dann in der Paint-Methode sollte ich hinzufügen salt.paint (mit Parametern) und playR.paint()? Auch, vielen Dank für die Hilfe! Ich und meine Kollegen waren sehr verwirrt, warum es nicht funktionierte. –

+1

Nicht direkt auf einen JFrame malen. Malen Sie mit der paintComponent-Methode eines JPanels, das einem JFrame hinzugefügt wird. Hier ist ein [Beispiel] (http://stackoverflow.com/questions/34981403/bufferedimage-not-being-cleared-before-each-rendering/35002727#35002727). –

+0

@GilbertLeBlanc Dies ist, was ich in meinem Programm tat, also warum druckt nichts auf dem Bildschirm? Hier passiert was passiert, wenn ich den unbearbeiteten Code ausführe: https://gyazo.com/a4540ae5d3233c22c791cf7f0fb7afec Ich habe auch eine print-Anweisung in der paintComponent-Methode, paint-Methode für die Salz- und Player-Klasse verwendet und keine davon druckt irgendetwas, was bedeutet, dass sie müssen nicht angerufen werden. –

1

Beginnen wir mit dem Offensichtlichen beginnen ...

public class Simulator extends JFrame ... { 
    //... 
    public void paintComponent(Graphics g) { 

     salt.paint(g); 
     playR.paint(g); 

    } 

JFrame kein Verfahren paintComponent genannt haben, so dass Ihr paintComponent nie sein genannt, so werden salt und playR nie gemalt.

können Sie dies testen, indem @Override zum paintComponent Zugabe, die für Sie Dies wird scheitern

public class Simulator extends JFrame ... { 
    //... 
    @Override 
    public void paintComponent(Graphics g) { 

     salt.paint(g); 
     playR.paint(g); 

    } 

eine Kompilierung Plausibilitätsprüfung tut zu kompilieren.

Nun könnte man paint stattdessen außer Kraft setzen, aber because, because, because, because, because ... Ich würde es nicht empfehlen ...

Machen Sie einen Schritt zurück für eine Sekunde. Was ist die JFrame wirklich verantwortlich? Bereitstellung eines Containers, auf dem Sie gui hinzufügen und auf dem Bildschirm anzeigen lassen können. Sie fügen der JFrame keine neuen Funktionen hinzu, also würde ich sie nicht als Ihre "Haupt" -Komponente verwenden, stattdessen würde ich nur eine Instanz davon erstellen und alle Komponenten hinzufügen, die Sie verwenden möchten.

Stattdessen würde ich mit einem JPanel starten und überschreiben Sie die paintComponent Methode und legen Sie alle Ihre benutzerdefinierten Gemälde hinein.

Ich würde dann diese Komponente als Ausgangspunkt für Ihre Kern-Logik und Controller verwenden.

Sie können sogar mehrere Komponenten erstellen, die wie die Menü- und Optionsansichten funktionieren, und sie mit CardLayout oder OverlayoutLayout anzeigen.

Ich würde auch empfehlen, einen Blick auf How to Use Key Bindings anstelle von KeyListener während Sie gerade dabei sind, dies wird Ihre nächste Frage beantworten.

+0

Irgendein Grund für die Abstimmung unten? Beantwortet es nicht die Ops-Frage? Inwiefern könnte es verbessert werden? – MadProgrammer

+0

Nicht dein Downvoter; Ich stimme zu, dass "Swing-Programme" paintComponent() 'außer Kraft setzen sollten, anstatt" paint() "zu überschreiben." - [* Painting in AWT and Swing: Die Malmethoden *] (http://www.oracle.com/technetwork/ Java/painting-140037.html # Rückrufe). – trashgod