0

因此,首先這是我第一次發佈,我正在嘗試使用java(1.8)和IntelliJ製作自上而下的遊戲,沒有別的。我已經完成了所有的代碼並且完成了(爲了讓精靈顯示出來),我測試了它,它一直給我提供錯誤消息,指出某些部分是無效的。它應該在頂部就在屏幕上顯示的圖像(人物)是所有的代碼,並請記住,我沒有這個完全結束:從頭開始的2D自上而下的Java(1.8)遊戲(無)

Game.java

package main; 

import main$entities.Player; 
import main$gfx.ImageLoader; 
import main$gfx.SpriteSheet; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.lang.*; 

public class Game extends Canvas implements Runnable { 
    private static final long serialVersionUID = 1L; 
    public static final int WIDTH = 700, HEIGHT = 400, SCALE = 1; 
    public static boolean running = false; 
    public Thread gameThread; 

    private BufferedImage spriteSheet; 

    private Player player; 

    public void init(){ 
     ImageLoader loader = new ImageLoader(); 
     spriteSheet = loader.load("./spritesheet.png"); 

     SpriteSheet ss = new SpriteSheet(spriteSheet); 

     player = new Player(0, 0, ss); 
    } 

    public synchronized void start(){ 
     if(running)return; 
     running = true; 
     gameThread = new Thread(this); 
     gameThread.start(); 
    } 
    public synchronized void stop(){ 
     if(!running)return; 
     running = false; 
     try { 
      gameThread.join(); 
     } catch (InterruptedException e) {e.printStackTrace();} 
    } 

    public void run(){ 
     long lastTime = System.nanoTime(); 
     final double amountOfTicks = 60D; 
     double ns = 1000000000/amountOfTicks; 
     double delta = 0; 

     while(running){ 
      long now = System.nanoTime(); 
      delta += (now - lastTime)/ns; 
      lastTime = now; 
      if(delta >= 1){ 
       tick(); 
       delta--; 
      } 
      render(); 
     } 
     stop(); 
    } 
    public void tick(){ 
     player.tick(); 
    } 
    public void render(){ 
     BufferStrategy bs = this.getBufferStrategy(); 
     if(bs == null){ 
      createBufferStrategy(3); 
      return; 
     } 
     Graphics g = bs.getDrawGraphics(); 
     // Render Here 

     g.fillRect(0, 0, WIDTH * SCALE, HEIGHT * SCALE); 

     player.render(g); 

     // End Render 
     g.dispose(); 
     bs.show(); 
    } 

    public static void main(String[] args){ 
     Game game = new Game(); 
     game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 
     game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 
     game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 

     JFrame frame = new JFrame("Tile RPG"); 
     frame.setSize(WIDTH *SCALE, HEIGHT * SCALE); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.add(game); 
     frame.setVisible(true); 

     game.start(); 
     } 
    } 

ImageLoader.java

package main$gfx; 

import javax.imageio.ImageIO; 

import java.awt.image.BufferedImage; 
import java.io.IOException; 

public class ImageLoader { 

    public BufferedImage load(String path){ 
     try { 
      return ImageIO.read(getClass().getResource(path)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

} 

SpriteSheet.java

package main$gfx; 

import java.awt.image.BufferedImage; 

public class SpriteSheet { 

    private BufferedImage sheet; 

    public SpriteSheet(BufferedImage sheet){ 
     this.sheet = sheet; 
    } 

    public BufferedImage crop(int col, int row, int w, int h){ 
     return sheet.getSubimage(col * 16, row * 16, w, h); 
    } 

} 

Player.java

package main$entities; 

import main.Game; 
import main$gfx.SpriteSheet; 

import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

public class Player implements KeyListener{ 

    private int x, y; 
    private SpriteSheet ss; 
    private boolean up = false, dn = false, lt = false, rt = false; 
    private final int SPEED = 3; 

    public Player(int x, int y, SpriteSheet ss){ 
     this.x = x; 
     this.y = y; 
     this.ss = ss; 
    } 

    public void tick(){ 
     if(up){ 
      y -= SPEED; 
     } 
     if(dn){ 
      y += SPEED; 
     } 
     if(lt){ 
      x -= SPEED; 
     } 
     if(rt){ 
      x += SPEED; 
     } 
    } 

    public void render(Graphics g){ 
     g.drawImage(ss.crop(0 ,0, 16, 16), x, y, 16 * Game.SCALE, 16 * Game.SCALE, null); 
    } 

    public void keyTyped(KeyEvent e) {} 

    public void keyPressed(KeyEvent e) { 

    } 

    public void keyReleased(KeyEvent e) { 

    } 
} 

的錯誤消息(它給我多封郵件,每一次都是不同// =什麼是該線路上的,所以你不必通過找到它算起,您的歡迎):

我第一次運行Game.java:

Exception in thread "Thread-2" java.lang.NullPointerException 
    at main.Game.tick(Game.java:64) // player.tick(); 
    at main.Game.run(Game.java:56) // tick(); 
    at java.lang.Thread.run(Thread.java:745) // this is in the JDK itself 

Process finished with exit code 0 

二(和所有進行)時我運行Game.java:

Exception in thread "Thread-2" java.lang.NullPointerException 
    at main.Game.render(Game.java:77) // player.render(g); 
    at main.Game.run(Game.java:59) // render(); 
    at java.lang.Thread.run(Thread.java:745) // this is in the JDK itself 

Process finished with exit code 0 

回答

0

這是因爲你永遠不調用init()方法,因此玩家,從來沒有被創建

您的spriteheet可以構造添加到遊戲類是這樣的:

public Game() { 
    init(); 
} 

或者你可以在main方法添加以下行:

public static void main(String[] args){ 
    Game game = new Game(); 
    game.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 
    game.setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 
    game.setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE)); 

    JFrame frame = new JFrame("Tile RPG"); 
    frame.setSize(WIDTH *SCALE, HEIGHT * SCALE); 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.setResizable(false); 
    frame.add(game); 
    frame.setVisible(true); 

    // Add this line 
    game.init();   

    game.start(); 
    } 
} 

但我更喜歡第一種方式

+0

讓我知道,如果它幫你:) – 2014-10-19 22:09:30

+0

感謝您的幫助,因爲精靈都顯示不出來...但我可以計算出來。 – PsychedelicPelican 2014-10-20 01:36:03

+0

這是有效的,現在精靈出現了,但我沒有game.start()w/the game.init()第一次沒有錯誤信息,但也沒有精靈,然後我嘗試了兩個並得到精靈,謝謝你大家好,因爲我是新的Java遊戲開發,我完全忘記了調用init()xD – PsychedelicPelican 2014-10-20 01:39:54

1

game.start();承擔全部責任。您的Game類不擴展線程,線程本身將在您實例化您的game's類後自動啓動,因爲線程是在遊戲類中創建的。 所以刪除:

game.start();

順便說一句,你落在陷阱:

public static final int WIDTH = 700, HEIGHT = 400; 

將無法​​正常工作,因爲這些字段隱藏另一個領域,爲什麼?因爲

WIDTH & HEIGHT保留論據

.fillRect(...); 
+0

好的謝謝你soo – PsychedelicPelican 2014-10-19 21:50:11