banner



How To Draw One Sprite Over Another In Gamemaker

In the above interactive example you can see some rather neat outlines around the images when you mouse over them. While most of the time in GameMaker you will but want adequately simple outlines this article will by and large look at doing circuitous borders around sprites.

So what am I doing dissimilar?

In GameMaker one of early realisations someone might come to past themselves is how you can draw an outline around something by simply cartoon a sprite 4 times in each direction and colouring those in and ta da! you take an online. Even so after a while you will get-go to encounter some of the limitations of this; y'all tin't do transparent borders, you tin can only do solid colours, you definitely cannot exercise clever animated things, and I'm sure in that location are many other issues y'all might get similar with depth.

What I'm going to do is a clever technique called masking, now I feel obliged to say hither that this is far less efficient than the previous method, nevertheless if you want something more a solid outline this is the best style I tin can think of to do it and as you can see it is running smoothly in the html5 version (which is notorious for performing code very poorly) and I am using masking on 10 objects simultaneously each of which hasn't been optimised then is actually redrawing the whole screen each time rather than only the area around the object (and you are able to code yours more efficiently but for my purposes these are good enough for me)

So what is masking?

For us it is going to exist using a surface to remove parts nosotros don't desire on another surface using draw_set_blend_mode(bm_subtract). Now for those that don't know what a surface is you don't demand to be worried by how complex the GameMaker transmission makes it audio because yous can just encounter it as a sail nosotros tin can draw on and then draw onto the screen merely similar nosotros would a sprite.

If you are new to Masking in GameMaker I accept a guide here.

how does the outline work?

You will run into in my lawmaking I have two surfaces: surfacehole and surfaceoutline. surfacehole is a negative silhouette of the sprite including the border. In my mind I see it to be like a hole dial we will apply to erase annihilation we don't want from surfaceoutline. surfaceoutline is just what nosotros volition draw on the screen nether the original sprite. Sounds easy correct? Well it is, we but need to find out how to make these two surfaces.

How to add an outline (stroke) to sprites in GameMaker, Image Borders
  1. Now this is the but part of my code I don't similar, in order to find out where the location of the edge will be drawn I actually draw the image 8 times offset by a fiddling each time just similar I explained in the unproblematic case, this works well for almost things including putting outlines on text, however if your image is long and fiddley you might observe things poke out in ways you don't expect, of course this tin can be solved by just drawing more than than 8 directions and using lengthdir_x() and lengthdir_y() nonetheless there is the pedantic programmer part of me that dislikes this solution.
  2. Using surface_set_target(surfacehole) we set it so GameMaker draws onto the surface we made and with draw_set_blend_mode(bm_subtract) we brand information technology so when cartoon rather adding to the image nosotros remove that office of the image. This is the bones concept behind masking.
  3. This is where nosotros fill a surface with the image we desire to outline the sprite. To go far easier I have used draw_sprite_tiled(spr_grid,0,x,y) to basically fill the whole surface with a repeated pattern.
  4. We subtract the whole of the hole punch nosotros made in step ii with the prototype we made in step three, making an image that is slightly bigger than the original sprite and filled with the outline we want.

Now all nosotros have to exercise is draw the surface made in step four and then depict the original sprite over the top, now nosotros are washed! Happy days!

And so at present permit's await at the lawmaking to do this, and I call back y'all will be surprised to find its really less code than it took me to explain how it worked.

The Code :

/// Draw Upshot  // For functioning this should be as small equally the epitome you want to draw including the edge  if (! surface_exists(surfacehole)) {surfacehole = surface_create(room_width, room_height); } if (! surface_exists(surfaceoutline)) {surfaceoutline = surface_create(room_width, room_height); }  surface_set_target(surfacehole) /// draw onto the dial out surface  draw_set_blend_mode(bm_subtract) // dont draw prototype merely remove the inverse from what we are drawing onto  draw_clear(c_black) // clear annihilation from the previous frame in case the image is beingness animated   // draw all the sprites on with a little offset to make a border if(distance_to_point(mouse_x,mouse_y) == 0) {     var distance = v     draw_sprite_ext(spr_flower,0,x+distance,y+distance,ane,1,image_angle,c_black,1)     draw_sprite_ext(spr_flower,0,x+distance,y-distance,i,1,image_angle,c_black,ane)     draw_sprite_ext(spr_flower,0,x-distance,y+distance,1,1,image_angle,c_black,1)     draw_sprite_ext(spr_flower,0,ten-distance,y-distance,ane,i,image_angle,c_black,one)          draw_sprite_ext(spr_flower,0,x+(distance*1.four),y,ane,1,image_angle,c_black,ane)     draw_sprite_ext(spr_flower,0,10-(distance*1.4),y,1,i,image_angle,c_black,i)     draw_sprite_ext(spr_flower,0,10,y+(altitude*i.iv),1,1,image_angle,c_black,one)     draw_sprite_ext(spr_flower,0,x,y-(altitude*1.4),ane,1,image_angle,c_black,1) }  // set all the drawing modes back to normal  draw_set_blend_mode(bm_normal)  surface_reset_target();    surface_set_target(surfaceoutline) // make the surface that will go the outline  draw_sprite_tiled(spr_texture,0,10,y) // fill this surface with whatever we want to be displayed   draw_set_blend_mode(bm_subtract) draw_surface(surfacehole,0,0) // dial out everything outside the border  draw_set_blend_mode(bm_normal)  surface_reset_target();  draw_surface_ext(surfaceoutline,0,0,1,i,0,c_white,0.2) draw_self()        

It'southward worth mentioning again that this works in the HTML5 module for GameMaker however does use WebGL so y'all will demand to make sure that you gear up WebGL to required, however I recall its pretty cool to see Masking done in WebGL and HTML5 equally information technology is a really handy technique.

This is a actually great trick you can employ to highlight buttons in GameMaker and outline buttons on mouse over. It will give your game a really polished look.

Some things you might desire to change :

Now the part that everyone is waiting for... How take I done the animated mask in GameMaker? Well that is super like shooting fish in a barrel yous meet the line:

draw_sprite_tiled(spr_texture,0,x,y)

Well you lot tin just modify that to:

outset += 0.iii draw_sprite_tiled(spr_texture,0,x+offset,y+offset)        

Likewise the examples that use a solid color are but:

draw_clear(c_black)

Making the stroke border bigger and smaller; On virtually line 9 you will meet the line var distance = five to brand the outline bigger and smaller y'all can only alter this number, bigger numbers make a bigger border.

Optimisation ane; To make the code easier to read higher up I put it all in the draw event, this works simply actually you should save the draw event to have only the most necessary lawmaking running in it. For example the surface_create(room_width, room_height) should be put in the create event, but if y'all do brand certain that you nevertheless check information technology exists considering as GameMaker says in the manual surfaces are volatile and a devices might remove them from the graphics retentivity when your programme is non being used.

Optimisation ii; Once more to make things easier to read I moved things effectually however I would massively recommend really checking the mouse distance in the step consequence, this makes sense because you might take a game pad or a controller that is really deciding when the stroke should be on and off.

Optimisation 3; I'grand pretty sure it is better to make all these surfaces in the step consequence and then in the describe result all you lot need to do is draw the outline and then the original sprite on pinnacle, once again I didn't practice this because the example at the top runs perfectly smoothly at 60fps.

Optimisation 4; if you have many objects making outlines at the same time I would have an outline object, this object would go through everything that wants an outline using a with() role. This means you can take a huge number of objects drawing outlines onto the aforementioned surface and would be incredibly efficient because y'all are only rendering this outline surface to the screen one time. Magic!

Optimisation 5; The GameMaker Transmission does tell y'all to utilise surface sizes that are powers of two similar: 16, 128, 512, 1024 etc. I never accept and this is might be why I have so many problems with surfaces.

Optimisation 6; Something yous should do is but remake the mask and the surface if something has changed. It would be quite simple to cache it with just a flag saying changed=truthful and I think this volition really assist.

Source: http://www.davetech.co.uk/gamemakeroutlinesprite

Posted by: cartercamestich1950.blogspot.com

0 Response to "How To Draw One Sprite Over Another In Gamemaker"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel