2012-12-16 21 views
1

所以我想在java中製作一個遊戲,它將顯示一個圖像網格作爲背景,現在它只是草地,偶爾有一塊岩石作爲我的圖像,當它工作時,我獲得32×32像預期的網格的大型顯示,但大約三分之二的時間,我的面板上沒有任何東西出現!Java Jpanel只出現了一半的時間

爲了解決問題,我已經消除了很多功能,並且當我運行代碼時,即使沒有每秒重繪數次,它仍然只會有時工作。

主要類

import javax.swing.JFrame; 


public class Main { 



    public static void main(String[] args) { 
     //Creating a new frame for the whole game and everything 
     JFrame frame = new JFrame("Lawlz this is my game"); 
     frame.setSize(800,800); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     frame.setResizable(false); 

     //adding the game panel to the main frame 
     frame.add(new GameFrame()); 
    } 

} 

遊戲框架類(其中潘內爾製成),這是幾乎所有註釋掉的代碼。即使是動畫和玩家類,但它仍然不會顯示大約一半的時間。

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Random; 

import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class GameFrame extends JPanel {//implements ActionListener { 

    Timer mainTimer; 
    Player player; 
    Random rand = new Random(); 
    Grid GameGrid = new Grid(25, 25); 

    int enemyCount = 5; 

    //Constructer! 
    public GameFrame() 
    { 
     setFocusable(true); 
     //player = new Player(100,100); 
    } 

    //Does all of the drawing for the game 
    public void paint(Graphics g) 
    { 
     //Sends to the JPanel class (super class) 
     super.paint(g); 

     //gets a graphics 2d object 
     Graphics2D g2d = (Graphics2D)g; 

     GameGrid.draw(g2d); 
    } 
} 

GameGrid類,基本上擁有大量的「網格空間」對象,每一個基本上只是一個圖像。它還負責,在這一點上,打印出身邊的一切畫成平局()方法

import java.awt.Graphics2D; 
import java.util.ArrayList; 


public class Grid { 

    ArrayList<GridSpace> grid = new ArrayList<GridSpace>(); 
    int width; 
    int height; 

    public Grid(int w, int h) 
    { 
     width = w; 
     height = h; 

     //Temporary for creating the x and y values by using the size of the images 
     int gw = new GridSpace(0,0).getGridImg().getWidth(null); 
     int gh = new GridSpace(0,0).getGridImg().getHeight(null); 

     for(int i = 0; i < h; i++) 
     { 
      for(int n = 0; n < w; n++) 
      { 
       grid.add(new GridSpace(n*gw,i*gh)); //GridSpace(n*ImageWidth, i*ImageHeight) 
      } 
     } 
    } 

    public void draw(Graphics2D g2d) 
    { 
     for(int i = 0; i < width; i++) 
     { 
      for(int n = 0; n < height; n++) 
      { 
       GridSpace tempSpace = GetGridSpaceByID(GetCoordinates(n,i)); //gets the GridSpace object for this corrdinate 
       g2d.drawImage(tempSpace.getGridImg(),tempSpace.x,tempSpace.y,null); 
      } 
     } 
    } 

    public void test(Graphics2D g2d) 
    { 
     GridSpace tempSpace = GetGridSpaceByID(GetCoordinates(0,0)); 
     g2d.drawImage(tempSpace.getGridImg(),tempSpace.x,tempSpace.y,null); 
    } 

    public GridSpace GetGridSpaceByID(int n) 
    { 
     return grid.get(n); 
    } 

    public int GetCoordinates(int x, int y) 
    { 
     return x + y * width; 
    } 


} 

最後,GridSpace對象,它基本上只是存儲的圖像

import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.image.CropImageFilter; 
import java.awt.image.FilteredImageSource; 
import java.util.Random; 

import javax.swing.ImageIcon; 


public class GridSpace { 
    Random r = new Random(); 
    ImageIcon ic; 
    int x = 0; 
    int y = 0; 

    public GridSpace(int x,int y) 
    { 
     this.x = x; 
     this.y = y; 

     //Stores an image for this grid space 
     //ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\pic1.png"); 
     if(r.nextInt(10) < 9) 
     { 
      ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\Video Game\\grass1.jpg"); 
     } 
     else 
     { 
      ic = new ImageIcon("C:\\Users\\Ben\\Desktop\\Video Game\\grass2.jpg"); 
     } 
    } 

    public Image getGridImg() 
    { 
     //Image image = ic.getImage(); 
     return ic.getImage(); 
    } 
} 

回答

2
  1. GameFrame(可能更準確地被稱爲GamePanel)應該重寫getPreferredSize()返回維度適合玩遊戲區域。框架本身有自己的裝飾,並且會更大。
  2. 主調用順序錯誤。請致電setVisible(true)作爲最後一部分。
  3. 另請注意在EDT上啓動GUI的建議。

這是我目前的「框架演示」模板中的一個主要部分,它顯示了最後兩點&提供了一些其他的好建議。

public static void main(String[] args) { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      // the GUI as seen by the user (without frame) 
      JPanel gui = new JPanel(new BorderLayout()); 
      gui.setBorder(new EmptyBorder(2,3,2,3)); 

      // TODO! 
      gui.setPreferredSize(new Dimension(400,100)); 
      gui.setBackground(Color.WHITE); 

      JFrame f = new JFrame("Demo"); 
      f.add(gui); 
      // Ensures JVM closes after frame(s) closed and 
      // all non-daemon threads are finished 
      f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
      // See http://stackoverflow.com/a/7143398/418556 for demo. 
      f.setLocationByPlatform(true); 

      // ensures the frame is the minimum size it needs to be 
      // in order display the components within it 
      f.pack(); 
      // should be done last, to avoid flickering, moving, 
      // resizing artifacts. 
      f.setVisible(true); 
     } 
    }; 
    // Swing GUIs should be created and updated on the EDT 
    // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html 
    SwingUtilities.invokeLater(r); 
} 
2

由於您目前加入呼籲

frame.setVisible(true); 

它不會被塗到諸如調整大小進行事件後加入GameFrame面板。您應該在main方法中將setVisible作爲最後方法。還可以使用paintComponent而不是paint來利用Swing的優化繪製模型。

強制性鏈接:Painting in AWT and Swing

2

其中的一些問題也可能出現,如果你在主線程中調用的Swing相關的代碼。嘗試在EDT(Event Dispatch Thread)中執行此操作。

要做到這一點,改變你的Main類這樣的:

import javax.swing.JFrame; 

public class Main { 

    public static void main(String[] args) 
    { 
     javax.swing.SwingUtilities.invokeLater (new Runnable() 
     { 
      public void run() 
      { 
       //Creating a new frame for the whole game and everything 
       JFrame frame = new JFrame("Lawlz this is my game"); 
       frame.setSize(800,800); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setVisible(true); 
       frame.setResizable(false); 

       //adding the game panel to the main frame 
       frame.add(new GameFrame()); 
      } 
     }); 
    } 
} 

詳情請參閱here

相關問題