Showing posts with label grid. Show all posts
Showing posts with label grid. Show all posts

Tuesday, November 8, 2011

Step one : Map

The first thing on my list if the map so lets get on to it.

And yes ! It`s time for another wonderful diagram :

And then :
Now the map is the first milestone of my little project. As said in my little graph the map is a grouping of classes that I call Tile. They hold a background sprite for the terrain they have room for an NPC or object to occupy the tile. I'm not sure yet if the tile has a reference to objects on top of it or the object on it has a reference to the tile, or both. Loading a sprite on a tile (and thus, loading the whole grid with tiles) is another thing I'm not sure about. My first reflex is to throw an 2d array at it and translate the integer values to images. Lets say :
{ 3, 2 }
{ 3, 1 }
3 is a road, 2 is grass and 1 is water. When the array is sent to the Grid it assigns a sprite depending on the value received. Of course this is a cheapo solution, a better way would be of creating a custom data structure that contains lets say an array of sprites. The way the sprite array is created is by using technique that I didn't figure out yet. Now that the structure is filled with images I send it to the grid at generation or I use a function to replace the current grid and render the grid again to reflect the changes. In the end I think that whatever technique I use I'll have to translate an array to images anyway. The big difference is what I send to the grid. If I send an array the grid needs to do the translation, if not an external module does the translation and send the already constructed structure to the grid and it simply replace the structure with the one I sent. I need an idea.

In my last game I used the array of int technique to create my maps. A simplified version looks like this :
{ 3, 3, 3, 1, 3, 3, 3, 3, 3,
   3, 3, 3, 1, 3, 3, 3, 3, 3,
   2, 2, 2, 1, 3, 3, 3, 3, 3,
   2, 2, 2, 1, 3, 3, 3, 3, 3,
   2, 2, 2, 1, 1, 1, 1, 1, 1,
   3, 3, 3, 3, 3, 3, 3, 3, 3,
   3, 3, 3, 3, 3, 3, 3, 3, 3 }

It looks pretty simple, lets say the 1's are roads, 3's are grass and 2's represent water. Just by looking at the array you can see a rough outline on how the map will look. Road starts from north goes to the center of the map next to a little pond and veers right to the east. The problem comes from the fact that there might be a hundred of sprites used and I need a number for each. After a while the map might look like this :
{ 33, 33, 33, 2, 33, 33, 33, 33, 33,
  103, 3, 3, 2, 33, 33, 33, 33, 33,
  6, 3, 3, 2, 33, 33, 33, 33, 88,
  33, 33, 33, 2, 33, 33, 33, 33, 33,
  46, 45, 9, 2, 2, 2, 2, 2, 2,
  33, 33, 33, 33, 33, 33, 33, 33, 33,
  33, 33, 33, 33, 33, 33, 33, 33, 33 }

Thats pretty much the same map as above exept I added a house and replaced the lake by a river. Can you make sense of this array now ? Not me, at least not with a quick glance. Last time I ended my project by trying to create a program, some kind of map-editor, on which I placed tiles and I it returned the array that I could copy & paste on my game and use. This was a semi-good idea in the sense that it kind of worked but it was a pain to create the external program and it took my attention off of the main project.

*Idea*
One way I could use is to create a .png of the map and import it to my game, the game will now take this image and turn it into a instance of a Grid readily available. Pros and Cons are:
Pros :
It's fairly easy to create a map in paint.
Importing it is extremely easy and fast.
Cons :
I need to make a custom content importer.
I need to make sure the map is 32 * MapSize.X and the tiles need to be spaced exactly on the right spot or the content importer will get the wrong tiles. For example if the first tile is at (0,0) and 32 in size, the tile to the right of it needs to be placed exactly at (33, 0) or I'll lose part of the tile. If my hand slips and I place the tile at (32, 0) I'll lose the one line of pixel. When the content importer takes the image and divide it by blocks of 32x32 it will not grab the right tiles, like everything's going to be offset by one pixel.

In the end I think I''ll try it, for lack of a better idea.

Thursday, March 11, 2010

Milestone achieved !

The Proof
Well I finally have something to show as a proof of concept:

Isn't that awesome ? Megaman standing on a map full of road and grass ! I made the image extra large so you all could see it. The simplicity of this piece of program is more complex than you can image. I will deploy a few images to explain what code I used to piece this up.

First I used both the "ArrayMap" and the "GridMatrix" technique from earlier posts. I have two arrays - BasicRoad and SpriteMap, that contains the values of which tile and sprite to apply in which position of the matrix ( as seen on the left ).

Then I created a method to take the values in the BasicRoad array to decide which image to place in the tiles matrix.
Afterwards I took the images from the matrix and put them inside a picturebox-like class and placed the tile on the form.
Next I had to do the same with the sprites, but unfortunately I had a problem. My idea was to place the sprite in a picturebox and put that picturebox on top of the tile he's resting on. But there is no opacity property on pictureboxes so wherever I put the sprite he was hiding the tile under him. Making an ugly hole in the map. to solve this problem I used the backgroundImage property and took the image of the tile he's resting on and applied it as background.

I created two classed derived from picturebox: GridTile and SpriteTile so when I scrolled through the form I could use their type to get only the tiles or only the sprites.
 
You can see that I am passing quite a few parameters to these classes, instead of giving them their values after I created them. I made a New() so I could give them their values directly when created. Much cleaner that way. You can see where I use the me.backgroundImage property and used the coordinates from the matrix. 

I'd like to stress that this is NOT a representation of the final project. This is from the vbProject that I made to explore the mechanism that I will use in my game. I still haven't done a single line of code regarding the game itself. The sprite I used are not mine and property of their respective owner. But I can take credit for the tiles since I made them, and they are awesome.

Wednesday, March 3, 2010

Design UPDATE !

Yes, an update already. I've been messing around with my IDE and decided to give a go to the design of the game. What I did here was to generate the grid of the game window. As you know in earlier RPG's, the world was a series of tiles aligned in a matrix pattern ( Meaning for example: a 16x16 grid, showing 256 tiles total ) and your character and anything in the game world occupied a single tile. I made a few samples to give me a better idea of what I wanted my game grid to look like.


I had a choice between placing each individual tile on the form, or programatically add them after the form loads. The advantage in adding them after the form has loaded is that your form can be easily modified. As well as giving a greater number of design tweaks. I tried both method thought, placing them manually and automatically. And here are my results:


The one on the left is the automatic, right now is manual.

I chose the colors at random just to give me an idea on the output. Not a lot of difference you might say ? Well when you look at my design form, you can see it is a lot less cluttered. 

Automatic generation yields a much cleaner form designer.


The one on the left is the auto-generated window, the one on the left is the one I added every single tile by hand ( with the help of CTRL+V of course ). You can see the absence of picture boxes on the one on the left because there is currently no tile alive yet. They have yet to be created. Also, the code for autogeneration is MUCH smaller than the manually added at start. 

Let me explain why: When placing controls on the form, even thought you cannot see the related code, some is still created. For a single picture-box, is looks like that
      Me.PictureBox195.Location = New System.Drawing.Point(288, 372)
        Me.PictureBox195.Name = "PictureBox195"
        Me.PictureBox195.Size = New System.Drawing.Size(32, 32)
        Me.PictureBox195.TabIndex = 213
        Me.PictureBox195.TabStop = False
Multiply that by 256 times, and you get quite a big file to load already at start. Meanwhile, when adding them automatically when the form loads, they are added one by one with much cleaner code thus making your source code smaller and lighter. The code I used for both forms is thus:

The first one is for the auto-generate, and the second one is manual. You can see on the second image that the only code running is the color-chooser, thats be cause there IS NO code needed on the main() procedure for showing all the picture boxes. But when you compare the first to the second, one simple method is much cleaner than 265 chunks of designer data.


All in all, auto-generation is a much better choice for the purpose of making game because the grid is not static. As we move to the edge of the screen I have to be able to change the map very quickly and efficiently .