Skip to content
This repository has been archived by the owner on Nov 10, 2018. It is now read-only.

Making your First Game

Jonathan Crockett edited this page Nov 9, 2018 · 4 revisions

Making your First Game

This guide will first walk you through the basics of RSauce, and then apply those basics to making a simple game.

The Entity Component System

RSauce uses a game design pattern known as an Entity Component System. An Entity Component System is an easy way to create complicated systems of entities without keeping track of complicated class "trees." Why is this so useful? Say you are designing an entity that represents a normal platform block, a-la Super Mario Brothers. You can walk on it, and if the player collides with it from underneath, it shatters, but you cannot pass through it from the sides; let's call this behavior. Most people who are familiar with Java and Object Oriented Programming will jump to making a Class for this, called Block which encapsulates this behavior. Let's say you also have enemies that perish if the player collides with them from above, but will kill the player if he collides from either side or underneath, also an example of behavior, and you make a class for that as well, called Enemy. This is straightforward enough, but what happens if you want to make an entity that seems like a block but is an enemy in disguise? You can't subclass both Block and Enemy, and each of those classes require common code that represents their respective behavior, so you cant make them interfaces. Any other solution to this would needlessly complicate your class tree.

So this is what the Entity Component System is for.

Entities and Components

In the Entity Component System, an Entity is just nothing more than a "box" of Components. A Component is nothing more than a completely abstract type that just represents some kind of property of the Entity, like position or velocity.

Engine is a singleton class, to get the current instance of Engine:

Engine engine = Engine.getEngine();

To add an Entity to the Engine:

Entity ent = new Entity;
engine.add(ent);

To give the Entity a sprite and position, use DrawComponent. DrawComponent is a Component built right into RSauce. Like other components, DrawComponent implements the Component interface. It has a constructor:

new DrawComponent(Graphic graphic, int x, int y, int z);

graphic represents the graphical asset (See the "Assets" section) that will be displayed at position x and y in the Scene. Let's use a Sprite for this. Let's call this already created Sprite entSprite for now:

DrawComponent drawComp = new DrawComponent(entSprite, 100, 100, 0);
ent.addComponent(drawComp);

The last argument, z represents the depth at where the Entity will be drawn. Entities with DrawComponent with a greater z will be drawn on top, and vice versa. Each Entity can only have one of any type of Component. If you try to add another DrawComponent to ent, it will replace the old one.

If you want to remove a Component from an Entity, use the respective class type:

ent.removeComponent(DrawComponent.class);

to remove an Entity from the Engine however, you'll need the actual Entity itself:

engine.removeEntity(ent);

Like DrawComponent, you can create your very own components by implementing the Component interface. Components don't usually do anything by themselves however, They are meant to be acted on by a System, but to understand Systems, we first have to understand the game loop.

The Game Loop

The game loop has 4 steps, "step", "pre-draw", "draw", and "post-draw", which are executed in that order. Most of the time, you'll only be concerned with two of those steps, "step" and "draw" (pre- and post- draw are just the steps that draw the background and foreground layers respectively, which will be discussed later in this guide).

A System is an Object that can be added to the Engine, just like entities, and are used to define the logic of your game as it's executed each frame. Subclasses of System have 3 methods to implement. addedToEngine() and removedFromEngine() are executed when the System is added or removed from the Engine, and update() is called by the Engine once per frame.

Unlike Entity, you cannot subclass System directly, but must instead subclass StepSystem or DrawSystem. The only difference between the two is exactly when their update() methods are called in the game loop. You'll be using StepSystem for most logic in the game, but keep in mind the "step" event occurs before all the "-draw" events, so if you try to draw anything in a StepSystem, it will probably get overwritten by the draw event. Use DrawSystem to draw things.

Here is an example of a vague StepSystem, note the superclass constructor:

public class MyStepSystem extends StepSystem{
    public MyStepSystem() {
        super(0); // Superclass constructor required. It takes an int which sets the priority value
    }

    @Override
    public void addedToEngine(Engine engine) {
        // This method is executed when this system is added to the Engine,
        // Use this time to set up and/or load your resources needed in update()
    }

    @Override
    public void update(double delta) {
        // Because this is a StepSystem, this method is executed during the step event.
        // "delta" is a value that represents the time, in seconds, since the last frame.
    }

    @Override
    public void removedFromEngine(Engine engine) {
        // This method is executed when this system is removed from the Engine,
        // Use this time to dispose of resources to avoid memory leaks.
    }
}

To add this System to the Engine:

StepSystem sys = new MyStepSystem();
engine.add(sys);

Like Component types in an Entity, there can only be one of any type of System in the Engine. If I try to add another MyStepSystem to the Engine it will replace the old one. Also like component, you remove Systems with their class reference:

engine.removeStepSystem(MyStepSystem.class);

So to summarize the game loop:

  1. STEP - Executes all StepSystems active in the engine, in order of their priority value.
  2. PREDRAW - Draws all the backgrounds in the current Scenes BackgroundAttribute, if it has one.
  3. DRAW - Executes all DrawSystems active in the engine, in order of their priority value, including RenderSystem, which renders all entities with a DrawComponent.
  4. POSTDRAW - Draws all the foregrounds in the current Scenes BackgroundAttribute, if it has one.
Clone this wiki locally