Skip to content
Franklin Webber edited this page Nov 24, 2012 · 12 revisions

Scene

A scene is one of three major concepts in Metro. A scene represents screens, transitions, or stages within the game. A Scene itself coordinates the many actors, events, animations, and actions that are currently on screen.

Overview

A Scene is similar to a Rails Controller.

Scenes are stored in the 'scenes' directory. The template game that Metro generates provides you with several scenes which are subclasses of GameScene. GameScene is a subclass of Metro::Scene. All scenes within Metro must have Metro::Scene as an ancestor.

This is again very similar to how Rails will generate a controller named ApplicationController and all new controllers will be subclasses of it.

An important suggestion is to use the inheritance with care. It is often times much easier to manage inheritance that is wide and shallow (e.g. Lots of subclasses of GameScene) instead of deep.

Creating a Scene

Scenes are not required to reside in the scenes directory. However, it is strongly encouraged to maintain the organization of your code.

Many scenes may also share a single file. However, it is strongly encouraged that you maintain one scene per file.

Manual Creation

A new scene can be created manually simply by saving ruby code that defines a scene to a file.

class DungeonScene < GameScene

end
  • Scene classes often use a common naming convention. Selecting a unique name as a prefix and the word Scene as a suffix. In the above example the word 'Dungeon' is the unique name.

  • The name of the file often matches the scene class name. Except the file name is usually a snake cased version of the CamelCased class name. This is a common convention within Ruby.

Generator

The metro command-line tool provides a generator to help create a new scene that abides by the conventions defined above.

$ metro generate scene new DungeonScene
$ metro generate scene new dungeon_scene
$ metro generate scene new dungeon

Any of the above specified commands will generate the a file at the path scenes/dungeon_scene.rb which contains a class named DungeonScene.

Scene Name

Each scene has a name. By default the name of a scene is a snaked cased version of the unique name prefix of the scene class.

The scene name of the the previously example is dungeon:

class FirstMazeScene < GameScene ; end

The following scene name would first_maze.

Scene names are used throughout your game as references to scenes to prevent the spread of scene classes spread all throughout the code.

  • The first scene of your game that is loaded, specified in your game configuration, uses the name of the scene.

  • The scene name, by default, determines the default view file that it uses.

  • Scene Transitions take the scene name as a parameter.

The name of a scene can be overridden. A custom scene name can be explicitly defined.

The following example defines a custom scene name, which overrides the usual default:

class FirstMazeScene < GameScene
  scene_name :first_labyrinth
end

Methods

A scene has a series of events which are essential to the lifetime of the scene. These methods are defined as placeholder methods in the Scene superclass. This allows you to redefine only the necessary methods in your scene.

This method is executed immediately after the initial initialize code is completed. A scene, however, is not yet visible and does not yet have the to draw, calculate layouts, or access any model object that requires the use of the window.

As Scene does a lot of work for you with regarding to setting up content, it is best not to override initialize and instead define an after_initialize method within the subclasses of Scene.

This method is called right after the scene has been adopted by the window.

This is often the method where you have access to all available resources. This is an ideal location for you to complete any initialize that requires model objects to establish relationships with each other, start playing music, or for models to generate or create any necessary sub-models.

This is called every update interval while the scene is being shown.

This is the method where you would define your core game logic that needs to happen on each update.

base_update is actually called first, which in turn calls update. This is done so that Metro can perform automatically perform the update operations for animations or existing models defined in the scene. If you need to override all existing behavior, you may want to redefine base_update.

This is called after every update and when the OS wants the window to repaint itself.

This is the method where you would define any custom drawing code that happens in your scene.

base_draw is actually called first, which in turn calls draw. This is done so that Metro can perform automatic drawing of existing models defined in the scene. If you need to override all existing behavior, you may want to redefine base_draw.

This is called during a scene transition event. After the scene transition event has been initiated, this method will be called for the current scene. This happens immediately before prepare_transition_to(old_scene) is called.

Before a scene is transitioned away from to a new scene, this method is called to allow for the scene to complete any tasks, stop any actions, or pass any information from the existing scene to the new scene that is about to replace it. The new_scene parameter is the scene that is about to replace the existing scene.

This is called during a scene transition event. This is called immediately following the call to prepare_transition_to(new_scene).

The new scene, which is about to replace the current scene, is the receiver of this call. Before this scene is transitioned to the current visible scene is passed to this new scene. This allows for the new scene to retrieve any data from the previous scene to assist with the layout of the current scene.

A scene is able to respond to events. These events could be generated from keyboard, mouse, or gamepad input. They may also be custom notifications generated by other models within the current scene.

A scene's ability to register and respond to events is because a Scene includes the module HasEvents which extends the ClassMethods.

Defining Models

A scene has a number of helper methods (draw, draws, and play) that allow you to quickly add models within the scene.

A scene's ability to register models is because a Scene includes the model Draws which extends the ClassMethods.

The draw class method within a scene allows you to define a model to draw. This instance of the model is often referred to an as an actor. The definition within a scene is simply a hash which contains all the parameters you wish to define.

class HellScene

  draw :title, model: 'metro::ui::label',
    text: 'Welcome To Hell!',
    position: "320,240,0",
    color: "rgba(255,255,255,1.0)"

end

The first parameter is the name of actor. The hash of parameters that follow the actor name describe important characteristics about what model the actor is based on and the important details of that should be presented.

  • model is one of the core models provided with Metro.
  • text is the text that appears within the label.
  • position describes the location of the upper-left point of the label.
  • color is the color represented as a web color string.

By stating that this scene draws the following 'metro::ui::label' it will automatically add this actor, in the update loop and draw loop. A 'metro::ui::label' is a simple model so it performs no action when its update method is called. It does love to draw itself and will generate text to the screen which reads 'Welcome To Hell!'.

Optional Model Parameter

If you do not provide a model, Metro will try to match the name of the actor against the names of all the models that it knows. In the following case a hero is drawn with the Hero model:

class HellScene
  draw :hero
end

class Hero < Metro::Model
  # details that define a hero
end

The play class method within a scene allows you to define song. This is similar to the draw class method, except it is assumed that you are creating a 'metro::audio::song' so you do not specify a model.

class HellScene
  play :theme, song: 'title.ogg', volume: 0.2
end

This is functionally equivalent to defining it with the draw method:

class HellScene
  draw :theme, model: 'metro::audio::song', song: 'title.ogg', volume: 0.2
end

Using a View to define your Models

By default your Scene automatically has an associated view file based on the name of the scene. The name of a scene's view can also be overridden.

The view file allows you to define numerous actor details in another location.

Previously we defined the 'Hell' Scene which defined a title label with a lovely welcome message.

class HellScene

  draw :title, model: 'metro::ui::label',
    text: 'Welcome To Hell!',
    position: "320,240,0",
    color: "rgba(255,255,255,1.0)"

end

We can also move this content to the Hell Scene's view file hell.yaml:

title:
  model: metro::ui::label
  text: Welcome To Hell!
  position: "320,240,0"
  color: "rgba(255,255,255,1.0)"

We can redefine our Hell Scene more succinctly:

class HellScene
  draw :title
end
  • Parameters, for an actor, can be defined in both the scene and the view
  • Parameters defined for an the actor, within the scene, will override the parameters defined for an actor in the view.

Animations

Clone this wiki locally