Author: Mark Alexander
Requirements: GameMaker: Studio Professional licence.
- Be able to import SWF files
- Know how vector sprites work
- Be able to use vector sprites
- Know what the Draw begin, Draw and Draw End events do
This tutorial is a very simple one designed to introduce you to the vector sprite capabilities of GameMaker: Studio Professional. Generally all sprites in GameMaker use bitmaps which, while flexible in terms of content, place limitations on both the size and number of frames possible in a sprite before memory usage can become prohibitive. Vector sprites work around these limitations by storing and drawing their contents differently - instead of a grid of pixels, which can become blocky or fuzzy when scaled, they are drawn as triangles (polygons) which can be scaled up without losing definition, as illustrated in the image below:
As you can see, quality is maintained when scaling vector sprites, making them an ideal solution when creating games to scale for different devices, or when your game requires the view to zoom in or out, etc...
So, in this tutorial, we are going to add some vector sprites to our "game", which uses a zoom and scale mechanic to move around. Note that the game itself is already coded for you and this tutorial will not cover the code itself, but rather the visual aspect of changing from bitmap to vector sprites (however the code is commented and can still be learned from).
Before going any further you should download the attached SWFTutorial.zip and extract it's contents to a safe location. The GMZ that is included is the base file required by this tutorial and you should open it in GameMaker: Studio now (Start GameMaker: Studio and then click the Import tab and browse to the folder you saved the GMZ in). There is also a folder titled "Vector Assets". From time to time this tutorial will require you to use images from this folder, so make sure you remember where you have saved it.
Before going any further, take a moment to play the game that is included with the SWFTutorial.zip (link at the top of this page). You need to use the left/right arrow keys to move, the <Shift> key to jump, and you can use the mouse wheel to zoom the view in or out.
Now, you'll notice a couple of things here... first, the player character appears to shrink and grow with the room, and second, when you zoom right in the graphics are horrible to look at! This is because they are bitmap sprites, and zooming in makes the individual pixels far more visible.
Vectors To The Rescue!
The game mechanic in this platformer is interesting, but you would need to increase the size of everything by two or three times so that the zoom doesn't show the individual pixels up close, and that would require a lot more memory to run, larger texture pages and a number of other fixes which are far from optimal. However, if we replace the images being drawn with vector sprites we can change this and maintain a great, sharp look throughout the whole game.
As mentioned previously, vector sprites are drawn differently to traditional bitmap sprites. They are stored as a series of filled polygons, which GameMaker then draws, and the image below shows how this is achieved by depicting a "skeleton" of polygons for a sprite:
Being vector based means that their memory footprint is a lot less than a bitmap sprite and that they scale far better. Note that the down side to this is that they are also more processor intensive to draw, so you have to trade off a certain amount of power for the extra looks!
Since our major issue in this demo game is the background, we'll start by changing that to use a vector based image. However, GameMaker: Studio doesn't accept vector images for backgrounds so we are going to substitute our background image for a sprite and have the controller object draw that instead of setting the background in the room editor.
Our tutorial game uses two background images, one for the dark stone wall at the back, and then a foreground image that "overlays" everything, so you should first turn these backgrounds off in the room editor. This is done by opening the room editor, then clicking on the "Backgrounds" tab and for each one un-checking the "Visible when room starts" option.
Loading A Vector Sprite
Currently GameMaker: Studio can only import vector images from SWF format files, and the way of importing them into the program is almost identical to that for adding a normal bitmap image.
To add a vector sprite, create a new sprite, which will bring up the standard Load Sprite dialogue, but make sure that you have selected *.swf from the file filter at the bottom.
Hitting the "Load" button will add the vector image or animation to the resource tree, with a progress bar being shown as the file is processed. Note that, depending on the complexity of the file, this can take a while (up to a minute for more complex animations). When processing has finished you'll be returned to the sprite properties dialogue, which we will cover now as we are now going to add our first vector sprite to the game!
Create a new sprite asset and call it "spr_Background", then click on the load button. You will need to navigate to the "Vector Assets" folder which you should have downloaded already and select "spr_Background.swf". Note that it could take a moment or two to load since it is a vector file and they take longer for GameMaker to parse (time will vary depending on their complexity).
Once it has loaded, set the origin to (0,0), and it is worth noting that you have two extra options in the Sprite Properties for vector sprites: Quality (as a slider) and Preview.
Since vector sprites are simply a collection of polygons, you can set a quality level for them, where a lower quality will make GameMaker use less polygons to render it, and a higher quality will use more. The setting you use here impact on your game, since a higher quality will require more processing, so you should think about what you plan to do in your game and what devices are going to tun it before setting this. You can also hit the "Preview" button to have GameMaker create a SWF file using the set quality level for you to see how it looks. For our game, since it has little going on in it, you can set the quality to 100, then click the "OK" button to save the new sprite.
Drawing The Vector Sprite
With that done, you need to open the object "obj_Control" and add a Draw Begin event. We are using the Draw Begin event simply because we want the image to appear beneath everything else, like a background, and this event is perfect in this situation as all other instances draw things in the standard Draw event, meaning that anything in Begin will be drawn under everything else, regardless of depth. Once you have added the event, drag a code block action and add the following code:
This code will draw the vector sprite stretched to fit the room. However, sprites drawn in the Draw Begin event will also draw behind conventional backgrounds defined in the room editor, so remember to remove any backgrounds before continuing. Now create another new sprite asset and call it "spr_Foreground", then add the "spr_Foreground.swf" file from the Vector Assets folder, as you did for the first image. This may take longer to load as it is a much more detailed image, but when it has loaded, set the origin to (0,0) and the quality to 100 then click on the "OK" button.
As with the background image, for the foreground we are going to take advantage of the extra Draw events, in this case the Draw End event. To save some time you can simply duplicate the Draw Begin event, as the code we are going to use is exactly the same (to duplicate the Draw Begin event, right click on it then select "Duplicate Event" and select the Draw End event as the target). Open the code block and change the name of the sprite being drawn to "spr_Foreground" then close and save it.
You can now run the game again and you should see that no matter how much you zoom in, the game graphics are still clean and sharp.
You are not limited to static images with SWF files however, and in the next part of this tutorial we will see how simple it is to add animated vector sprites to our games.
One of the things that vector sprites permit is for you to import SWF animations and use them as you would normal sprites in your game. SWF animations have all the benefits of vector images previously mentioned, but they can also give a smoother, more natural feel to animations, so we are going to convert our player sprite from a boring single image, into a much nicer animated sprite.
As you saw before, adding a vector sprite to GameMaker: Studio is practically the same as adding a bitmap sprite, so go ahead and add four new sprites to the resource tree, one for each of the "spr_Player_*.swf" files bundled in the Vector Assets folder. Name each sprite like it's file name, giving you "spr_Player_Idle", "spr_Player_Run", "spr_Player_Jump", and "spr_Player_Fall". Make sure to set the x and y origins to 150 and 380 (so that the origin is at the feet of the sprite) and set the quality slider to 100.
You will see that the sprites have been authored at a larger size than we actually need, which would normally mean that you would have to use the image editor to scale them down, or draw them scaled down using code, which in turn would affect their quality... but with this being a vector sprite we don't need to worry about this and can draw it at the scale we require, as you will see.
NOTE: the image shown in the preview window of the Sprite preferences is generated automatically by GameMaker to give you an idea of the contents of the SWF file. However it is not an accurate representation of the finished sprite and it is only a basic, single frame image that you are seeing, not the final animated sprite.
Code The Animations
In most circumstances you can assign a vector sprite to an instance and it will be drawn as any regular sprite would. In fact, as far as <i>GameMaker</i> is concerned it is the same as any other sprite and all the instance variables that control sprite properties like scale, alpha etc... will work for as normal. However, in our demo game we can't set the sprite_index of the instance to our vector sprites, as we require the mask sprite to be used for the collisions and scaling, so we will use some custom variables and draw the sprite using them.
Open up the object "obj_player", and add the following code into the Create Event, after the rest of the code:
As you can see from the comments, these variables will control the scale, sprite, and animation. We will now use these variables in the End Step event of the instance, so go ahead and add that now, then drag a code action and add this code:
Here we first check to see if the player vertical speed is 0 and that there is "ground" under the player, and if there is we either set the player sprite to "idle" or "running" depending on whether the keys are being pressed or not. If the player is falling/jumping, we then check the vspeed and set the appropriate sprite.
Now add this piece of code:
With this, we check the keys and set the "p_side" variable so that the image will "flip" when the player goes left and right, then we increment the "p_img" variable. We must do this because the built-in image_index variable can't be used (since the actual sprite_index has no animations) yet we want our sprites to move! The final stage is to change the Draw Event, which requires a simple substitution of the code it contains for the following:
That will draw the sprite correctly, taking the base scale and the current image scale into account. Run the game now and play around with it, zooming in and out and jumping around. You should see that the player sprite now animates and that everything works perfectly!
As you have now seen, SWF vector sprites are used in a game just like any other sprite. You can use all the built in variables with them, and you can draw them with all the draw functions except the draw_sprite_part() and draw_sprite_pos() functions. They are great for scaling and for creating smooth animations, and they have a very low memory footprint. However, there are a few caveats to using vector sprites, which are outlined below:
- When importing a *.SWF file, Actionscript is not supported, so if your SWF relies on it to work correctly then it probably won't turn out right. Similarly, any embedded movie clips that have their own timeline will only have their first frame shown throughout the animation - all animation must be on the main timeline.
- If your vector file has particularly fine detail you may occasionally find that holes or strange triangles will appear in the resulting sprites. This is because at small scales geometry can sometimes collapse together to create shapes that just don't triangulate well. In this case you have two options - you can scale up the contents of the vector file which will give the importer more room to play with, or you can try to reduce the level of detail in the object that is breaking.
- GameMaker: Studio uses the stage size of the SWF as the bounds of the resulting sprite. However, if you have anything on the stage outside these bounds it is still drawn. This means that you should either try to avoid putting anything outside your stage bounds if you don't want it to be shown, or use a mask layer to limit drawing to this area.
- The stage size also affects the size of any collision masks that are generated, therefore if you have a large stage size and a lot of frames in your animation you can potentially eat up a lot of memory. So, only use precise collision masks if you really need it.
- As a SWF file is created from multiple layers, some of which potentially overlap, alpha doesn't work quite the way it does with bitmap sprites - overlapping areas will not look as transparent as other parts of the sprite, as the pixels there are being drawn over multiple times.
- Bitmap fills are supported though if you use tiled bitmap fills as part of your SWF file you need to make sure the bitmap is a power-of-two in size, otherwise it won’t tile properly. Text rendering is also supported, but you need to embed the font in your SWF file for it to show up in the resulting sprite. Also, currently only left-aligned single line text is supported.
As long as you keep these things in mind while creating the SWF file, you should have no issues using them in GameMaker: Studio Professional.