Tilemap not drawing after implementing LoadFromFile [SOLVED]

Hey everyone this is my first post and I must say that I like the community that I have seen here and look forward to contributing to other people’s success.

I’m making a 2D tile-based (small scale) rpg and cannot for the life of me figure out why my tilemap is not displaying. I just implemented loading maps from files and I know that before this the map was loading and displaying just fine I believe I have narrowed the possibilities down to my images being null when I go to draw them but I cannot seem to figure out why that is. Here is the code for my entire tilemap class with the null image

import java.util.*;
import java.awt.*;

import java.io.File;

import javax.swing.*;

public class TileMap{

  ArrayList<Image> textures = new ArrayList<Image>();
  
  int[][] map;
  
  static int tileWidth = 32;
  static int tileHeight = 32;
  
  static int tileMapWidth;
  static int tileMapHeight;
  
  public TileMap(){}    
	public TileMap(int width, int height){
      map = new int[height][width];
      for (int x = 0; x < width; x++)
          for (int y = 0; y < height; y++)
              map[y][x] = -1;

      tileMapWidth = map[0].length;
      tileMapHeight = map.length;
	}  
  public TileMap(int[][] newMap){
      this.map = newMap.clone();
  
      tileMapWidth = map[0].length;
      tileMapHeight = map.length;
  }  
  
  public static TileMap LoadFromFile(String fileName){

    TileMap tileMap;
    ArrayList<ArrayList<Integer>> tempLayout = new ArrayList<ArrayList<Integer>>();
    ArrayList<String> textureList = new ArrayList<String>();
    Scanner input;
    File file;
   
    try{
        file = new File(fileName);
        input = new Scanner(file);
    }catch(Exception e){
        file = null;
        System.out.println("File is null");
        input = null;
        System.out.println("Input is null");
    }
  
    boolean readingTextures = false;
    boolean readingLayout = false;
            
    while(input.hasNext()){
        String line = input.nextLine().trim();
        
        if (line.isEmpty())
            continue;
        
        if (line.contains("[Textures]")){
          readingTextures = true;
          readingLayout = false;
        }
        else if (line.contains("[Layout]")){
          readingLayout = true;
          readingTextures = false;
        }
        else if (readingTextures){
          textureList.add(line);
        }
        else if (readingLayout){
          ArrayList row = new ArrayList();
          
          String[] cells = line.split(" ");
          
          for (String c : cells){
            if (!c.isEmpty())
                row.add(Integer.parseInt(c));
          }
          tempLayout.add(row);
        }          
    }
    
    int width = tempLayout.get(1).size();
    int height = tempLayout.size();
    
    System.out.println(width);
    System.out.println(height);
    
    tileMap = new TileMap(width, height);
    
    for (int y = 0; y < height; y++){
        for (int x = 0; x < width; x++){
            try{
                tileMap.setCellIndex(x, y, tempLayout.get(y).get(x));
            }catch(NullPointerException e){
                System.out.println("SetCellIndex() has returned a NullPointerException");
            }
        }
    }
    
    String[] textureArray = new String[textureList.size()];
    for (int i = 0; i < textureList.size(); i++){
        textureArray[i] = textureList.get(i);
    }
    
    tileMap.LoadTextures(textureArray);

    return tileMap;    
  }  
  public void LoadTextures(String ... fileNames){
      for (int i = 0; i < fileNames.length; i++){
          try{
            textures.add(new ImageIcon(Game.SRC_PATH + fileNames[i]).getImage());
          }catch(Exception e){
            System.out.println("File not added.");
          }
      }
      
  }
  
  public int getCellIndex(int x, int y){
    return map[y][x];
  }  
  public void setCellIndex(int x, int y, int cellIndex){
    map[y][x] = cellIndex;
  }
  
  public static int getWidthInPixels(){
    return tileMapWidth * tileWidth;
  }  
  public static int getHeightInPixels(){
    return tileMapHeight * tileHeight;
  }
  
  public void Draw(Graphics2D g, Camera camera){
                 
      int tileMapWidth = map[0].length;
      int tileMapHeight = map.length;
    
      for (int x = 0; x < tileMapWidth; x++){
          for (int y = 0; y < tileMapHeight; y++){
              int index = map[y][x];
              
              if (index == -1)
                  continue;
              
/////////////////////// NULL IMAGE RIGHT HERE \\\\\\\\\\\\\\\\\\\\\\\\\
              Image image = textures.get(index);
                                          
              try{
                g.drawImage(image, 
                            x * tileWidth - (int)camera.Position.X, 
                            y * tileHeight - (int)camera.Position.Y,
                            Color.WHITE,
                            null);
              }catch(NullPointerException n){
                System.out.println("Draw Image threw a NullPointerException");
              }
          }
      }
  }
}

If anyone can help me spot the problem I would be very greatful. I thank you for taking the time to read over my code and here is a link to my entire project (zip file) with images and the tilemap text file.
https://docs.google.com/leaf?id=0B-7lPg3Z0pepZTU5NDNlNTAtOGNiMS00ZGExLWIxZjAtNWYxZGJlMjQyYTRj&hl=en&authkey=CIW-nLMK

Thanks everyone!

Do you get any output on system out while you’re running the program?

Kev

It might be to do with:


{
            textures.add(new ImageIcon(Game.SRC_PATH + fileNames[i]).getImage());
}

You’d be best to add some debug telling you what that string resolves to, and whether it’s actually accessible. Also you might consider using ImageIO.read() instead of the ImageIcon().getImage();

Kev

The only output that I’m getting is a window with the black background that set in my main java class constructor. If I remove that line of code, all I get is a window with the generic grey canvas that java makes

Man, I’ve added and removed so many debug lines it’s disgusting. Let me tell you a few things that I know based on a bunch of System.out.println() - type debugging:
The textureArray that is passed to LoadTextures() contains all six of the textures filenames.
The tilemap layout matches the layout from the text file.
The image is null when the g.DrawImage() is called.

What’s the advantage of using ImageIO.read() instead of ImageIcon().getImage()?

ImageIO is immediate loading, not sure ImageIcon works that way, might be asynchronous.

What console output do you get when you run the program I meant, i.e. what are the System.out saying?

Try changing this:


public void LoadTextures(String ... fileNames){
      for (int i = 0; i < fileNames.length; i++){
          try{
            textures.add(new ImageIcon(Game.SRC_PATH + fileNames[i]).getImage());
          }catch(Exception e){
            System.out.println("File not added.");
          }
      }
       
  }

to this:


public void LoadTextures(String ... fileNames){
      for (int i = 0; i < fileNames.length; i++){
          try{
              String location = Game.SRC_PATH + fileNames[i];
              System.out.println("Loading: "+location);     
              Image image = new ImageIcon(location).getImage();
              System.out.println("Loaded image: "+image);
            textures.add(image);
          }catch(Exception e){
            System.out.println("File not added.");
          }
      }
       
  }

And let us know what the console output is - might help diagnose whats going on there?

Kev

Ok I changed the LoadTextures() to what you suggested and I’m still getting the black screen in a window and the console output is:
Loading: “images/grass0.png”
Loaded image: sun.awt.image.ToolkitImage@bbe0f0a
Loading: “images/grass1.png”
Loaded image: sun.awt.image.ToolkitImage@6acd5f8b
Loading: “images/grass2.png”
Loaded image: sun.awt.image.ToolkitImage@513bd574
Loading: “images/dirt0.png”
Loaded image: sun.awt.image.ToolkitImage@2f3adc56
Loading: “images/dirt1.png”
Loaded image: sun.awt.image.ToolkitImage@4157aa53
Loading: “images/dirt2.png”
Loaded image: sun.awt.image.ToolkitImage@626f50a8
Loading: “images/dirt3.png”
Loaded image: sun.awt.image.ToolkitImage@7a187814

which makes me think that the images loaded fine.
I even added block in my Draw() that says


if (image == null){
   System.out.println("Image is null");
}

Which did not show up in the output.

And I even removed the call to set the background to black (in my main class) which did make the window go back to that greyish color.

I am very confused by this bug

I’m confused too, you’re not alone! :slight_smile:

Can you update this:


/////////////////////// NULL IMAGE RIGHT HERE \\\\\\\\\\\\\\\\\\\\\\\\\
              Image image = textures.get(index);

to


              Image image = textures.get(index);
              System.out.println("Image for index: "+index+" is "+image);

And post the output, thinking theres got to be something else going on but just to confirm.

Kev

Oh, I guess it’d be good to know what position your camera has also.

Kev

Sure, well it prints out that line for every cell in the map (which it should) and here is some of the output:

Image for index: 0 is sun.awt.image.ToolkitImage@bbe0f0a
Image for index: 0 is sun.awt.image.ToolkitImage@bbe0f0a
Image for index: 0 is sun.awt.image.ToolkitImage@bbe0f0a
Image for index: 2 is sun.awt.image.ToolkitImage@513bd574
Image for index: 1 is sun.awt.image.ToolkitImage@6acd5f8b
Image for index: 1 is sun.awt.image.ToolkitImage@6acd5f8b
Image for index: 1 is sun.awt.image.ToolkitImage@6acd5f8b
Image for index: 1 is sun.awt.image.ToolkitImage@6acd5f8b
Image for index: 0 is sun.awt.image.ToolkitImage@bbe0f0a
Image for index: 0 is sun.awt.image.ToolkitImage@bbe0f0a

I also put a System.out.println(“Got here”); after my call to g.DrawImage(); in the try{} block and it was outputting infinitely (which it should because I’m always calling the draw method from main).

I also added in a System.out for the x and y of camera and it is x = 0 and y = 0 at the beginning and is updating when I press my arrow keys (like it should be)

I guess you looked at the NullpointerException itself, to rule out that it’s your Graphics or Camera objects that are null? :slight_smile:

Yes, well, it’s not throwing the exception so I’m assuming that they aren’t null. I tried moving the drawImage() call outside of the try{} block and it still didn’t work

Hi.

I got it working :slight_smile:

In your layers.txt file, replace “images/grass0.png” with just images/grass0.png

I also changed image loading to use ImageIO, but I’m not sure if that part mattered at all. The good thing about ImageIO though is that it threw an exception which made me look into the layers.txt.

So now I got mountains’n grass!

Oh my gosh! Thank you so much! I can’t believe it was something that simple. :-X
I guess I should have thought to look there as well as in my code. Thanks very much for your help, now I can move on to bigger and better things!

Were you able to move around Addictman?

Now whenever I System.out the camera x and y it still updates those when I use the arrow keys but it does not redraw the map. Very perplexing to me.