Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (517)
Games in Android Showcase (123)
games submitted by our members
Games in WIP (578)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Loading A 2D Array Into A Image. Drawing Not Working!  (Read 4042 times)
0 Members and 1 Guest are viewing this topic.
Offline v0rtex

Senior Newbie





« Posted 2012-02-19 12:47:14 »

Okay so I am trying to draw a tiled map in Java. I am currently doing the following:

  • Loading mapData from a text file (level1.dat) which is then stored into a 2D Integer Array
  • Draw a BufferedImage dependant on the map data
  • Draw the BufferedImage to my JFrame.

I have four classes:

  • ArrayToImage - Class whereby I convert the Array to the Image
  • MapToArray - Class whereby I convert the level1.dat into the 2D Array
  • Main - Class that instantiates the MainFrame
  • MainFrame - JFrame to display the Image

I think the problem is in MainFrame (Perhaps I am drawing the Image wrong?) or in ArrayToImage as the double for loop might not be working properly?

Here is the code I have worked on so far:

ArrayToImage
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;


public class ArrayToImage {
   Image image;
      //ignore this part
   private Image wall = null;
    private Image table = null;
    private Image floor = null;
      int x,y,temp=0;
      //nothing here yet
     
      public void loadImages() {
       
       wall = Toolkit.getDefaultToolkit().getImage("Tree.bmp");
          table = Toolkit.getDefaultToolkit().getImage("Icicle.bmp");
         floor = Toolkit.getDefaultToolkit().getImage("floor.bmp");
         
      }
      public ArrayToImage(){
         loadImages();
      }
      //This function will return an BufferedImage with all the tiles drawn on it
      public BufferedImage getMap(int[][] map){
         loadImages();
         BufferedImage bufferedImage = new BufferedImage(map.length*4, (map[0].length)*15, BufferedImage.TYPE_INT_BGR);
         Graphics2D g2d = bufferedImage.createGraphics();
         g2d.setColor(Color.green);
         g2d.fillRect(0, 0, map.length*4, (map[0].length)*15);
         for(int height= 0; height<map[0].length; height++){
         for(int length = 0; length<map.length; length++) {
              switch(map[length][height]){
case 0:
g2d.drawImage(floor, length*15, height*15, null);
                                break;
case 1:
g2d.drawImage(wall, length*15, height*15, null);
break;
case 2:
g2d.drawImage(table, length*15, height*15, null);
break;
}
           }
         }

         g2d.finalize();
         g2d.dispose();
         return bufferedImage;
      }
   }


MapToArray


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
public class MapToArray {

   private final String fileName;
   public int length;
   public int height;
   //simple constructor, Sets the map
   MapToArray(String fileName) {
      this.fileName = fileName;
   }
   
   //returns the 2D array of the map in INT[] []
   public int[] [] getArray() throws IOException {
      ArrayList<String> array = new ArrayList<String>();
       length = getLength();
       height = getHeight();
     
      LineNumberReader reader = new LineNumberReader (new FileReader(fileName));
      for (int i = 0; i < height; i++) {
      array.add(reader.readLine());
      }
     
      if (array.size() == 0) {
         System.out.println("Empty map");
   }
      int[][] numbers = new int [length][height]; //reserve space in memory
   int r= 0;
   //now that we have the size of our array and the data, we fill it in
   for (String s : array) {
      toArray(s, r, numbers);
      r++;
   }
   return numbers; //return map
   }
     
   //returns the map's Length
   private int getLength() throws IOException {
      int countChar = 0;
      try {
         LineNumberReader reader = new LineNumberReader (new FileReader(fileName));
      String lineRead = reader.readLine();
      int length = 0;
      while (countChar < lineRead.length()) {
         if (!(lineRead.charAt(countChar) == ',')) {
            length++;
         }
         countChar++;
      }
      reader.close();
      return length;
      } catch (IOException e) {
         throw e;
      }
   }
   
   //returns height of map (number of lines)
   public int getHeight() throws IOException {
      int height = 0;
      try {
         LineNumberReader reader = new LineNumberReader(new FileReader(fileName));
         String lineRead;
         while ((lineRead = reader.readLine()) != null) {
         }
         //loops to last line of file}
            height = reader.getLineNumber();
            reader.close();
            return height;
         
      } catch (IOException e) {
         throw e;
      }
   

   }
   
   //This function will fill an entire row with the numbers from String s.
    private void toArray(String s, int row, int[][] numbers) {
        String match = ",";
        String[] veld = s.split(match);
       
        for(int i = 0; i<veld.length;i++)
           veld[i] = veld[i].replaceAll(" ","");
       
        for (int i = 0; i < veld.length; i++) {
            try {
                numbers[i][row] = Integer.parseInt(veld[i]);
            } catch (NumberFormatException e) {
                System.out.println("Not a valid map!");
            }
        }
    }

}


MainFrame

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
import javax.swing.*;

import java.awt.*;
import java.io.IOException;
public class MainFrame extends JFrame{
   int[][] array_map1;
   MapToArray map1;
   Image bckground_1;
   ArrayToImage draw = new ArrayToImage();

public void init() throws IOException {
   map1 = new MapToArray("level1.dat"); //sets the current map
   array_map1 = map1.getArray(); // grabs the map data and stores it in a 2D integer Array.
   bckground_1 = draw.getMap(array_map1); //draws the "Map" by creating a BufferedImage dependant on the 2D Array.
   }

   MainFrame() throws IOException {
      setSize(640,480);
      setTitle("MapLoad Demo");
   init();
   setVisible(true);
   
   }
   public void paint (Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
   g2d.drawImage(bckground_1, 0, 0 ,null);
   }
   
   
   
}


Main

1  
2  
3  
4  
5  
public class Main {
   public static void main(String[] args) throws IOException {
      new MainFrame();
}
}


The problem is when I run main.java ; A 15 * 15 Image loads in the top right (only 1 tile?) so I think It might not be looping properly in ArrayToImage.java. The problem can be seen in the screenshot below:







I also think that all the Images are loading correctly as I painted one Image.
I am pretty sure that I am drawing the images incorrectly in MainFrame.java
Any help is appreciated, Thanks
v0rtex

P.S.: Here is the map Data for level1.dat

1,1,1,1,1,
1,0,0,0,1,
1,0,2,0,1,
1,0,0,0,1,
1,1,1,1,1,


Credit goes to elamre to whom provided most of the code through this tutorial.
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2012-02-19 15:28:24 »

Don't draw directly to a JFrame or some parts of all sides will be cut off due to window decorations, as shown by that cut off green rectangle. It is best to extend JComponent and draw in its paintComponent(Graphics g) method and add that JComponent to the JFrame.

Concerning your problem, it looks like it's more of a problem in your MapToArray class. You are opening 3 streams of the same file, two to get the width and height, and one to actually read it. This is very inefficient and error prone. It is best to just open 1 BufferedReader on your file and add all the lines to the ArrayList, only to split it up later on.

Did you try printing out what is in your map array before drawing its contents in ArrayToImage.getMap?

Offline elamre

JGO Coder


Medals: 17
Projects: 1


hitar!


« Reply #2 - Posted 2012-02-19 15:38:48 »

hmmyez, that seems to work ra4king.
I know this class might not be to your standards, but the mapToArray class works perfectly fine. And yeah its not efficient, but the efficiency isnt really important at this point Smiley.
Also i used to have it differently, untill somebody on this forum told me this way it was better. But ill have to do some research to it i guess.

And write a foolproof tutorial as well it seems.

My projects:
Tower Defence!]http://www.java-gaming.org/topics/iconified/25690/view.html]Tower Defence! [lll.......] 30%!
Lightsnakerider! [llllll....] 60%!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline v0rtex

Senior Newbie





« Reply #3 - Posted 2012-02-19 16:21:29 »

I am answering here from now on as it was the site that I got the original information from. I added a JComponent and am drawing the bufferedImage to the JComponent and then adding the JComponent to a JFrame like ra4king suggested and this makes the image display correctly but the Image is still not showing up, any help is appreciated. This is really getting rather annoying Sad

Also I have confirmed (thanks to the help of elamre) that the level1.dat is being read correctly but g2d.drawImage is not adding the Images to the bufferedImage as the returned Image is simply blank?
Offline v0rtex

Senior Newbie





« Reply #4 - Posted 2012-02-19 16:49:33 »

Got it working, for some reason returning an ImageIcon when loading the Image corrected the Image, I also added a boolean check on whether the Images were loaded correctly.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;

import javax.swing.ImageIcon;

public class ArrayToImage {
   Image image;

   private Image wall = null;
   private Image table = null;
   private Image floor = null;
   int x, y, temp = 0;
   private boolean imagesLoaded = false;

   public void loadImages() {
      wall = loadImage("wall.jpg");
      table = loadImage("Icicle.jpg");
      floor = loadImage("Floor.jpg");

      imagesLoaded = true;
   }

   private Image loadImage(String fileName) {
      return new ImageIcon(fileName).getImage();
   }

   public void drawImage(Graphics g, Image image, int x, int y) {
      g.drawImage(image, x, y, null);
   }

   public ArrayToImage() {
   }

   // This function will return an BufferedImage with all the tiles drawn on it
   public BufferedImage getMap(int[][] map) {
      loadImages();
      int largestRow = 0;
      for (int i = 0; i < map.length; i++) {
         if (map[i].length > largestRow)
            largestRow = map[i].length;
      }
      int tileSize = 32;

      BufferedImage bufferedImage = new BufferedImage(map.length * tileSize,
            largestRow * tileSize, BufferedImage.TYPE_INT_BGR);
      Graphics2D g2d = bufferedImage.createGraphics();
      g2d.setColor(Color.white);
      if (imagesLoaded) {
         for (int heigth = 0; heigth < map[0].length; heigth++) {
            for (int length = 0; length < map.length; length++) {
               switch (map[length][heigth]) {
               case 0: {
                  g2d.drawImage(floor, length * tileSize, heigth
                        * tileSize, null);
                  break;
               }
               case 1: {
                  g2d.drawImage(wall, length * tileSize, heigth
                        * tileSize, null);
                  // g2d.setColor(Color.red);
                  // g2d.fillRect(length*tileSize, heigth*tileSize, 32,
                  // 32);
                  break;
               }
               case 2: {
                  g2d.drawImage(table, length * tileSize, heigth
                        * tileSize, null);
                  break;
               }
               }
            }
         }
         if (imagesLoaded == false) {
            System.out.println("Error Loading Images!");
         }
      }
      g2d.finalize();
      g2d.dispose();
      return bufferedImage;
   }

}


Thanks again all!
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #5 - Posted 2012-02-19 17:34:18 »

Don't use ImageIcon, it is best to use javax.imageio.ImageIO:
1  
BufferedImage image = ImageIO.read(getClass().getClassLoader().getResource(path));

Where "path" is relative to the root of your project.

Offline v0rtex

Senior Newbie





« Reply #6 - Posted 2012-02-19 17:45:39 »

Any reason why in particular? Is it better resource or performance wise?
Just curious,
v0rtex
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #7 - Posted 2012-02-19 17:56:31 »

Both, first off you creating an ImageIcon instance, waste of resource and performance. Secondly, internally it just does Toolkit.getDefaultToolkit().getImage(path). Also it is much cleaner to use ImageIO codewise, and I consider using ImageIcon for anything other than Swing icons a sin Smiley

Offline v0rtex

Senior Newbie





« Reply #8 - Posted 2012-02-19 17:58:17 »

I don't want to sin! Ok will integrate that, thanks!
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #9 - Posted 2012-02-19 18:04:17 »

REPENT OF YOUR SINS! Grin

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline v0rtex

Senior Newbie





« Reply #10 - Posted 2012-02-19 18:29:24 »

Uhm, one last question when I run the code, the tiles now load fine but there is huge spaces in the tiles themselves. I am unsure of how to remedy that? Any help is appreciated...
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #11 - Posted 2012-02-19 18:32:39 »

What do you mean by huge spaces? Could you provide a screenshot?

Offline v0rtex

Senior Newbie





« Reply #12 - Posted 2012-02-19 18:38:26 »

Sure.

http://s16.postimage.org/j78mb49xh/spacing.png
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2012-02-19 18:39:57 »

Are the images 15x15? Wink

Offline v0rtex

Senior Newbie





« Reply #14 - Posted 2012-02-19 18:40:44 »

128 x 128. But I changed the tileSize variable:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;

import javax.swing.ImageIcon;

public class ArrayToImage {
   Image image;

   private Image wall = null;
   private Image stone = null;
   private Image Water = null;
   int x, y, temp = 0;
   private boolean imagesLoaded = false;

   public void loadImages() {
      wall = loadImage("Wall.png");
      stone = loadImage("Stone.png");
      Water = loadImage("Water.png");

      imagesLoaded = true;
   }

   private Image loadImage(String fileName) {
      return new ImageIcon(fileName).getImage();
   }

   public void drawImage(Graphics g, Image image, int x, int y) {
      g.drawImage(image, x, y, null);
   }

   public ArrayToImage() {
   }

   // This function will return an BufferedImage with all the tiles drawn on it
   public BufferedImage getMap(int[][] map) {
      loadImages();
      int largestRow = 0;
      for (int i = 0; i < map.length; i++) {
         if (map[i].length > largestRow)
            largestRow = map[i].length;
      }
      int tileSize = 128;

      BufferedImage bufferedImage = new BufferedImage(map.length * tileSize,
            largestRow * tileSize, BufferedImage.TYPE_INT_BGR);
      Graphics2D g2d = bufferedImage.createGraphics();
      g2d.setColor(Color.white);
      if (imagesLoaded) {
         for (int height = 0; height < map[0].length; height++) {
            for (int length = 0; length < map.length; length++) {
               switch (map[length][height]) {
               case 0: {
                  g2d.drawImage(Water, length * tileSize, height
                        * tileSize, null);
                  break;
               }
               case 1: {
                  g2d.drawImage(wall, length * tileSize , height
                        * tileSize, null);
                  // g2d.setColor(Color.red);
                  // g2d.fillRect(length*tileSize, height*tileSize, 32,
                  // 32);
                  break;
               }
               case 2: {
                  g2d.drawImage(stone, length * tileSize, height
                        * tileSize, null);
                  break;
               }
               }
            }
         }
         if (imagesLoaded == false) {
            System.out.println("Error Loading Images!");
         }
      }
      g2d.finalize();
      g2d.dispose();
      return bufferedImage;
   }

}
Offline ra4king

JGO Kernel


Medals: 353
Projects: 3
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2012-02-19 18:44:28 »

The screenshot doesn't look like the tiles are 128x128, they look more like 96x128.

Also, you don't need curly braces around cases in a switch statement.

Offline v0rtex

Senior Newbie





« Reply #16 - Posted 2012-02-19 18:45:57 »

They were 76x128. OOPS Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

DarkCart (16 views)
2014-10-31 21:44:48

DarkCart (21 views)
2014-10-31 21:43:57

TehJavaDev (40 views)
2014-10-27 03:28:38

TehJavaDev (31 views)
2014-10-27 03:27:51

DarkCart (44 views)
2014-10-26 19:37:11

Luminem (27 views)
2014-10-26 10:17:50

Luminem (30 views)
2014-10-26 10:14:04

theagentd (36 views)
2014-10-25 15:46:29

Longarmx (64 views)
2014-10-17 03:59:02

Norakomi (62 views)
2014-10-16 15:22:06
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!