GM Studio
Home Up GM Studio GM 8.1

 

Automatic sprite group assignment

GM Studio update: The technique described here has been tested in GM Studio 1.0 as of June 2015.

A programming technique for GM Studio 1.0 that allows a group of sprites to be assigned to an object by assigning the first sprite of the group to the object and giving the following sprites in the set special names

In certain types of game (platform game) an object may use one of a number of sprites depending on its movement direction, or other game events. A player in Super Bouncy Ball consists of nine sprites. These are standing still, moving, jumping and squashed facing right and left, plus an additional facing forward sprite used to indicate the active player. There are multiple player objects each needing a different set of sprites. In games where an object only has one sprite it is easy to create other copies or descendants of the object with a different sprite. Where an object uses multiple sprites the sprite names are usually hard-coded into events, making them difficult to change.

Other game types benefit as well as platform games. Many games feature objects that can rotate. It used to be considered difficult to have rotation and animation in the same object (although now that sprites can be drawn rotated it is not quite such an issue). It has been demonstrated that rotation and animation can be combined by using an array of sprites such that the multiple images of the sprites contain various rotations and the series of sprites contain successive frames of animation (used in water panic), or each sprite may be fully animated at one rotation so that the series of sprites contains a full rotation (used in the curve platform demo).

This technique may not be compatible with Studio 2.0 when it appears as it depends on the sprite name string being available at runtime, and this is information that is usually discarded when a program is compiled. The function "asset_get_index" is not available in the older GM HTML5 version that preceded Studio. In GM8.1 the same functionality may be achieved by "execute_string".

Automating sprite group assignment:

Firstly the sprites need to be named in a specific way.

Sprites organised in folders A spriteset.

There is one master sprite, then all the sub-sprites have the same name but with suffixes added.

The other player sets (shown as groups) have different names but the same suffixes.

Note that in this implementation I haven't actually used the master sprite except as a placeholder, but in this demo it is the same image as "stand left" and could be used as that.

In the constructor* create event of the player object there is the following code:

//auto_sprite code
//takes name of object's sprite and adds suffixes
//to fill a spriteset
var name;
name=sprite_get_name(sprite_index)
stand_right=asset_get_index(name+"_s_r")
stand_left=asset_get_index(name+"_s_l")
walk_right=asset_get_index(name+"_m_r")
walk_left=asset_get_index(name+"_m_l")
jump_right=asset_get_index(name+"_j_r")
jump_left=asset_get_index(name+"_j_l")
squash_right=asset_get_index(name+"_sq_r")
squash_left=asset_get_index(name+"_sq_l")

 

In the object information dialog box we set the sprite to the master sprite for that player. The "execute_string" commands fill all the variables with the appropriate sub-sprites. To assign a different player sprite set we only have to change the master sprite to an alternative.

Note that each master sprite must be accompanied by a set of correctly named sub sprites. This is about automatic sprite assignment, not automatic sprite generation (though I may cover this someday).

Assigning a sprite group to an array

Things get more fun with arrays.

In my "curve_platform" demo I had a number of sprites representing the player in different orientations. If the player runs at a curving surface they stay on it and can even run up walls and along the underside of platforms. 

In this demo I use arrays to store the sprites. By using arrays I avoid the need to have lots of "If" or "switch" constructs to determine which sprite to use. The arrays still need to be filled though and the brute force method is not fun:

rn[0,0]=run_l0
rn[0,1]=run_l1
rn[0,2]=run_l2
rn[0,3]=run_l3
rn[0,4]=run_l4
rn[0,5]=run_l5
rn[0,6]=run_l6
rn[0,7]=run_l7
This is only part of the original create code, the full code is nearly three times the length since it includes sprites for running facing left and right in many orientations, and sprites for walking, jumping and standing still.

A better way would be to fill the arrays using loops. To allow this I rename the sprites using numbers to represent the actions and orientations as follows:

Sprites organised in folders For clarity I've only expanded the left hand set of running sprites. The right hand set are in the folder run_r. I have numbered them this time.

The first digit is the facing direction. 0 represents left and 1 represents right.

The second digit is 0 for standing and 1 for walking

In the running sprites the second digit gives the orientation. an orientation of zero means moving to the right so in the left hand set sprite play_run_00 is running on the ceiling.

The code to fill arrays with that lot is as follows:

//auto_sprite code
//takes name of object's sprite and adds suffixes
//to fill a spriteset
var name,d,n;
name=sprite_get_name(sprite_index)
for (d=0;d<=1;d+=1)
{
  for (n=0;n<=1;n+=1)
  {
    walk_sp[d,n]=asset_get_index(name+"_"+string(d)+string(n))
  }
  for (n=0;n<=7;n+=1)
  {
    run_sp[d,n]=asset_get_index(name+"_run_"+string(d)+string(n))
  }
  
}

That's it, it sets up the array walk_sp with the regular sprites and run_sp with all the rotated sprites. I can substitute the sprite-set easily provided the replacement set is suffixed the same way as the original set.

Footnote:

I am aware that GM Studio has made it a lot easier to do top down games with rotation, however you may want to use pre-rendered lighting effects on your sprites or a projection that isn't totally top down, in which case you will still need rotated sprites.

Further footnote

Often it is possible to think of the create and destroy events as being equivalent to the constructor and destructor in object oriented programming. Under GM Studio they are called reliably in almost all cases with the exception of the save and load game keys.