Backgrounds

From Open Surge Wiki
Jump to: navigation, search

Definition

In Open Surge a background is composed of two parts: the background script, and the background image.

The background image contains all the visual elements of the background, while the background script contains the definitions of the background such as dimensions, layers, and behaviors.

A background image is nothing without the script, even if you want to have a static background. There is a very simple reason for this. Even though making a static background looks easy as 123, the very same static background can be assembled in hundreds of different ways just by specifying different source points for the image, layering the background parts differently, or even by playing around with the scrolling speeds.

So, to summarize it, the most basic elements of a background are:

  • The background image (an image in .PNG format contained in the images folder of open surge)
  • the background script (a plain text file with extension .BG contained in the themes folder of open surge)

My first background

Starting a background script

Assuming you have already chosen an image for your background, we will use the one below as reference:

images/sunshinesky.png (design by KZR)

Now open your text editor, start a new file, and you may want to add this to the start:

// Open Surge Background
// by User001
// Background theme for My Zone
// OS Version: x.x.x

The // is the symbol that notes a line as a comment, and this means the engine will not read this line, as it is only meant to inform you, "the creator", or other people, "the modders", of important details about the background script.

Having this at the start of the file informs:

  • line one tells us this file is an open surge background.
  • line two tells us who created this file.
  • line three tells us what this background file was made for.
  • line four tells us which version of the game we need.

Also, if you are editing someone else's file, you should also add:

// Modified by user002

and this is what we call a header, even though this is a very simple one with only comments and no commands.

Simple background

Now that you are done with the header, you can leave some empty paragraphs, then start the very first layer.

Once again, the // symbol is useful here to help you identify which layer represents a certain part of the image.

This is an example of a code block for a background layer

// sky 
background
{
   initial_position    0 -64
   scroll_speed        -0.01 0
   behavior            DEFAULT
   repeat_x            TRUE
   repeat_y            TRUE
   zindex              0.2
	
   sprite
   {
       source_file     "images/sunshinesky.png"
       source_rect     0 0 768 192
       frame_size      768 192

       animation
       {
           repeat      TRUE
           fps         1
           data        0
       }
   }
}

Each background { ... } block represents a layer. You can have one or more layers per background script. In this example, we only have one layer.

So you start the first line with the word "background", so the engine knows it will create a background, and it will add the properties below.

The { and } symbols open and close a statement. The statement is a block of commands and parameters, and there can be statements inside statements, like when the Sprite is declared.

Attention: you should always respect the structure shown in the example. Misplaced { } will make your background unable to load.

A more advanced background script

// Open Surge Background
// by Mateus Reis
// Background theme for Dark Forest Prototype

// sky 0
background
{
   initial_position    0 0
   scroll_speed        0 0
   behavior            DEFAULT
   repeat_x            TRUE
   repeat_y            true
   zindex              0

   sprite
   {
       source_file     "images/darkforestsky.png"
       source_rect     0 0 16 16
       frame_size      16 16

       animation
       {
           repeat      TRUE
           fps         1
           data        0
       }
   }
}


// sky 1
background
{
   initial_position    0 128
   scroll_speed        -0.0 -0.04
   behavior            DEFAULT
   repeat_x            TRUE
   repeat_y            FALSE
   zindex              0.1
	
   sprite
   {
       source_file     "images/darkforestsky.png"
       source_rect     0 0 768 256
       frame_size      256 256

       animation
       {
           repeat      TRUE
           fps         15
           data        0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2
       }
   }
}

// mountains 1
background
{
   initial_position    0 160
   scroll_speed        -0.10 -0.04
   behavior            DEFAULT
   repeat_x            TRUE
   repeat_y            FALSE
   zindex              0.2
	
   sprite
   {
       source_file     "images/darkforestbg.png"
       source_rect     0 0 640 256
       frame_size      640 256

       animation
       {
           repeat      TRUE
           fps         8
           data        0
       }
   }
}

// riverside forest 1
background
{
   initial_position    0 384
   scroll_speed        -0.30 -0.05
   behavior            DEFAULT
   repeat_x            TRUE
   repeat_y            FALSE
   zindex              0.5
	
   sprite
   {
       source_file     "images/darkforestbg.png"
       source_rect     0 256 640 288
       frame_size      640 288
       animation
       {
           repeat      TRUE
           fps         8
           data        0
       }
   }
}

// rain 1
background
{
   initial_position    0 0
   scroll_speed        10 20
   behavior            linear -50 150
   repeat_x            TRUE
   repeat_y            true
   zindex              1

   sprite
   {
       source_file     "images/rain.png"
       source_rect     0 0 64 64
       frame_size      64 64
       animation
       {
           repeat      TRUE
           fps         8
           data        0
       }
   }
}

// rain 2
background
{
   initial_position    0 0
   scroll_speed        15 25
   behavior            linear -100 200
   repeat_x            TRUE
   repeat_y            true
   zindex              1

   sprite
   {
       source_file     "images/rain.png"
       source_rect     0 0 64 64
       frame_size      64 64
       animation
       {
           repeat      TRUE
           fps         8
           data        0
       }
   }
}

Used Images:

rain.png

Rain.png

darkforestbg.png

Darkforestbg.png

darkforestsky.png

Darkforestsky.png

TODO

Explanation needed.

Command reference

initial_position

Syntax: initial_position x-position y-position

Receives two parameters: X position and Y position. both counting from the top left edge of the level. higher X values mean to the right, higher Y values mean downwards.

scroll_speed

Syntax: scroll_speed x-speed y-speed

Receives two parameters: X speed and Y speed. Positive values mean the background will be moving in the same direction you are, which looks unnatural, but can be used to create a different effect. Negative values scroll the background in the opposite direction of movement, which is how things work in real life.

If the (horizontal or vertical) speed is close to zero, then the layer becomes very slow (good for distant backgrounds). If it's not close to zero, then it gets faster. If the number is negative, then it moves in the opposite direction of the camera (useful on most cases). If the number is positive, then it moves in the same direction of the camera (which would be very strange in most cases). Finally, if the horizontal (vertical) speed is zero, then it doesn't move horizontally (vertically).

behavior

Syntax: behavior behavior_name [behavior_parameter1 [behavior_parameter2 ... [behavior_parameterN] ... ]]

Receives one or more parameters.

Available behaviors are:

  • DEFAULT
    • Syntax: DEFAULT
    • Description: this default behavior is meant to only scroll the background on player movement.
  • LINEAR
    • Syntax: LINEAR x-speed y-speed
    • Description: this behavior makes the background scroll with constant speed, in addition of camera or player movements. x-speed and y-speed are given in pixels per second.
  • CIRCULAR
    • Syntax: CIRCULAR x-amplitude y-amplitude x-speed y-speed [x-initialphase [y-initialphase]]
    • Description: this behavior makes the background describe a circular or elliptical movement. The center of the movement is the position of the background. x-amplitude and y-amplitude are given in pixels; x-speed and y-speed, in cycles per second, and x-initialphase and y-initialphase are optional parameters ranging from 0 to 359, inclusive (the default value is zero).

repeat-x

Syntax: repeat-x VALUE

VALUE is TRUE if the layer must be repeated horizontally, or FALSE otherwise.

repeat-y

Syntax: repeat-y VALUE

VALUE is TRUE if the layer must be repeated vertically, or FALSE otherwise.

sprite

The sprite section in a background { ... } block is used to tell the game engine how the layer looks like graphically. Refer to: Sprites

zindex

Syntax: zindex VALUE

VALUE is a number between 0 and 1 (inclusive) specifying the order in which background layers must be rendered. Layers with higher z-index will be rendered after layers with lower z-index.

If no zindex property is specified, the order in which the layers are rendered (printed to the screen) are given according to the order of their declaration in the .bg file. However, you can change this behavior by specifying a zindex value. If no zindex is declared, layers have zindex equal to zero.

Let's see an example:

  • Let A, B, C and D be layers with z-indexes equal to 0.0, 0.5, 0.7 and 1.0, respectively.
  • Then, layer A will be displayed behind layer B, which will be displayed behind layer C, which will finally be displayed behind layer D.
  • This would be the same as declaring A, B, C and D in alphabetical order in the .bg file, but there's more: layers with zindex greater than 0.5 are foregrounds - they are rendered after other level elements like bricks, items and the player itself.
    • This means that layers C and D are foregrounds, while A and B are regular backgrounds.

You don't need to know this, but in case you're curious, the position of a layer with no attached movement behaviors in the screen is given by:

xpos = initial_xpos + topleft_xpos * speed_x
ypos = initial_ypos + topleft_ypos * speed_y

Where topleft is the position of the top-left corner of the screen related to the level. If you're making a foreground, these formulas can be useful to know where you should position your layer.