As stated, we originally planned to do everything from scratch. And I mean everything. So for the graphics' storing, we designed a simple heriarchy that would lead us from the pixel to the world network.
Originally:
- Pixel: would store the RGB values;
- Boxel: would store a matrix of pixels such as a texture (lame pun for voxel, I know, I know);
- World: would store a matrix of boxels;
- World_Table: would store all the worlds and their names for future references.
However we quickly learned that generating output from raw information like this is very complicated. Not only that, but there's already classes that do so more efficiently.
Thus, we started using BufferedImage, a Java-integrated class that can quickly load and save external images, as well as have useful resources such the ability to edit the inside tiles (should that ever be necessary).
We also decided making a World an ordered list of Maps. Why? Well, that way we would have Background Maps, Ground maps and Foreground Maps. This is mainly aesthetic, but:
- Background: What's in the back of the screen. Doesn't affect or hide anything. Looks pretty;
- Ground: where everything stands and happens. This is the only "functional" map. The platforms with which you interact;
- Foreground: What's in front of the ground. Aesthetic, but can hide the player (and enemies!) from the camera.
Once we have all that, well, let's move to the how-tos.
Loading textures
The million dollar question: where do we get a texture from? Answer: from an image. Duh. For reasons of space and image quality, therefore, we store the textures in a .png file.
When we talk about textures we really mean all the visual boxels that represent elements of the game, or sprites. Of course, somebody must first draw these sprites, manually. That's why one normally designs a pattern that's unambiguous to paint on (where do I draw? How many pixels wide is this supposed to be? Etcetera). The easiest way out is making a grid with background colors that you don't plan on using on the game to distinguish them from the real textures:
We've loaded the textures. We're supposed to keep them in matrixes inside Worlds. But, what texture goes in each slot? This is a thing the designers must decide when creating each map, making a world of their own. How? Why, with basic bitmap-mapping, of course!
---------------------------
EXTRA INFO: BITMAP-MAPPING
Though I call it this name, truth is this technique probably has another one, but I can't be bothered to search it (lazylity F-T-W!).
Bitmap-mapping is using an image so that every pixel of it represents one boxel, and the color that every pixel has is translated to a sprite in the game (through interpretation of the color). Example:
Loading textures
The million dollar question: where do we get a texture from? Answer: from an image. Duh. For reasons of space and image quality, therefore, we store the textures in a .png file.
When we talk about textures we really mean all the visual boxels that represent elements of the game, or sprites. Of course, somebody must first draw these sprites, manually. That's why one normally designs a pattern that's unambiguous to paint on (where do I draw? How many pixels wide is this supposed to be? Etcetera). The easiest way out is making a grid with background colors that you don't plan on using on the game to distinguish them from the real textures:
We are definitely not using that pink. Ever.
Making an algorithm that ignores the margins and only grabs the 400px inside was relatively easy; BufferedImage allows to grab a portion of itself with the getSubImage(int x_coord, int y_coord, int width, int length) method.
Loading the worlds
We've loaded the textures. We're supposed to keep them in matrixes inside Worlds. But, what texture goes in each slot? This is a thing the designers must decide when creating each map, making a world of their own. How? Why, with basic bitmap-mapping, of course!
---------------------------
EXTRA INFO: BITMAP-MAPPING
Though I call it this name, truth is this technique probably has another one, but I can't be bothered to search it (lazylity F-T-W!).
Bitmap-mapping is using an image so that every pixel of it represents one boxel, and the color that every pixel has is translated to a sprite in the game (through interpretation of the color). Example:
In this map, the black pixels represent dirt, or the first texture, whereas the white ones are air - technically speaking, no sprite whatsoever.
-------------------------
Painting the result
We've got the textures drawn (because we're awesome artists, that's why); we've got a good storage, a good interpret, and a world that makes sense with them. But those are all just assumptions! How to we make them graphic to check we're on the right track?
Making the screen display your game is possibly the most abstract part of them all. You're used to work with command lines and ASCII outputs - how are we going to get the wizard that lives inside the screen help us showing our pretty doodles?
Luckily Java also has a couple of classes that will help our way around graphical outputting. A JFrame, for example, is an easy way to open a window in which to paint. Just be wary of making it the right dimension.
BUT! JFrame won't paint itself; rather, JFrame is there to be painted on. So, what brush shall we use to paint on our window?
The answer is Graphics2D. A class specialized in painting two-dimensional shapes and Images on any place that has graphics to offer (as in, linking them like Graphics2D g2 = (Graphics2D) jFrame.getGraphics()- remember to downcast!). With this, we're showing the Graphics2D where can it paint. Once he acknowledges that, it's party time. Every boxel takes an initial coordinates and paints its 20x20px texture on it own, eventually making a whole map.
You may remember this on facebook - that was the work of what I've just explained:
Note that the shape of the dirt and the air (auxiliarly the pink-background color) match the map Image I showed earlier. The difference between textures were cause of testing with dynamic neighbor-sensitive texture changing - but that's still green, and a story for another day.
[ANOTHER ENTRY shall be up in a relatively small amount of time. It will depict the problems so far with the view implementation. It will aid in keeping the entries topic-ordered as well as short (or at least shorter. I know I'm a long writer, bite me).]
-------------------------
Painting the result
We've got the textures drawn (because we're awesome artists, that's why); we've got a good storage, a good interpret, and a world that makes sense with them. But those are all just assumptions! How to we make them graphic to check we're on the right track?
Making the screen display your game is possibly the most abstract part of them all. You're used to work with command lines and ASCII outputs - how are we going to get the wizard that lives inside the screen help us showing our pretty doodles?
Luckily Java also has a couple of classes that will help our way around graphical outputting. A JFrame, for example, is an easy way to open a window in which to paint. Just be wary of making it the right dimension.
BUT! JFrame won't paint itself; rather, JFrame is there to be painted on. So, what brush shall we use to paint on our window?
The answer is Graphics2D. A class specialized in painting two-dimensional shapes and Images on any place that has graphics to offer (as in, linking them like Graphics2D g2 = (Graphics2D) jFrame.getGraphics()- remember to downcast!). With this, we're showing the Graphics2D where can it paint. Once he acknowledges that, it's party time. Every boxel takes an initial coordinates and paints its 20x20px texture on it own, eventually making a whole map.
You may remember this on facebook - that was the work of what I've just explained:
Note that the shape of the dirt and the air (auxiliarly the pink-background color) match the map Image I showed earlier. The difference between textures were cause of testing with dynamic neighbor-sensitive texture changing - but that's still green, and a story for another day.
[ANOTHER ENTRY shall be up in a relatively small amount of time. It will depict the problems so far with the view implementation. It will aid in keeping the entries topic-ordered as well as short (or at least shorter. I know I'm a long writer, bite me).]