Difference between revisions of "Sprites"

From Open Surge Engine Wiki
Jump to: navigation, search
m (Modifying the battery sprite)
m (Get ready for action: the Action Spot)
 
(12 intermediate revisions by the same user not shown)
Line 111: Line 111:
  
 
Now that we understand how the engine reads these files, it is easier to know what input we need to give it in order for our sprites to be displayed correctly.
 
Now that we understand how the engine reads these files, it is easier to know what input we need to give it in order for our sprites to be displayed correctly.
 +
 +
=== Try it yourself! ===
 +
 +
As an exercise, write a sprite definition for the spritesheet below. You'll need an image editor to extract the coordinates. If you don't have one, [https://www.gimp.org GIMP] is a popular choice.
 +
 +
[[File:Rings.png|512px|thumb|none|Save it to images/my_rings.png]]
  
 
== Modifying sprites The Right Way™ ==
 
== Modifying sprites The Right Way™ ==
Line 116: Line 122:
 
=== Overriding sprites ===
 
=== Overriding sprites ===
  
While it's tempting to modify the sprites simply by editing the original .spr files that are shipped with Open Surge (due to the simplicity of the process), this introduce an issue: you'll lose your changes as soon as you [[Upgrading the engine|upgrade the engine]]. Not only that: you'll also lose the original sprite.
+
While it's tempting to modify the sprites simply by editing the original .spr files that are shipped with Open Surge (due to the simplicity of the process), this introduce an issue: you'll lose your changes as soon as you [[Upgrading the engine|upgrade the engine]]. Not only that: you'll also lose the original sprites.
  
 
Open Surge version 0.5.2 introduced a special folder, '''sprites/overrides/'''. Sprites defined in this folder override sprites defined elsewhere.
 
Open Surge version 0.5.2 introduced a special folder, '''sprites/overrides/'''. Sprites defined in this folder override sprites defined elsewhere.
Line 137: Line 143:
 
'''Note:''' feel free to create subfolders at will. We can store our modified collectibles.spr in sprites/overrides/items/, and it will work just as well.
 
'''Note:''' feel free to create subfolders at will. We can store our modified collectibles.spr in sprites/overrides/items/, and it will work just as well.
  
== Try it yourself! ==
+
== Transitions between animations ==
  
As an exercise, write a sprite definition for the spritesheet below:
+
Since Open Surge 0.6.0, it's possible to create transitions between animations. Transitions are animations that play automatically when the engine detects that a particular sprite has changed from one animation to another. Example: by holding the "up" key when standing, the player will look up. By releasing the "up" key, the player will no longer look up and will be standing again. You may want to play an additional animation between looking up and standing, so that there is a smooth transition in between.
  
[[File:Rings.png|512px|thumb|none|Save it to images/my_rings.png]]
+
The syntax of a transition is similar to the syntax of an animation. When defining a transition, you will specify two numbers: '''from''' and '''to'''. In the example below, we declare a transition that will be played as soon as the player stops looking up and goes back to standing mode:
 +
 
 +
// Suppose that looking up corresponds to animation 5
 +
// and that standing corresponds to animation 0
 +
 +
// from looking up to standing
 +
transition 5 to 0
 +
{
 +
    repeat      FALSE
 +
    fps        16
 +
    data        20 21
 +
}
 +
 
 +
We set '''repeat''' to FALSE because it doesn't much make sense to set it otherwise. Other fields are familiar. Additionally, you may use the '''any''' wildcard to specify transitions to any other user-defined animations:
 +
 
 +
transition 10 to any
 +
{
 +
    // ...
 +
}
 +
 
 +
If you find yourself needing to specifying a transition ''from'' '''any''' to a particular animation, simply set the initial frames of that particular animation instead of defining a transition. You cannot specify a transition from '''any''' to '''any''', nor a transition from a particular animation to itself.
 +
 
 +
== Get ready for action: the Action Spot ==
 +
 
 +
The concept of action spot was introduced in Open Surge 0.6.0. The action spot is a point of the sprite that can be used for purposes that are specific to your game. If the sprite appears flipped, rotated or scaled in the game, the action spot will be flipped, rotated or scaled accordingly. Use this feature to specify things such as: the point where the player should hold a vine, the point where a projectile should come out of a gun, and so on.
 +
 
 +
The action spot can be specified for the entire sprite or per individual animations (just like the hot spot) and can be accessed via SurgeScript. The example below shows how both the hot spot and the action spot can be specified for a sprite:
 +
 
 +
// The Power Pluggy will hold the player at the action spot
 +
sprite "Power Pluggy"
 +
{
 +
    source_file    "images/items/power_pluggy.png"
 +
    source_rect    256 32 160 160
 +
    frame_size      160 32
 +
    hot_spot        16 16
 +
    action_spot    152 16
 +
 +
    animation 0
 +
    {
 +
        repeat      TRUE
 +
        fps        12
 +
        data        0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 2 1
 +
    }
 +
}
 +
 
 +
[[File:Power_pluggy_spots.png|480px|thumb|none|Power Pluggy by Alexandre]]
 +
 
 +
Let's see it in action ;)
 +
 
 +
[[File:Power_pluggy_example1.png|426px|thumb|left|Power Pluggy in action!]] [[File:Power_pluggy_example2.png|426px|thumb|none|See how it rotates?]]
  
 
[[Category:MODs]]
 
[[Category:MODs]]
 
[[Category:Sprites]]
 
[[Category:Sprites]]

Latest revision as of 19:36, 15 October 2022

Introduction

All objects with an animation are referred to as sprites. Consider a picture sheet with all the frames needed to be displayed in an animation. In Open Surge, a sprite is composed by two things:

  • A picture sheet (also known as spritesheet), usually in the .png format. These files are placed in the images/ folder.
  • A .spr file, which is a text file telling the engine how to display the sprite. These files are placed in the sprites/ folder and they can be opened with any simple text editor like Notepad.

All picture sheets have a transparent color. They differ between games, but Open Surge uses magenta (RGB 255,0,255) as transparent. Since Open Surge 0.5.0, RGBA 0,0,0,0 can also be used as transparent.

How to create and modify sprites

The battery sprite

We'll learn by example. Consider the following spritesheet:

Collectibles by svgmovement

Batteries are used as collectible elements in the game.

Let's see how Open Surge reads data from your images so that it can be displayed in-game. We will look at the corresponding sprite file (.spr) included with the game.

...

// Collectible
sprite "Collectible"
{
    source_file     "images/collectibles.png"
    source_rect     0 0 304 16
    frame_size      16 16
    hot_spot        8 12

    // spinning
    animation 0
    {
        repeat      TRUE
        fps         16
        data        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    }

    // disappearing
    animation 1
    {
        repeat      FALSE
        fps         8
        data        16 17 18
    }
}

...

In the above file, there are several things you will notice:

  • There are lines that begin with //. These lines are there merely for your convenience and are ignored by the engine.
  • sprite "Collectible": This is what this definition is called. You must make sure that no two sprites have the same name.
  • source_file: This is where the image you are reading from is located. The engine assumes that images are located somewhere in the game directory folder, so you do not need to specify the full file path. Instead, you just have to specify where the images are located in the game folder.
  • source_rect: The first two numbers give the X and Y coordinate, respectively, of the top left corner of the image you are defining. The second two numbers, width and height, respectively, give how big of a rectangle it would take to completely enclose every frame of the animation. These numbers are given in pixels. You can get them with an image editor such as GIMP.
  • frame_size: Defines the size of each frame of your animation. In this example, the size of the source rectangle is 304 by 16 pixels, but each piece of the animation is only 16 by 16 pixels.
  • hot_spot: Every object in the engine has a X and a Y position in the screen, but is this spot its top-left corner? Or maybe its center? This is the place which the engine will use to determine the x and y position of your object. It also is the place where the level editor grabs your object when you select it. There are different reasons for placing hotspots in different places, however it is mostly a matter of preference. The hot spot also performs an important role in objects that are flipped or rotated in the game.
  • animation <NUMBER>: These are the animations your object can perform. Assuming that your object has N animations, <NUMBER> must vary from 0 to N-1. For example, if you're creating an object with five animations, you would need to specify animation 0, animation 1, ... and animation 4. There are three different things that animations need to be fully defined:
    • repeat: this tells the engine if you want it to keep doing the animation as long as it is the selected one. In this case, while the collectible is standing still it will continuously spin because repeat is set to TRUE in animation 0. However, when the active animation changes to 1 (when a player touches it), it will play the animation only one time before disappearing.
    • fps: This defines how fast the engine will cycle through your frames. In this case it plays 16 frames every second for animation 0 and 8 frames per second for animation 1. The higher the fps, the faster the animation.
    • data: This defines which frame you want to play at any particular moment. In this case it plays frames 0-7 and then repeats under animation 0, and plays frames 8-10 and doesn't repeat under animation 1.

Note: you may also define different values of hot_spot in different animation blocks, but that is optional.

Modifying the battery sprite

Now that we've examined a sprite file and determined what each of the components do, we'll modify it so that we replace the batteries in the game with our collectibles.

Warning: Changing sprite files makes a major change to the game. Make sure to backup your sprite files before you change them, so if something goes wrong, you will be able to restore the original functionality to the game. Read below for a better way to do it.

images/my_collectibles.png (art by lunarrush)

We'll now edit sprites/items/collectibles.spr and modify the Collectible sprite:

// Collectible
sprite "Collectible"
{
   source_file     "images/my_collectibles.png"
   source_rect     1 1 176 16
   frame_size      16 16
   hot_spot        8 12
   
   // idle
   animation 0
   {
       repeat      TRUE
       fps         16
       data        0 1 2 3 4 5 2 6
   }
   
   // end
   animation 1
   {
       repeat      FALSE
       fps         8
       data        7 8 9 10
   }
}

Here are some things you should notice right off the bat:

  • sprite "Collectible", located at the top, remains the same. We're defining a sprite whose name is Collectible.
  • The source_file is different. This is because we have created a new image and it has a different file name than the original.
  • The source_rect is different, since the frames of the new sprite are at a different places inside the new image than the originals were.
  • The frame_size is the same. We have used a standard size rectangle to create our collectibles, so that they can seamlessly replace the built-in ones.
  • The hot_spot is the same. This is because we didn't see any need to change this from what it already was.
  • The animation <NUMBER> lines are the same. As in the original sprite, animation 0 specifies the spinning animation and animation 1, the disappearing one.
    • The repeat entries are set to the same values, since the modified sprite acts in a similar way compared to the original one.
    • The fps values are the same. This could be modified if we wanted to speed up or slow down the animation.
    • The data values are different. This is because the frames of our modified sprite must be presented in a different order to be a complete animation.
  • Different lines that start with //. These are comments. Although they are ignored by the computer, they help us to keep track of things. They aren't required, but they are helpful.

Now that we understand how the engine reads these files, it is easier to know what input we need to give it in order for our sprites to be displayed correctly.

Try it yourself!

As an exercise, write a sprite definition for the spritesheet below. You'll need an image editor to extract the coordinates. If you don't have one, GIMP is a popular choice.

Save it to images/my_rings.png

Modifying sprites The Right Way™

Overriding sprites

While it's tempting to modify the sprites simply by editing the original .spr files that are shipped with Open Surge (due to the simplicity of the process), this introduce an issue: you'll lose your changes as soon as you upgrade the engine. Not only that: you'll also lose the original sprites.

Open Surge version 0.5.2 introduced a special folder, sprites/overrides/. Sprites defined in this folder override sprites defined elsewhere.

If you want to modify a sprite that is shipped with Open Surge, do not modify its .spr file directly. If you do so, you'll lose your changes as soon as you upgrade the engine. Instead, copy the file you want to modify into sprites/overrides/ and modify YOUR COPY instead. Files stored in this folder won't be overwritten when upgrading the engine.

When modifying a sprite, do not edit the original image files that are shipped with Open Surge. Instead, make a copy and edit YOUR COPY. This helps you keep your changes if you upgrade the engine.

Modifying the battery sprite The Right Way™

When modifying the battery sprite above, we edited file sprites/items/collectibles.spr directly. We will no longer do this. Instead, we will copy the original file that is shipped with Open Surge into sprites/overrides/collectibles.spr. Next, we will edit sprites/overrides/collectibles.spr. Notice the following:

  • File sprites/items/collectibles.spr is the original sprite definition that is shipped with Open Surge, totally unchanged
  • File sprites/overrides/collectibles.spr is your modification
  • File images/collectibles.png is the original spritesheet that is shipped with Open Surge, totally unchanged
  • File images/my_collectibles.png is your modification

We now have two .spr files defining the same sprite, "Collectible". Since sprites defined in sprites/overrides/ take precedence over sprites defined elsewhere, the engine will display your modification. When you upgrade the engine, your modification will be kept.

Note: feel free to create subfolders at will. We can store our modified collectibles.spr in sprites/overrides/items/, and it will work just as well.

Transitions between animations

Since Open Surge 0.6.0, it's possible to create transitions between animations. Transitions are animations that play automatically when the engine detects that a particular sprite has changed from one animation to another. Example: by holding the "up" key when standing, the player will look up. By releasing the "up" key, the player will no longer look up and will be standing again. You may want to play an additional animation between looking up and standing, so that there is a smooth transition in between.

The syntax of a transition is similar to the syntax of an animation. When defining a transition, you will specify two numbers: from and to. In the example below, we declare a transition that will be played as soon as the player stops looking up and goes back to standing mode:

// Suppose that looking up corresponds to animation 5
// and that standing corresponds to animation 0

// from looking up to standing
transition 5 to 0
{
    repeat      FALSE
    fps         16
    data        20 21
}

We set repeat to FALSE because it doesn't much make sense to set it otherwise. Other fields are familiar. Additionally, you may use the any wildcard to specify transitions to any other user-defined animations:

transition 10 to any
{
    // ...
}

If you find yourself needing to specifying a transition from any to a particular animation, simply set the initial frames of that particular animation instead of defining a transition. You cannot specify a transition from any to any, nor a transition from a particular animation to itself.

Get ready for action: the Action Spot

The concept of action spot was introduced in Open Surge 0.6.0. The action spot is a point of the sprite that can be used for purposes that are specific to your game. If the sprite appears flipped, rotated or scaled in the game, the action spot will be flipped, rotated or scaled accordingly. Use this feature to specify things such as: the point where the player should hold a vine, the point where a projectile should come out of a gun, and so on.

The action spot can be specified for the entire sprite or per individual animations (just like the hot spot) and can be accessed via SurgeScript. The example below shows how both the hot spot and the action spot can be specified for a sprite:

// The Power Pluggy will hold the player at the action spot
sprite "Power Pluggy"
{
    source_file     "images/items/power_pluggy.png"
    source_rect     256 32 160 160
    frame_size      160 32
    hot_spot        16 16
    action_spot     152 16

    animation 0
    {
        repeat      TRUE
        fps         12
        data        0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 2 1
    }
}
Power Pluggy by Alexandre

Let's see it in action ;)

Power Pluggy in action!
See how it rotates?