Implementing Screen - sinusinu/Flora GitHub Wiki
Normally, games have multiple "screen"s to do different works. (e.g. Title screen, Game screen, Settings screen...)
To make implementing screen a bit easier, Flora provides IScreen
interface. Let's try this one!
Begin with Simple Program:
using Flora;
using Flora.Gfx;
namespace FloraTest {
class MyCore : FloraCore {
IScreen currentScreen = null;
IScreen pendingScreen = null;
public override void Prepare() {
currentScreen = new ScreenA(this);
}
public override void Pause() {
if (currentScreen != null) currentScreen.Pause();
}
public override void Resume() {
if (currentScreen != null) currentScreen.Resume();
}
public override void Resize(int width, int height) {
if (currentScreen != null) currentScreen.Resize(width, height);
}
public override void Render(float delta) {
if (currentScreen != null) currentScreen.Render(delta);
if (pendingScreen != null) {
currentScreen.Cleanup();
currentScreen = pendingScreen;
pendingScreen = null;
}
}
public override void Cleanup() {
if (currentScreen != null) currentScreen.Cleanup();
}
public void SetScreen(IScreen newScreen) {
pendingScreen = newScreen;
}
}
}
Now MyCore
have currentScreen
and pendingScreen
variable, sets currentScreen
to new ScreenA(this)
on Prepare
, and just passes all the functions to currentScreen
.
Render
code is a bit unusual; It switches the screen after the render is over, instead of switching it immediately. This is to preserve reference of current screen while render is being executed.
Finally, We expose SetScreen
function for screens to set new screens.
Create a new class file named ScreenA.cs
. Fill it with this:
using Flora;
using Flora.Gfx;
using System;
namespace FloraTest {
class ScreenA : IScreen {
MyCore core;
public ScreenA(MyCore core) {
this.core = core;
Console.WriteLine("Screen A created!");
}
public void Pause() {
}
public void Resume() {
}
public void Resize(int width, int height) {
}
public void Render(float delta) {
Gfx.Begin();
Gfx.End();
core.SetScreen(new ScreenB(core));
}
public void Cleanup() {
}
}
}
You can see that IScreen
interface have all the same functions with FloraCore
except Prepare
.
That's because Flora is supposed to be already initialized when any of IScreen
-inheriting object is being constructed. So any preparation can be done in constructor, instead of having separate Prepare
function.
It is important for screens to keep the reference of MyCore
alive by passing it around - or there will be no way to change the screen.
For now, ScreenA
sets current screen to ScreenB
every Render
call.
Create a new class file named ScreenB.cs
. Fill it with this:
using Flora;
using Flora.Gfx;
using System;
namespace FloraTest {
class ScreenB : IScreen {
MyCore core;
public ScreenB(MyCore core) {
this.core = core;
Console.WriteLine("Screen B created");
}
public void Pause() {
}
public void Resume() {
}
public void Resize(int width, int height) {
}
public void Render(float delta) {
Gfx.Begin();
Gfx.End();
core.SetScreen(new ScreenA(core));
}
public void Cleanup() {
}
}
}
Same deal as ScreenA
, but ScreenB
sets current screen to ScreenA
every Render
call.
Now if you launch this app, you will see two screens quickly switching between them via Console. Nothing is being drawn on screen yet because we draw nothing on it.
You can use IScreen
this way to easily implement screens!