Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (497)
Games in Android Showcase (114)
games submitted by our members
Games in WIP (563)
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  
  Tile Maps...  (Read 1987 times)
0 Members and 1 Guest are viewing this topic.
Offline DarkMortar

Junior Member




Java Padawan


« Posted 2006-12-05 06:37:18 »

I've been working on a tile map that draws 40x40 tiles onto the canvas evenly using my own logic. I have tho, used kev glass' SpriteStore and Sprite class so that I can store duplicate tiles in one memory spot, im actually not sure if i used the class totailly correctly, of wheather or no its really in one memory space.

Well anyway, I have drawn the tiles on the canvas with sucess Smiley. But the scrolling part is bothering me. Yes, it scrolls, BUT it renders all of the tiles AT ONCE, and if i make a map even slightly big, it will lag like nuts or not load at all! So its bad because im rendering a huge image now.

Then, to count this, i added another array that keeps track of visibility. I made final int variabled HIDDEN and VISIBLE, it works well, and it will only render tiles within your screen on any resolution. BUT i dont know how to make them HIDDEN, then VISIBLE as you scroll through the screen, so basically my map is only what fits in the screen, and as you scroll around, the rest is the black background. but the HIDDEN does work, because i can have any map size and it wont lag, but the problem is that i dont know how to scroll then draw, then make hidden.

some snippets:
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  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
import java.awt.Graphics;
import java.util.Random;

/****************************
 * WorldGenerator v1.0
 * + TileMap Class
 * @author X
****************************/


public class TileMap {

   /** The value indicating a clear cell */
   private static final int LIGHT_GRASS = 1;
   private static final int DARK_GRASS  = 2;
   private static final int DIRT        = 3;
   private static final int SAND        = 4;
   private static final int WATER       = 5;
   
   /** The value indicating a blocked cell */
   //private static final int STATIC = 1;
 
   /** The sprite that represents this entity */
   protected Sprite tileGraphic;
   
   /** The current x location of this entity */
   protected int xPos;
   /** The current y location of this entity */
   protected int yPos;
   
   Random rand = new Random();
   
   private int random;
   private final int VISIBLE = 0;
   private final int HIDDEN  = 1;
   
   private String mapName;
   
   /** The width in grid cells of the map */
   private int MAP_WIDTH;
   /** The height in grid cells of the map */
   private int MAP_HEIGHT;
   
   /** The rendered size of the tile (in pixels) */
   private int TILE_SIZE;
   
   /** The actual data for our map */
   private int[][] tile    = new int[0][0];
   private int[][] tileVis = new int[0][0];

   public TileMap(String ref, int width, int height, int x, int y, int size) {
     
      this.mapName = ref;
      this.MAP_WIDTH  = width;
      this.MAP_HEIGHT = height;
      this.xPos = x;
      this.yPos = y;
      this.TILE_SIZE = size;
      this.tile    = new int[MAP_WIDTH][MAP_HEIGHT];
      this.tileVis = new int[MAP_WIDTH][MAP_HEIGHT];
     
      /** DIRECT CONTROL */
      /*
      this.tile[0][0] = LIGHT_GRASS; this.tile[1][0] = LIGHT_GRASS; this.tile[2][0] = LIGHT_GRASS; this.tile[3][0] = LIGHT_GRASS;
      this.tile[0][1] = LIGHT_GRASS; this.tile[1][1] = LIGHT_GRASS; this.tile[2][1] = LIGHT_GRASS; this.tile[3][1] = LIGHT_GRASS;
      this.tile[0][2] = LIGHT_GRASS; this.tile[1][2] = LIGHT_GRASS; this.tile[2][2] = LIGHT_GRASS; this.tile[3][2] = LIGHT_GRASS;
      */

     
      for (int i = 0; i < this.MAP_WIDTH; i++) {
         for (int j = 0; j < this.MAP_HEIGHT; j++) {
           
               random = rand.nextInt(2)+1;
               //if (random==0) { this.tile[i][j] = LIGHT_GRASS; }
              if (random==1) { this.tile[i][j] = DARK_GRASS;  }
               if (random==2) { this.tile[i][j] = DIRT;        }
               //if (random==3) { this.tile[i][j] = SAND;        }
              //if (random==4) { this.tile[i][j] = WATER;       }  
             
               this.tileVis[i][j] = HIDDEN;
         }
      }
     
      for (int i = 0; i < (800 / TILE_SIZE); i++) {
         for (int j = 0; j < (600 / TILE_SIZE); j++) {
           
            this.tileVis[i][j] = VISIBLE;
         }        
      }
   }
   
   public void setX(int amount) {
      this.xPos += amount;
   }
   
   public void setY(int amount) {
      this.yPos += amount;
   }
   
   /**
    * Draw this tile to the graphics context provided
    *
    * @param g The graphics context on which to draw
    */

   public void draw(Graphics g) {
     
      for (int i = 0; i < this.MAP_WIDTH; i++) {
         for (int j = 0; j < this.MAP_HEIGHT; j++) {
            if (this.tileVis[i][j] == VISIBLE) {
               if (this.tile[i][j] == LIGHT_GRASS) { this.tileGraphic = SpriteStore.get().getSprite("\\tile_textures\\lightGrass.png"); }
               if (this.tile[i][j] == DARK_GRASS)  { this.tileGraphic = SpriteStore.get().getSprite("\\tile_textures\\darkGrass.png");  }
               if (this.tile[i][j] == DIRT)        { this.tileGraphic = SpriteStore.get().getSprite("\\tile_textures\\dirt.png");       }
               if (this.tile[i][j] == SAND)        { this.tileGraphic = SpriteStore.get().getSprite("\\tile_textures\\sand.png");       }
               if (this.tile[i][j] == WATER)       { this.tileGraphic = SpriteStore.get().getSprite("\\tile_textures\\water.png");      }
               
               this.tileGraphic.draw(g, this.xPos+(this.tileGraphic.getWidth()*i), this.yPos+(this.tileGraphic.getHeight()*j));
            }
         }
      }
   }
}


1  
2  
3  
4  
5  
6  
7  
public void programScroll(TileMap map) {
      TileMap mapped = map;
      if (leftPressed)  { mapped.setX(4);  }
      if (rightPressed) { mapped.setX(-4); }
      if (downPressed)  { mapped.setY(-4); }
      if (upPressed)    { mapped.setY(4);  }
   }

1  
2  
3  
4  
5  
6  
   /** BEGIN PAINT **/
         
         g.setColor(Color.black);
         g.fillRect(0,0,SCREENWIDTH,SCREENHEIGHT);
         
         defaultMap.draw(g);


Next time i proabably will not use normal arrays for a map, for this reason:

Well I was wondering if arrayLists are better since they handel objects and classes. You see when I get to making an RPG, each tile much keep track of:
Quote
Is it collidable?
Visible?
terrain type?
any inventory on the tile?
resources contained in the tiles(crafting)?

so what is the best way to make a 2D tile map for an rpg?

 ty for help!

Offline Eliwood

Junior Member




Stencyl


« Reply #1 - Posted 2006-12-05 07:08:21 »

Are you sure that SpriteStore is caching your images properly? It sounds like a case where you are loading in the images every frame drawn, which would explain the poor performance.

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #2 - Posted 2006-12-05 08:00:38 »

Well, you know which tiles are on screen. You know the size of the tiles, the world offset and the size of the window.

Calculate the x and y for the first visible tile (upper left)... translate... draw everything in place (screenw/tilew+1 * screenh/tileh+1tiles altogether) and un-translate again.

But... doesn't the TileMap thingy in slick that stuff for you? (I'm sure there is some render/draw method.)

弾幕 ☆ @mahonnaiseblog
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DarkMortar

Junior Member




Java Padawan


« Reply #3 - Posted 2006-12-06 01:54:06 »

i have thought of work arounds but i dont know if they are good to use. My tilemap class does know the tile corner position. Since my arrow keys move the screen 4 pixels per operation, i could calculate how much the map has move and mess with the arrays again for visibility.

Also i would like to understand the best way to make a tilemap, and if arrayLists are good for these?

also, the draw, then untranslate again wont work, because i move the screen fluidly, and no tile-tile, so the edge of the screen is usually not perfectly centered tile-tile, so usually the edges show only part of adjacent tiles.

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #4 - Posted 2006-12-06 06:07:07 »

>Also i would like to understand the best way to make a tilemap, and if arrayLists are good for these?

ALs are an option for editors, but in game you should use 2d arrays, because iterating across em is faster (and you don't need the dynamic resizing of ALs).

>also, the draw, then untranslate again wont work, because i move the screen fluidly, and no tile-tile, so the edge
>of the screen is usually not perfectly centered tile-tile, so usually the edges show only part of adjacent tiles.

Thats why you draw one row and column more. So, for 640x480 with 32x32 tiles you would draw 21*16 (instead of 20*15) tiles. The special case where 20 columns or 15 rows would be enough can be ignored.

弾幕 ☆ @mahonnaiseblog
Offline DarkMortar

Junior Member




Java Padawan


« Reply #5 - Posted 2006-12-07 00:25:23 »

True but i want it to render tiles as FAST AS POSSIBLE! So, I guess one tile more over for width and height "may" be faster than calculating the arrow key movements and where it really is maybe? Because one extra tile means in the final game, 50x50 size, and with bigger resolutions, that would be a huge waste of rendering all those extra tile corners.

Also, so 2d arrays are the fastest possible? But it seems like it can be slower if your are storing more than numbers for this reason.

With an arraylist, you can store and object so, each object can contain elements about the tiles, so it "may" be faster than a 2d array, because id have to scan through maybe like 10 2d arrays in a single loop across and down the screen. because the ~10 duplicate 2d arrays contain only single information.

Also since there will be mutiple maps, wouldnt i be wasting more memory if i made a crap-load of 2d arrays rather than a single arrayList? I dunno, help Tongue

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #6 - Posted 2006-12-07 01:27:40 »

>True but i want it to render tiles as FAST AS POSSIBLE!

Well, as I said... its a rare special case (with 32x32 tiles its 1:32) where you could draw one column or row less. Don't worry about something so meaningless.

And the other problem you have there... I don't understand it.

The 2D array only contains indexes like:
1,2,1,1,1,1,1,1
1,2,2,2,2,2,2,2

Which you use to for looking up the tiles (graphics), which are over in some other (1d) array. There can be another 1d array, which holds the physical properties of the tile (wall, ice, mud, slope whatever). And there can be another 2d array with like events or something like that.

So you iterate over the map 2d array across the parts on screen... and use those indexes to figure out which graphics to draw. Then you check the properties of the (few) interesting tiles for collision detection and stuff like events.

Thats it. Very easy and very cheap.

弾幕 ☆ @mahonnaiseblog
Offline DarkMortar

Junior Member




Java Padawan


« Reply #7 - Posted 2006-12-07 02:03:06 »

Ok, I get it, so make multiple 2D arrays. Not sure if i fully understood the extra 1d array part, since i was using final int numbers that are named, but really represent a number.

1  
2  
3  
4  
5  
6  
/
   private static final int LIGHT_GRASS = 1;
   private static final int DARK_GRASS  = 2;
   private static final int DIRT        = 3;
   private static final int SAND        = 4;
   private static final int WATER       = 5;


And why is that other array 1,1,2,11,2 etc.. if there are mutiple tiles, so are you saying that the 1 and 2 refer to different 1d-2d arrays. But i dont see why thats nessary when i need seperate 2d "layers" for visibility, crafting resource extraction values, colission, texure, whether or not that tile is fogged in fog view, etc...

Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #8 - Posted 2006-12-07 02:39:17 »

-At map[0][0] (which has the value 1)... I draw tile[1],
(done... say... 21*16 times if its 640x480 with 32x32 tiles for example)

-which has the attributes[1] (which are used for collision detection or whatever)...
(looked up 4 times if the character is <= tile size)

-and if I walk over it it triggers event[0][0] (if its set to something).
(looked up 4 times if the character is <= tile size)

Its one way to do it. If you want to do something different instead, go ahead.

edit: "21*16" instead of "26*16"... obviously

弾幕 ☆ @mahonnaiseblog
Offline DarkMortar

Junior Member




Java Padawan


« Reply #9 - Posted 2006-12-07 03:37:48 »

ok, ty.

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

Junior Member




Java Padawan


« Reply #10 - Posted 2006-12-10 13:33:01 »

just as a heads up, i sucessfully managed to scroll the map while hidding the tiles, and giantormous maps run flawlessly now, because of my visibility controls Smiley.

i may post a link to download my source code so it can be looked over and judged.

Offline DarkMortar

Junior Member




Java Padawan


« Reply #11 - Posted 2006-12-15 03:30:49 »

Ok, i got the source code uploaded. I would like it if someone would help me make it better, like faster and I need help with the following:

1) Best way to store map data array positions.
2) fastest way to render these thingys

Screenies:
http://img431.imageshack.us/img431/7838/1ot5.png
http://img98.imageshack.us/img98/134/2ge8.png
http://img98.imageshack.us/img98/5139/3lg0.png

and also when i use transparent images it is SLOWER, a lot, drops from any high-end fps to like 30-40fps Sad

Also does it seem slighly clucky, or flickery, i have buffering of course, but just SLIGHTLY?

Please someone help me, and see, or run my source code and give me recommendations, or change it and send it to me. It would be greatly apprecieated, and I'm sorry but im kinda noob at these things, but I promise ill get better if its fixed better. This program is based off Kev glass tuts, yet the actually tile algorithm and visibility controls are mine. I did use his SpriteStore and Sprite class though. But I also wonder if i am using them correctly in TileMap to store the images in only ONE memory location. I think not... Tongue

Quote
Kee-World-Ala-Tor v1.0

This program generates (stupid) random maps without corner overlay blending tiles. Yet the point of this program is to render a scrollable tile map, with visibility controls and have it be able to scale to any window resolution (works).

Features:
+ Renders a tile map based on 2D array algorithms
+ Scrollable
+ Grid on/off
+ Coord labels on/off
+ Transparent interface
+ 10 Sample Maps
+ Tile visibility controls (only tiles visible on screen are rendered) (works with any window size as well)
+ Edge of map scroll stops
+ Completely scalable interface
+ Works with any window size (within means)
+ Works with any tile texture size
+ Sync’ed scrolling based on fps

Issues:
+ Slow, slow transparency performance.
+ Slow drawRect and drawString performance (Grid/coord)
+ a little flickery?
+ Other things here and there


Download link, look to right and click Download, and then you click the link at the bottom, (sorry if this is a bad way to upload).
http://storeandserve.com/download/639271/WorldGenerator.rar.html

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.

BurntPizza (22 views)
2014-09-19 03:14:18

Dwinin (35 views)
2014-09-12 09:08:26

Norakomi (62 views)
2014-09-10 13:57:51

TehJavaDev (87 views)
2014-09-10 06:39:09

Tekkerue (42 views)
2014-09-09 02:24:56

mitcheeb (65 views)
2014-09-08 06:06:29

BurntPizza (47 views)
2014-09-07 01:13:42

Longarmx (35 views)
2014-09-07 01:12:14

Longarmx (40 views)
2014-09-07 01:11:22

Longarmx (36 views)
2014-09-07 01:10:19
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!