The engine life cycle is very simple, similar to the game standards.
As the LionEngine is a library (and not a program), you will have to create the first step of the life cycle: the Main
public final class MainJava { public static void main(String[] args) { // Here the program starts } }
public final class MainAndroid extends Activity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Here the program starts } }
Nothing new until there if you have enough knowledge in the domain.
Once the language entry point is clear, you may want to discover the engine life cycle.
Here the completes tree structure of the life cycle:
The main idea behind this is that the Loader
can be considered as a Sequence
scheduler, where
each part of the game (introduction, menu, level...) represents a Sequence
. So when a Sequence
is finished (end of an introduction, or a game level...), the application (and also the engine), is
not necessary finished. You may want to continue to another level, or simply start the menu after the introduction.
The application starts with the first Sequence
you gave, and continues its life until its end (by simply
stop any activities, or start a new Sequence
). In any case, this is the Loader
that controls
theses steps. The only one condition to end a program is when the Loader
does not have any new Sequence
to start. In that case, the engine will be closed, and the application will end (and the JVM will terminate).
The engine initialization must be made inside the main. This is where you will have the opportunity to setup the
engine, depending of your needs. You will have to define required elements, such as your program name &
version, the resources directory, the output resolution (plus an optional filtering), and finally
the first Sequence
.
What about the required code ?
Engine.start("Name", Version.create(1, 0, 0), Verbose.CRITICAL, "resources"); final Resolution output = new Resolution(640, 480, 60); final Config config = new Config(output, 32, false); final Loader loader = new Loader(config); loader.start(Scene.class);
The initialization part is almost the same for both Java & Android target...
...excepted for a special case when using Android target, that must be applied to the first line (this
):
Engine.start("Name", Version.create(1, 0, 0), Verbose.CRITICAL, this);
This is because the resource directory is relative to the Android Application Activity, and can not be set manually (also due to access rights).
Once the engine is initialized and the loader is started with its first Sequence
, the program is in
freewheel. There is two main possible actions that can be performed during this step:
Sequence
simply starts a new one, and terminates at the same time. Control goes to the new one.
Sequence
can start and load a new Sequence
while running, and gives the control back
when terminating.
While the first case is simple to understand, the second one is a little bit more tricky.
Here a good example to illustrate it:
I want to make an advanced transition between my game menu and my level. The idea would be to load the game level while being in the menu. The second case of the previous explanation does the job !
The next Sequence
loading is performed in a separated thread, which allows to not block the
current Sequence
. This way it is possible to significantly reduce the overall loading time, at least in
appearance for the user, at it is possible to interact with something while the engine is loading the next Sequence
.
Here an example on how to simply link two Sequence
(where Menu
is the first Sequence
):
s.lionengine.Resolution; import com.b3dgs.lionengine.core.Graphic; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Sequence; /** * SequenceLinkSimple implementation. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public class SequenceLinkSimple extends Sequence { /** Count value. */ private int count; /** * Constructor. * * @param loader The loader reference. */ public SequenceLinkSimple(Loader loader) { super(loader, new Resolution(320, 100, 32)); } /* * Sequence */ @Override protected void load() { count = 0; } @Override protected void update(double extrp) { count++; if (count > 2) { end(SequenceNext.class); } } @Override protected void render(Graphic g) { System.out.println("SimpleLink rendering number " + count); } } |
s.lionengine.Resolution; import com.b3dgs.lionengine.core.Graphic; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Sequence; /** * SequenceNext implementation. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public class SequenceNext extends Sequence { /** * Constructor. * * @param loader The loader reference. */ public SequenceNext(Loader loader) { super(loader, new Resolution(320, 100, 32)); } /* * Sequence */ @Override protected void load() { System.out.println("SequenceNext loaded !"); } @Override protected void update(double extrp) { end(); } @Override protected void render(Graphic g) { System.out.println("I am Next !"); } } |
s.lionengine.Config; import com.b3dgs.lionengine.Resolution; import com.b3dgs.lionengine.Version; import com.b3dgs.lionengine.core.Engine; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Verbose; /** * Program starts here. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public final class AppSequenceLinkSimple { /** * Main function called by the jvm. * * @param args The arguments. */ public static void main(String[] args) { Engine.start("AppSequenceLinkSimple", Version.create(1, 0, 0), Verbose.CRITICAL, "resources"); final Resolution output = new Resolution(640, 480, 60); final Config config = new Config(output, 16, true); final Loader loader = new Loader(config); loader.start(SequenceLinkSimple.class); } }
The SequenceLinkSimple
will end when count > 2
, and start the next Sequence
called SequenceNext
. One the next Sequence
is started, it will simply definitely end (as we
called it).
Here an example on how to create an advanced link between two Sequence
(where Menu
is the
first Sequence
):
s.lionengine.Resolution; import com.b3dgs.lionengine.core.Graphic; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Sequence; /** * SequenceLinkComplex implementation. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public class SequenceLinkComplex extends Sequence { /** Count value. */ private int count; /** * Constructor. * * @param loader The loader reference. */ public SequenceLinkComplex(Loader loader) { super(loader, new Resolution(320, 100, 32)); } /* * Sequence */ @Override protected void load() { count = 0; } @Override protected void update(double extrp) { count++; if (count == 1) { start(false, SequenceNext.class); } if (count > 2) { end(); } } @Override protected void render(Graphic g) { System.out.println("ComplexLink rendering number " + count); } } |
s.lionengine.Resolution; import com.b3dgs.lionengine.core.Graphic; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Sequence; /** * SequenceNext implementation. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public class SequenceNext extends Sequence { /** * Constructor. * * @param loader The loader reference. */ public SequenceNext(Loader loader) { super(loader, new Resolution(320, 100, 32)); } /* * Sequence */ @Override protected void load() { System.out.println("SequenceNext loaded !"); } @Override protected void update(double extrp) { end(); } @Override protected void render(Graphic g) { System.out.println("I am Next !"); } } |
s.lionengine.Config; import com.b3dgs.lionengine.Resolution; import com.b3dgs.lionengine.Version; import com.b3dgs.lionengine.core.Engine; import com.b3dgs.lionengine.core.Loader; import com.b3dgs.lionengine.core.Verbose; /** * Program starts here. * * @author Pierre-Alexandre (contact@b3dgs.com) */ public final class AppSequenceLinkComplex { /** * Main function called by the jvm. * * @param args The arguments. */ public static void main(String[] args) { Engine.start("AppSequenceLinkComplex", Version.create(1, 0, 0), Verbose.CRITICAL, "resources"); final Resolution output = new Resolution(640, 480, 60); final Config config = new Config(output, 16, true); final Loader loader = new Loader(config); loader.start(SequenceLinkComplex.class); } }
The SequenceLinkComplex
will start the next Sequence
called SequenceNext
, but
will also continue its life until count > 2
, and then end. When the SequenceLinkComplex
terminated, the SequenceNext
will immediately enter in its routine (update
& render
).
Read next page: Base tools