Added a scene manager module.

This commit is contained in:
Kapendev 2024-09-13 14:48:45 +03:00
parent 348b54e50a
commit 78aa0c084e
13 changed files with 205 additions and 11 deletions

View file

@ -34,3 +34,7 @@ This example shows how to create an animated character that follows the mouse.
## [Timer](timer.d)
This example shows how to use the timer structure of Popka.
## [Scene](scene.d)
This example shows how to use the scene manager of Popka.

75
examples/scene.d Normal file
View file

@ -0,0 +1,75 @@
/// This example shows how to use the scene manager of Popka.
import popka;
// The game variables.
auto sceneManager = SceneManager();
// The first scene.
struct Scene1 {
mixin extendScene;
float counter = 0;
void ready() {
println("Entering scene 1.");
setBackgroundColor(gray1);
}
bool update(float dt) {
if (Keyboard.space.isPressed) {
sceneManager.enter!Scene2();
}
counter += 5 * dt;
drawDebugText("Press enter to change scene.", resolution * Vec2(0.5), DrawOptions(Hook.center));
drawDebugText("Scene 1\nCounter: {}".format(cast(int) counter), Vec2(8));
return false;
}
void finish() {
println("Exiting scene 1.");
}
}
// The second scene.
struct Scene2 {
mixin extendScene;
void ready() {
println("Entering scene 2.");
setBackgroundColor(gray2);
}
bool update(float dt) {
if (Keyboard.space.isPressed) {
sceneManager.enter!Scene1();
}
drawDebugText("Press enter to change scene.", resolution * Vec2(0.5), DrawOptions(Hook.center));
drawDebugText("Scene 2\nNo counter here.", Vec2(8));
return false;
}
void finish() {
println("Exiting scene 2.");
}
}
void ready() {
lockResolution(320, 180);
// Enter the first scene. This will call the ready function of that scene.
sceneManager.enter!Scene1();
}
bool update(float dt) {
// Update the current scene.
return sceneManager.update(dt);
}
void finish() {
// Free the scene manager. This will call the finish function of the current scene.
sceneManager.free();
}
mixin runGame!(ready, update, finish);

View file

@ -10,7 +10,7 @@ enum header = "// ---
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---";
int main(string[] args) {

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
// TODO: The DialogueCommandRunner should work with gc functions too. Think about how to do it.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
// TODO: Test the resources code and the tag thing.
@ -157,6 +157,33 @@ struct DrawOptions {
Color color = white; /// The color of the drawn object.
Hook hook = Hook.topLeft; /// An value representing the origin point of the drawn object when origin is set to zero.
Flip flip = Flip.none; /// An value representing flipping orientations.
@safe @nogc nothrow:
/// Initializes the options with the given scale.
this(Vec2 scale) {
this.scale = scale;
}
/// Initializes the options with the given rotation.
this(float rotation) {
this.rotation = rotation;
}
/// Initializes the options with the given color.
this(Color color) {
this.color = color;
}
/// Initializes the options with the given hook.
this(Hook hook) {
this.hook = hook;
}
/// Initializes the options with the given flip.
this(Flip flip) {
this.flip = flip;
}
}
/// A structure representing a camera.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
module popka;
@ -11,6 +11,7 @@ module popka;
public import joka;
public import popka.dialogue;
public import popka.engine;
public import popka.scene;
public import popka.sprite;
public import popka.tilemap;
public import popka.timer;

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
/// The `rl` module provides access to the raylib library.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
/// The `rayib` module provides access to the raylib.h functions.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
/// The `rlgl` module provides access to the rlgl.h functions.

87
source/popka/scene.d Normal file
View file

@ -0,0 +1,87 @@
// ---
// Copyright 2024 Alexandros F. G. Kapretsos
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.22
// ---
// TODO: Update all the doc comments here.
/// The `scene` module provides a simple scene manager.
module popka.scene;
import stdc = joka.stdc;
import popka.engine;
struct Scene {
void delegate() ready;
bool delegate(float dt) update;
void delegate() finish;
}
struct SceneManager {
Scene* scene;
Scene* nextScene;
@trusted @nogc nothrow
void enter(T)() {
if (nextScene) return;
auto temp = cast(T*) stdc.malloc(T.sizeof);
*temp = T();
temp.prepare();
nextScene = cast(Scene*) temp;
}
bool update(float dt) {
if (nextScene) {
if (scene) {
if (scene.finish) scene.finish();
stdc.free(scene);
}
scene = nextScene;
nextScene = null;
if (scene.ready) scene.ready();
if (scene.update) return scene.update(dt);
return true;
}
if (scene && scene.update) return scene.update(dt);
return true;
}
void free() {
if (scene) {
if (scene.finish) scene.finish();
stdc.free(scene);
scene = null;
}
if (nextScene) {
stdc.free(nextScene);
nextScene = null;
}
}
}
mixin template extendScene() {
Scene base;
@safe @nogc nothrow
void prepare() {
auto base = mixin("&", this.tupleof[0].stringof);
static if (hasMember!(typeof(this), "ready")) {
base.ready = &this.ready;
} else {
base.ready = null;
}
static if (hasMember!(typeof(this), "update")) {
base.update = &this.update;
} else {
base.update = null;
}
static if (hasMember!(typeof(this), "finish")) {
base.finish = &this.finish;
} else {
base.finish = null;
}
}
}

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
// TODO: Think about gaps in an atlas texture.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
// TODO: Think about gaps in an atlas texture.

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
// Email: alexandroskapretsos@gmail.com
// Project: https://github.com/Kapendev/popka
// Version: v0.0.21
// Version: v0.0.22
// ---
// TODO: Update all the doc comments here.
@ -11,7 +11,7 @@
/// The `timer` module provides a simple and extensible timer.
module popka.timer;
import popka.engine;
import joka.math;
@safe @nogc nothrow: