SoulHow to work with surfaces (Game Maker)

NOTE: This blog has moved!
Comments at this location are now locked.
If you want to comment or ask a question,
or see any new content whatsoever,
you will have to go to the new location!!!
Click here to view this post at the new location.
Posts will remain here but new content
and updates will ONLY occur at the new location.
Please update your bookmarks.
For more info, see this post.

Skill Level: Advanced user (7)

Welcome to the surfaces SoulHow article. In this article you will learn how to use surfaces in Game Maker. They can be used for many purposes, such as neat transitions, dynamic textures, and custom sprites made at runtime. A lot of people think surfaces are some magical, superdifficult concept you shall never understand except by…witchcraft. Got you.

The basic idea is this: A surface is like a blank canvas. Imagine going to the art store, and buying a blank canvas. On this canvas, you can paint whatever you want, and put it wherever you want on the wall. You can paint over what you’ve already painted, and you can rotate the canvas as well. However, unlike what is possible with a physical canvas, with surfaces, you can also scale and stretch, alpha blend, and transparify.

As I mentioned, first you need a blank canvas. So you go to the store and buy one. Or, in Game Maker, you call surface_create(), give it the width and height of the surface to be created, and catch the return value in a variable. The variable now holds the index number of your brand shiny new surface. Actually, it’s not shiny yet; you have to make it shiny. Or dull. Or whatever you want.

On this new surface, you can draw whatever you want. How do you do this, though? All drawing functions draw on the screen! Is there no possible way to get my drawing to go onto this surface?!

Of course there is, silly. You use surface_set_target() and feed it the index of your surface as an argument, and GM now knows that all further drawing should be done on that surface. Giving a value of -1 or using surface_reset_target() will tell GM to draw on the screen again.

Note: Contrary to common sense, do NOT switch drawing targets or draw on a surface in the draw event. Only in other events.  As stated in the GM manual, it will “cause serious problems with the projection and viewport”. So don’t.

First though, you have to clear the surface to nothing; that way, your surface doesn’t have to always be a rectangular drawing. Imagine painting on a glass canvas, where you can see what you paint but everything else is see-through. To clear the surface, use draw_clear_alpha(), and give it two arguments: c_white (for “color”), and then 0 (for “alpha”). This tells GM to make the surface completely transparent, essentially clearing it to no color at all.

Okay, now you can start drawing on the surface. You might do something like this in the create event (or anywhere but the draw event; see above):

mysurface=surface_create(32,32);
surface_set_target(mysurface);
draw_clear_alpha(c_white,0);
draw_sprite(sprReallyCoolSprite,0,0,0);
draw_set_color(c_black);
draw_circle(16,16,16,1);
surface_reset_target();

Let’s look at this line by line. First, we create a surface with the size of 32×32. Then we change the drawing target to the new surface. Next we draw a sprite and an outline of a circle on our surface, and reset the drawing target back to the screen.

There’s one thing to note here. When you draw on a surface, you need to ignore the room coordinates. Only worry about the surface. That means that 0,0, is no longer the upper-left corner of the room, but rather the upper left corner of the surface.

Imagine standing in a room with a large wall in front of you, and a canvas off to your right. When you set the drawing target to the surface, you’re turning away from the large wall and looking directly at the canvas. The wall means nothing. Then when you reset the target after painting on the canvas, you’re turning back to the wall, and when you finally draw the canvas on the screen you take the canvas and hang it on the wall.

Oh yes, I’ve forgotten that part. Drawing the surface on the screen. What good is it, if you don’t actually put it somewhere? To do this, you use draw_surface. (there are a few other drawing functions, like draw_surface_stretched, draw_surface_tiled, etc.; however they do the same thing as draw_surface but with more parameters. Just like draw_sprite_ext compared to draw_sprite)

draw_surface must go in the draw event, which is safe because you won’t be messing with the drawing target. Once you’ve drawn on the surface and reset the drawing target, you can draw the surface on the screen however you want, whenever you want. So after the above code, you might place this code in the draw event:

draw_surface(mysurface,objPlayer.x,objPlayer.y-32);

And your surface will be drawn 32 pixels above the player object. All done.

And that’s it. To have some more dynamic effects, you draw different things on the surface and draw it in different ways. You can also create a sprite from a surface using sprite_create_from_surface(), or a background with background_create_from_surface(). Yet even more fancy functions await you in the surfaces section of the GM manual; check it out and start practicing.

As always, feedback welcome. If you happen to spot some mistake or just have a suggestion, drop a comment.

If you enjoyed this article, please consider checking out the rest of the blog.

If you have a technical question, such as “How do I do this” or “this is not working right” (relative to something with your Game Maker game after reading this tutorial), please head over to the Game Maker Community and ask there.  I can’t answer any such questions in this blog and the members at the GMC will be more than capable to help you.  Unfortunately any technical-question-related comments will be deleted without a response.  Any other comments, however, will be welcomed wholeheartedly.  Thanks!

2 Responses

  1. WOOHOOOO

    yay, thanks, now i can use surfaces :D

  2. Very nice. your description of the surfaces (canvas/wall) was great. helped me understand it very easily.

    i can now draw

Comments are closed.