2013-07-27 75 views
2

我正在編寫一個Java RPG遊戲的過程中,並且遇到了一個障礙。我的代碼目前有精靈動畫,隨機地圖生成perlin噪聲和碰撞檢測。該地圖是平鋪的基地,所以我目前正試圖將perlin噪音轉換爲瓷磚。 perlin函數生成一個數組,並將該數組中的每個數字輸入到一個tile png中。這是問題出現的地方:RUNTIME ERROR:Java.Lang.NullPointerException。 問題是我的編譯器(netbeans)不會告訴我發生錯誤的地方,而是隻給我這個錯誤代碼。通過排除過程,我設法找到錯誤,該錯誤發生在第364行。如果此網站不支持行,則位於loadTile()方法的「if(perlinIsland [x] [y] < = 0.05)blockImg [x] [y] = TILE [0];「。我相信所有變量都被正確初始化,但我無法找到解決方案。請原諒長碼,但爲了提供信息,我包含了所有內容。預先感謝您的幫助!java.lang.NullPointerException找不到源

package java4k; 

import java.awt.*; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D; 
import java.awt.image.*; 
import java.io.File; 
import java.io.IOException; 
import java.net.URL; 
import java.util.Random; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import java.math.*; 
import java.util.*; 

/** 
* 
* @author Christophe 
*/ 
public class Main extends JFrame implements Runnable{ 

    public Image dbImage; 
    public Graphics dbGraphics; 

    //Image + Array size 
    final static int listWidth = 500, listHeight = 500; 


    //Move Variables 
    int playerX = 320, playerY = 240, xDirection, yDirection; 

    //Sprites 
    BufferedImage spriteSheet; 

    //Lists for sprite sheet: 1 = STILL; 2 = MOVING_1; 3 = MOVING_2 
    BufferedImage[] ARCHER_NORTH = new BufferedImage[4]; 
    BufferedImage[] ARCHER_SOUTH = new BufferedImage[4]; 
    BufferedImage[] ARCHER_EAST = new BufferedImage[4]; 
    BufferedImage[] ARCHER_WEST = new BufferedImage[4]; 

    Image[] TILE = new Image[8]; 

    //Animation Variables 
    int currentFrame = 0, framePeriod = 150; 
    long frameTicker = 0l; 
    Boolean still = true; 
    Boolean MOVING_NORTH = false, MOVING_SOUTH = false, MOVING_EAST = false, MOVING_WEST = false; 

    BufferedImage player = ARCHER_SOUTH[0]; 

    //World Tile Variables 
    //20 X 15 = 300 tiles 
    Rectangle[][] blocks = new Rectangle[listWidth][listHeight]; 
    Image[][] blockImg = new Image[listWidth][listHeight]; 
    Image[][] blockImgTrans = new Image[listWidth][listHeight]; 
    Boolean[][] isSolid = new Boolean[listWidth][listHeight]; 
    int tileX = 0, tileY = 0; 
    Random r = new Random(); 

    Rectangle playerRect = new Rectangle(playerX + 4,playerY+20,32,20); 
    //Map Navigation 
    static final byte PAN_UP = 0, PAN_DOWN = 1, PAN_LEFT = 2, PAN_RIGHT = 3; 

    //Perlin noise variables: 
    Color test = new Color(0, 0, 0); 
    static float[][] perlinNoise = new float[listWidth][listHeight]; 
    static float[][] gradiantNoise = new float[listWidth][listHeight]; 
    static float[][] perlinIsland = new float[listWidth][listHeight]; 
    static float[][] biome = new float[listWidth][listHeight]; 
    //Saved as png 
    static BufferedImage perlinImage; 



    public Main(){ 

     this.setTitle("JAVA4K"); 
     this.setSize(640,505); 
     this.setResizable(false); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 

     addKeyListener(new AL()); 

     TILE[0] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_1.png").getImage(); 
     TILE[1] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_2.png").getImage(); 
     TILE[2] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_3.png").getImage(); 
     TILE[3] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_WATER_1.png").getImage(); 
     TILE[4] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_1_BOT.png").getImage(); 
     TILE[5] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_1_TOP.png").getImage(); 
     TILE[6] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_2_BOT.png").getImage(); 
     TILE[7] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_2_TOP.png").getImage(); 

     loadTiles(); 

     init(); 
    } 


    //Step 1: Generates array of random number 0 < n < 1 
    public static float[][] GenerateWhiteNoise(int width, int height){ 

     Random r = new Random(); 
     Random random = new Random(r.nextInt(1000000000)); //Seed to 0 for testing 
     float[][] noise = new float[width][height]; 

     for (int i = 0; i < width; i++) 
     { 
      for (int j = 0; j < height; j++) 
      { 
       noise[i][j] = (float)random.nextDouble() % 1; 
      } 
     } 

     return noise; 

    } 

    //Step 2: Smooths out random numbers 
    public static float[][] GenerateSmoothNoise(float[][] baseNoise, int octave){ 

     int width = baseNoise.length; 
     int height = baseNoise.length; 

     float[][] smoothNoise = new float[width][height]; 

     int samplePeriod = 1 << octave; // calculates 2^k 
     float sampleFrequency = 1.0f/samplePeriod; 

     for (int i = 0; i < width; i++) 
     { 
      //calculate the horizontal sampling indices 
      int sample_i0 = (i/samplePeriod) * samplePeriod; 
      int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around 
      float horizontal_blend = (i - sample_i0) * sampleFrequency; 

      for (int j = 0; j < height; j++) 
      { 
       //calculate the vertical sampling indices 
       int sample_j0 = (j/samplePeriod) * samplePeriod; 
       int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around 
       float vertical_blend = (j - sample_j0) * sampleFrequency; 

       //blend the top two corners 
       float top = Interpolate(baseNoise[sample_i0][sample_j0], 
        baseNoise[sample_i1][sample_j0], horizontal_blend); 

       //blend the bottom two corners 
       float bottom = Interpolate(baseNoise[sample_i0][sample_j1], 
        baseNoise[sample_i1][sample_j1], horizontal_blend); 

       //final blend 
       smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend); 
      } 
     } 

     return smoothNoise; 
    } 

    //Used in GeneratePerlinNoise() to derivate functions 
    public static float Interpolate(float x0, float x1, float alpha) 
    { 
     float ft = alpha * 3.1415927f; 
     float f = (float) (1 - Math.cos(ft)) * .5f; 
     return x0*(1-f) + x1*f; 
    } 

    //Step 3: Combines arrays together to generate final perlin noise 
    public static float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount) 
    { 
    int width = baseNoise.length; 
    int height = baseNoise[0].length; 

    float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing 

    float persistance = 0.5f; 

    //generate smooth noise 
    for (int i = 0; i < octaveCount; i++) 
    { 
     smoothNoise[i] = GenerateSmoothNoise(baseNoise, i); 
    } 

     float[][] perlinNoise = new float[width][height]; 
     float amplitude = 1.0f; 
     float totalAmplitude = 0.0f; 

     //blend noise together 
     for (int octave = octaveCount - 1; octave >= 0; octave--) 
     { 
     amplitude *= persistance; 
     totalAmplitude += amplitude; 

     for (int i = 0; i < width; i++) 
     { 
      for (int j = 0; j < height; j++) 
      { 
       perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude; 
      } 
     } 
     } 

    //normalisation 
    for (int i = 0; i < width; i++) 
    { 
     for (int j = 0; j < height; j++) 
     { 
      perlinNoise[i][j] /= totalAmplitude; 
     } 
    } 

    return perlinNoise; 
    } 

    //Step 4: Generate circular gradiant: center = 0, outside = 1 
    public static float[][] GenerateCircularGradiant(float[][] base, int size, int centerX, int centerY){ 

     base = new float[size][size]; 

     for (int x = 0; x < base.length; x++) { 
      for (int y = 0; y < base.length; y++) { 

       //Simple squaring, you can use whatever math libraries are available to you to make this more readable 
       //The cool thing about squaring is that it will always give you a positive distance! (-10 * -10 = 100) 
       float distanceX = (centerX - x) * (centerX - x); 
       float distanceY = (centerY - y) * (centerY - y); 

       float distanceToCenter = (float) Math.sqrt(distanceX + distanceY); 

       //Make sure this value ends up as a float and not an integer 
       //If you're not outputting this to an image, get the correct 1.0 white on the furthest edges by dividing by half the map size, in this case 64. You will get higher than 1.0 values, so clamp them! 
       float mapSize = base.length/2; 
       //mapSize = 500; 
       distanceToCenter = distanceToCenter/mapSize; 

       base[x][y] = distanceToCenter - 0.2f; 

      } 
     } 

     return base; 
    } 

    //step 5: Combine perlin noise with circular gradiant to create island 
    public static float[][] GenerateIsland(float[][] baseCircle, float[][] baseNoise){ 

     float[][] baseIsland = new float[baseNoise.length][baseNoise.length]; 

     for(int x = 0; x < baseNoise.length; x++){ 
      for(int y = 0; y < baseNoise.length; y++){ 
       baseIsland[x][y] = baseNoise[x][y] - baseCircle[x][y]; 
      } 
     } 

     return baseIsland; 
    } 

    //Method for optional paramater = float[][] biome 
    public static void GreyWriteImage(float[][] data, String filename){ 

     float[][] temp = null; 
     GreyWriteImage(data, temp, filename); 
    } 

    //Converts array data to png image 
    public static void GreyWriteImage(float[][] data, float[][] biome, String fileName){ 
     //this takes and array of doubles between 0 and 1 and generates a grey scale image from them 

     BufferedImage image = new BufferedImage(data.length,data[0].length, BufferedImage.TYPE_INT_RGB); 

     for (int y = 0; y < data[0].length; y++) 
     { 
      for (int x = 0; x < data.length; x++) 
      { 


       if (data[x][y]>1){ 
       data[x][y]=1; 
      } 
      if (data[x][y]<0){ 
       data[x][y]=0; 
      } 


      Color col; 

      //Deep Water 0 - 0.05 
      if(data[x][y] <= 0.05) col = new Color(0, 0, 255); 
      //Shallow Water 0.05 - 0.08 
      else if(data[x][y] <= 0.08) col = new Color(100, 100, 255); 
      //Beach 0.08 - 0.2 
      else if(data[x][y]<=0.15) col = new Color(255, 255, 0); 
      //Forest 0.2 - 0.6 + 0 0 0.7 
      else if(data[x][y]<=0.6 && biome != null && (biome[x][y] < 0.6 || biome[x][y] > 0.9)){ 
       //Forest 
       if(biome[x][y] < 0.6) col = new Color(0, 150, 0); 
       //Desert 
       else col = new Color(200, 200, 0); 
      } 
      //Plains 0.2 - 0.6 
      else if(data[x][y] <= 0.6) col = new Color(0, 255, 0); 
      //Rocky Mountains 0.6 - 0.8 
      else if(data[x][y] <= 0.65) col = new Color(100, 100, 100);    
      //Snowy Mountains 0.6 - 1 
      else col = new Color(255, 255, 255); 

      image.setRGB(x, y, col.getRGB()); 
      } 
     } 

     try { 
      // retrieve image 
      File outputfile = new File(fileName); 
      outputfile.createNewFile(); 

      ImageIO.write(image, "png", outputfile); 
     } catch (IOException e) { 
      System.out.println("GREY WRITE IMAGE ERROR 303: " + e); 
     } 
    } 



    //First called to store image tiles in blockImg[][] and tile rectangles in blocks[][] 
    private void loadTiles(){ 

     //Primary Perlin Noise Generation 
     perlinNoise = GenerateWhiteNoise(listWidth, listHeight); 
     GreyWriteImage(perlinNoise, "perlinNoise.png"); 
     perlinNoise = GenerateSmoothNoise(perlinNoise, 7); 
     GreyWriteImage(perlinNoise, "smoothNoise.png"); 
     perlinNoise = GeneratePerlinNoise(perlinNoise, 5); 
     GreyWriteImage(perlinNoise, "finalPerlin.png"); 
     gradiantNoise = GenerateCircularGradiant(gradiantNoise, listWidth, listWidth/2 - 1, listHeight/2 - 1); 
     GreyWriteImage(gradiantNoise, "gradiantNoise.png"); 
     perlinIsland = GenerateIsland(gradiantNoise, perlinNoise); 
     GreyWriteImage(perlinIsland, "perlinIsland.png"); 


     //Biome Perlin Noise Generation 
     biome = GenerateWhiteNoise(listWidth, listHeight); 
     biome = GenerateSmoothNoise(biome, 6); 
     biome = GeneratePerlinNoise(biome, 5); 
     GreyWriteImage(perlinIsland, biome, "biome.png"); 






     for(int y = 0; y < listHeight; y++){ 
      for(int x = 0; x < listWidth; x++){ 

       //Sets boundaries: 0 < perlinIsland[x][y] < 1 
       if (perlinIsland[x][y]>1) perlinIsland[x][y]=1; 
       if (perlinIsland[x][y]<0) perlinIsland[x][y]=0; 

       //Deep Water 0 - 0.05 
       if(perlinIsland[x][y] <= 0.05)blockImg[x][y] = TILE[0]; 
       //Shallow Water 0.05 - 0.08 
       else if(perlinIsland[x][y] <= 0.08) blockImg[x][y] = TILE[3]; 
       //Beach 0.08 - 0.2 
       else if(perlinIsland[x][y]<=0.15) blockImg[x][y] = TILE[4]; 
       //Forest 0.2 - 0.6 + 0 0 0.7 
       else if(perlinIsland[x][y]<=0.6 && biome != null && (biome[x][y] < 0.6 || biome[x][y] > 0.9)){ 
        //Forest 
        if(biome[x][y] < 0.6) blockImg[x][y] = TILE[5]; 
        //Desert 
        else blockImg[x][y] = TILE[3]; 
       } 
       //Plains 0.2 - 0.6 
       else if(perlinIsland[x][y] <= 0.6) blockImg[x][y] = TILE[2]; 
       //Rocky Mountains 0.6 - 0.8 
       else if(perlinIsland[x][y] <= 0.65) blockImg[x][y] = TILE[3];    
       //Snowy Mountains 0.6 - 1 
       else blockImg[x][y] = TILE[1]; 

       blocks[x][y] = new Rectangle(x*32, y*32, 32, 32); 

      } 
     } 

    } 


    //collision detection 
    public boolean collide(Rectangle in) 
    { 
     if(blocks[0][0] != null){ 
      for (int y = (int)((playerRect.y - blocks[0][0].y)/32)-1; y <= (int)((playerRect.y+playerRect.height - blocks[0][0].y)/32)+1; y++){ 
       for (int x = (int)((playerRect.x - blocks[0][0].x)/32)-1; x <= (int)((playerRect.x+playerRect.width - blocks[0][0].x)/32) + 1; x++){ 
        if (x >= 0 && y >= 0 && x < 32 && y < 32){ 
         if (blockImg[x][y] != null) 
         { 
           if (in.intersects(blocks[x][y]) && isSolid[x][y] == true){ 
           { 
            return true; 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
     return false; 
    } 


    //Key Listener 
    public class AL extends KeyAdapter{ 
     public void keyPressed(KeyEvent e){ 

      int keyInput = e.getKeyCode(); 
      still = false; 
      if(keyInput == e.VK_LEFT){ 

       navigateMap(PAN_RIGHT); 
       MOVING_WEST = true; 

      }if(keyInput == e.VK_RIGHT){ 

       navigateMap(PAN_LEFT); 
       MOVING_EAST = true; 

      }if(keyInput == e.VK_UP){ 

       navigateMap(PAN_DOWN); 
       MOVING_NORTH = true; 

      }if(keyInput == e.VK_DOWN){ 

       navigateMap(PAN_UP); 
       MOVING_SOUTH = true; 
      } 
     } 
     public void keyReleased(KeyEvent e){ 

      int keyInput = e.getKeyCode(); 
      setYDirection(0); 
      setXDirection(0); 

      if(keyInput == e.VK_LEFT){ 

       MOVING_WEST = false; 
       player = ARCHER_WEST[0]; 

      }if(keyInput == e.VK_RIGHT){ 

       MOVING_EAST = false; 
       player = ARCHER_EAST[0]; 

      }if(keyInput == e.VK_UP){ 

       MOVING_NORTH = false; 
       player = ARCHER_NORTH[0]; 

      }if(keyInput == e.VK_DOWN){ 

       MOVING_SOUTH = false; 
       player = ARCHER_SOUTH[0]; 
      } 
      if(MOVING_SOUTH == MOVING_NORTH == MOVING_EAST == MOVING_WEST == false){ 
       still = true; 
      } 
     } 
    } 


    public void moveMap(){ 


     for(int a = 0; a < 30; a++){ 
       for(int b = 0; b < 30; b++){ 
        if(blocks[a][b] != null){ 
         blocks[a][b].x += xDirection; 
         blocks[a][b].y += yDirection; 
        } 
       } 
      } 

     if(collide(playerRect) && blocks[0][0]!= null){ 
      for(int a = 0; a < 30; a++){ 
       for(int b = 0; b < 30; b++){ 
        blocks[a][b].x -= xDirection; 
        blocks[a][b].y -= yDirection; 
       } 
      } 
     } 
    } 


    public void navigateMap(byte pan){ 
     switch(pan){ 
      default: 
       System.out.println("Unrecognized pan!"); 
       break; 
      case PAN_UP: 
       setYDirection(-1); 
       break; 
      case PAN_DOWN: 
       setYDirection(+1); 
       break; 
      case PAN_LEFT: 
       setXDirection(-1); 
       break; 
      case PAN_RIGHT: 
       setXDirection(+1); 
       break; 
     } 
    } 


    //Animation Update 
    public void update(long gameTime) { 

     if (gameTime > frameTicker + framePeriod) { 
      frameTicker = gameTime; 
      currentFrame++; 
      if (currentFrame >= 4) { 
       currentFrame = 0; 
      } 
     } 
     if(MOVING_NORTH) player = ARCHER_NORTH[currentFrame]; 
     if(MOVING_SOUTH) player = ARCHER_SOUTH[currentFrame]; 
     if(MOVING_EAST) player = ARCHER_EAST[currentFrame]; 
     if(MOVING_WEST) player = ARCHER_WEST[currentFrame]; 
    } 


    public void setXDirection(int xdir){ 

     xDirection = xdir; 
    } 


    public void setYDirection(int ydir){ 

     yDirection = ydir; 
    } 


    //Method to get sprites 
    public BufferedImage grabSprite(int x, int y, int width, int height){ 
     BufferedImage sprite = spriteSheet.getSubimage(x, y, width, height); 
     return sprite; 
    } 


    private void init(){  
     spriteSheet = null; 
     try { 
      spriteSheet = loadImage("ARCHER_SPRITESHEET.png"); 
     } catch (IOException ex) { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     for(int i = 0; i <= 3; i++){ 
      ARCHER_NORTH[i] = grabSprite(i*16, 16, 16,16); 
      ARCHER_SOUTH[i] = grabSprite(i*16, 0, 16, 16); 
      ARCHER_EAST[i] = grabSprite(i*16, 32, 16, 16); 
      ARCHER_WEST[i] = grabSprite(i*16, 48, 16, 16); 
     } 
    } 


    public BufferedImage loadImage(String pathRelativeToThis) throws IOException{ 

     URL url = this.getClass().getResource(pathRelativeToThis); 
     BufferedImage img = ImageIO.read(url); 
     return img; 
    } 


    public void paint(Graphics g){ 

     dbImage = createImage(getWidth(), getHeight()); 
     dbGraphics = dbImage.getGraphics(); 
     paintComponent(dbGraphics); 
     g.drawImage(dbImage, 0, 25, this); 

    } 

    public void paintComponent(Graphics g){ 
     requestFocus(); 

     /** 

     //Draws tiles and rectangular boundaries for debugging 
     for(int a = 200; a < 230; a++){ 
      for(int b = 200; b < 230; b++){ 
       if(blockImg[a][b] != null && blocks[a][b] != null){ 
        g.drawImage(blockImg[a][b], Math.round(blocks[a][b].x), Math.round(blocks[a][b].y), 32, 32, null); 
       } 
      } 
     } 

     //Draw player and rectangular boundary for collision detection 
     g.drawImage(player, playerX, playerY, 40, 40, null); 
     repaint(); 

     //Draws transparent tiles 
     for(int a = 0; a < 20; a++){ 
      for(int b = 0; b < 15; b++){ 
       if(blockImgTrans[a][b] != null && blocks[a][b] != null){ 
        g.drawImage(blockImgTrans[a][b], blocks[a][b].x, blocks[a][b].y, 32, 32, null); 
       } 
      } 
     } 


     **/ 
    } 

    public void run(){ 
     try{ 
      while(true){ 
       moveMap(); 
       if(!still) update(System.currentTimeMillis()); 
       Thread.sleep(13); 
      } 
     }catch(Exception e){ 
      System.out.println("RUNTIME ERROR: " + e); 
     }  
    } 


    public static void main(String[] args) { 
     Main main = new Main(); 

     //Threads 
     Thread thread1 = new Thread(main); 
     thread1.start(); 
    } 
} 
+1

stacktrace應該是不錯的開始:) – rocketboy

+0

方式太多的代碼,包括註釋掉的代碼。你應該逐步診斷,減少代碼的數量,直到它是可管理的。那時你可能已經自己發現了這個問題。 –

+1

你無法找到有限的catch代碼異常:catch(Exception e){System.out.println(「RUNTIME ERROR:」+ e);}'。至少打印堆棧跟蹤。至少在你的catch塊中有'e.printStackTrace()'。 –

回答

2

您有限的catch塊代碼阻礙了您找到您的空值的能力。

例如,這行代碼:

try { 
    while (true) { 
     moveMap(); 
     if (!still) 
      update(System.currentTimeMillis()); 
     Thread.sleep(13); 
    } 
    } catch (Exception e) { 
    System.out.println("RUNTIME ERROR: " + e); 
    } 

將只打印

RUNTIME ERROR: java.lang.NullPointerException 

不帶行號或堆棧跟蹤,當該代碼運行到NPE。

首先,你不應該陷入簡單的異常,而是爲了明確的例外。接下來,您應該使用更多信息的catch塊,例如至少通過e.printStackTrace()打印堆棧跟蹤的塊。

塊上面確實應該寫成:

public void run() { 
    while (true) { 
    moveMap(); 
    if (!still) 
     update(System.currentTimeMillis()); 
    try { 
     Thread.sleep(13); 
     // only catch the explicit exception and in localized code if possible. 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    } 
} 

做到這一點,你會看到NPE發生在這裏:

if (in.intersects(blocks[x][y]) && isSolid[x][y] == true) { 

然後你就可以在該行的前面填充碼查看哪個變量導致問題:

例如,

   if (blockImg[x][y] != null) { 
       System.out.println("in is null: " + (in == null)); 
       System.out.println("blocks[x][y] is null: " 
         + (blocks[x][y] == null)); 
       System.out.println("isSolid is null: " 
         + (isSolid == null)); 
       System.out.println("isSolid[x][y] is null: " 
         + (isSolid[x][y] == null)); 

       if (in.intersects(blocks[x][y]) && isSolid[x][y] == true) { 
        { 
         return true; 
        } 
       } 
       } 

,你會看到的問題是,isSolid[x][y]爲空:

in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 
in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 
in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 
Exception in thread "Thread-3" java.lang.NullPointerException 
    at pkg.Main.collide(Main.java:465) 
    at pkg.Main.moveMap(Main.java:557) 
    at pkg.Main.run(Main.java:693) 
    at java.lang.Thread.run(Unknown Source) 
in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 
in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 
in is null: false 
blocks[x][y] is null: false 
isSolid is null: false 
isSolid[x][y] is null: true 

爲什麼呢?它是一組布爾數組,不是布爾值,所以它不會初始化爲Boolean.FALSE,而是默認爲null。解決方案:使用布爾型[] []數組或顯式初始化您的數組。

最重要的是:使用信息豐富的catch塊,不捕獲一般異常。


編輯注意,順便說一句,爲了讓我得到你的代碼運行,我不得不取消您的圖像和精靈表的使用,因爲這些都是不可用的我的資源。這項工作應該是你的,因爲你是未來的追求者。我會問,將來您會將代碼限制爲可以測試和運行的最小代碼,這些代碼可以證明您的問題,但代碼不會與您的問題無關,並且不依賴於外部資源,例如圖像,數據庫,等等,一個sscce

+0

非常感謝你這個了不起的答案!正如你可能知道的那樣,我對編程相當陌生,這些提示一定會在未來幫助我!再次感謝 ! :) – user2614974

+0

@ user2614974:不客氣。請參閱編輯以回答您在本網站上的下一個問題。我們感謝您付出的努力,以便我們能夠運行您的代碼並幫助您更好地完成任務。 –

+0

好吧,我一定會正確格式化我的代碼,並再次感謝:) – user2614974