GameMaker: Fun with Surfaces
Surfaces are one of the keys to success in GameMaker. It allows us to use advanced features, such as mini-maps, shadows, fog of war and other fun things. I am going to show you in this crash course how to use them.
You need an understanding of GML. If you are still using Drag and Drop Items, you might not understand this tutorial and want to dive into programming first.
Still here? Good, grab a cup of coffee and some cookies.
Next you are going to need one or two different backgrounds, an enemy sprite and a player sprite. I used sprites from this pack: http://opengameart.org/content/space-shooter-redux Consider donating to Kenny if you like his art, he does all this stuff for free.
All set? Good, now onwards, my minions, to the tutorial!
Alright, the first section should be pretty straightforward.
Create one or two different backgrounds, depending on your gusto. I use one bright and one dark background.
Create a sprite, name it sprEnemy and load one of the sprites from the pack.
Create a sprite, name it sprPlayer and load (a different) one of the sprites from the pack.
Create objects for the previously created sprites (they don’t need to do anything, but you can make the player move if you want)
Create a room.
Set it’s height to 720 and it’s width to 2560 in the settings
Switch to views
Make the room follow the player
Set “View in Room” to 1280x720
Set “Viewport on Screen” to 1280x720
Add one instance of the player and some random number of enemies randomly to the room.
Set the lighter background for the room.
This is how it should look like:
Parenting is pretty much polymorphism in GM:S. So if you set a parent, all events in that parent are transferred to the child. Or, you can make this object the parent of all objects that need to be drawn on the mini-map and you can walk them without having to search for each object that you want on your mini-map. This is quite handy.
Create an object, call it objShowMiniMapParent and assign it as parent to objEnemy and objPlayer.
So we do not want our player having to stare at the mini-map all the time. You want to have a quick look and he knows what is happening. Since we are using a parent to walk through all objects, we do not know what kind of object it really is. If it is the player or an enemy. For this reason, we use 2 new images:
Now double click your player sprite in GameMaker. Go to “Edit sprite” and in the File menu, click on “Add from File”. Now GameMaker will complain that this file has not the same size. Answer as shown here:
This will ensure your sprite will not get cropped and the circle is placed on a transparent background. Later in the code, we are going to use this to display the circles on the mini-map.
You should have it like this now:
But, if you would start the game right now, the game would “play” it as animation. That is why we need to add some code to the player object and the enemies. Add a create event to both of them and add this code:
Setting image_speed to zero stops the animation and image_index set’s the normal sprite of your space ship as current sprite, provided it is 0, which it should be since you added the circle after the normal sprite, right?
Now we are going to create the mini-map. Create an object and name it objMinimap. I always like to add a sprite with an ugly background and some text on it to it, so I find it better in the editor. But that is up to you. Place that object in the level.
Now, coding time. We are going to use a surface to draw our mini-map. So first, we create a “Create Event” and add this code:
Next, we are going to create the surface with the exact size of our room and draw the content of our level to this surface. Create a new script in the step event for this code:
This part is easy. We need to draw the surface to our screen. Add a “Draw GUI” Event to objMiniMap and add this code:
As you can see, using the surface is pretty straightforward and easy. And this is what it looks like:
There are easier ways to add mini-maps and you can actually use views for that. But in my opinion, that is just plain ugly. This way we have a nice mini-map that can be distinguished from the actual level and gameplay and you only need a quick look to see what is going on. You can use this technique for space games, platformers, RTS, does not matter. The approach can always be similar. Of course, if you have really a lot of objects, this might cost significant performance!
But it should be good enough for your average household 2D Game. Hope you have fun using this tutorial in your game.
If you want to save memory, scale down the actual size of the map when you create it, by dividing the room size with e.g. 3 or 4. Don’t forget to adjust the coordinates of objects too, by dividing them through the same number. This is especially important on mobile devices.