The dialogue system works now and it is in core.

This commit is contained in:
Kapendev 2024-03-13 23:45:12 +02:00
parent 0dcc534b7a
commit 732f3b832d
6 changed files with 57 additions and 52 deletions

View file

@ -1,6 +1,5 @@
# NOW
* Working on menu for dialogue.
* Test engine on Windows.
# TODO

View file

@ -6,16 +6,20 @@
module popka.core.ascii;
enum {
digitChars = "0123456789",
upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
lowerChars = "abcdefghijklmnopqrstuvwxyz",
alphaChars = upperChars ~ lowerChars,
spaceChars = " \t\v\r\n\f",
}
bool isLower(char c) {
return c >= 'a' && c <= 'z';
bool isDigit(char c) {
return c >= '0' && c <= '9';
}
bool isLower(const(char)[] str) {
bool isDigit(const(char)[] str) {
foreach (c; str) {
if (!isLower(c)) return false;
if (!isDigit(c)) return false;
}
return true;
}
@ -31,6 +35,17 @@ bool isUpper(const(char)[] str) {
return true;
}
bool isLower(char c) {
return c >= 'a' && c <= 'z';
}
bool isLower(const(char)[] str) {
foreach (c; str) {
if (!isLower(c)) return false;
}
return true;
}
bool isAlpha(char c) {
return isLower(c) || isUpper(c);
}
@ -42,17 +57,6 @@ bool isAlpha(const(char)[] str) {
return true;
}
bool isDigit(char c) {
return c >= '0' && c <= '9';
}
bool isDigit(const(char)[] str) {
foreach (c; str) {
if (!isDigit(c)) return false;
}
return true;
}
bool isSpace(char c) {
foreach (sc; spaceChars) {
if (c == sc) return true;
@ -67,13 +71,13 @@ bool isSpace(const(char)[] str) {
return true;
}
char toLower(char c) {
return isUpper(c) ? cast(char) (c + 32) : c;
char toDigit(char c) {
return isDigit(c) ? cast(char) (c - 48) : '0';
}
void toLower(char[] str) {
void toDigit(char[] str) {
foreach (ref c; str) {
c = toLower(c);
c = toDigit(c);
}
}
@ -87,13 +91,13 @@ void toUpper(char[] str) {
}
}
char toDigit(char c) {
return isDigit(c) ? cast(char) (c - 48) : '0';
char toLower(char c) {
return isUpper(c) ? cast(char) (c + 32) : c;
}
void toDigit(char[] str) {
void toLower(char[] str) {
foreach (ref c; str) {
c = toDigit(c);
c = toLower(c);
}
}

View file

@ -9,6 +9,7 @@ module popka.core.basic;
public import popka.core.ascii;
public import popka.core.color;
public import popka.core.container;
public import popka.core.dialogue;
public import popka.core.fmt;
public import popka.core.io;
public import popka.core.math;

View file

@ -1,14 +1,14 @@
// Copyright 2024 Alexandros F. G. Kapretsos
// SPDX-License-Identifier: MIT
/// The dialogue module is a versatile dialogue system for games,
/// The dialogue module is a versatile dialogue system,
/// enabling the creation of interactive conversations and branching narratives.
// TODO: API might need some work.
module popka.core.dialogue;
module popka.game.dialogue;
import popka.core.basic;
import popka.core.container;
import popka.core.io;
import popka.core.strutils;
enum dialogueUnitKindChars = "-#.@>|^";
@ -38,7 +38,7 @@ struct DialogueUnit {
struct Dialogue {
List!DialogueUnit units;
List!(const(char)[]) options;
List!(const(char)[]) menu;
size_t unitIndex;
size_t pointCount;
const(char)[] text;
@ -48,16 +48,16 @@ struct Dialogue {
load(path);
}
bool hasOptions() {
return options.length != 0;
bool hasMenu() {
return menu.length != 0;
}
bool canUpdate() {
return unitIndex < units.length && units[unitIndex].kind != DialogueUnitKind.pause;
}
DialogueUnit now() {
return units[unitIndex];
const(char)[][] options() {
return menu.items;
}
void reset() {
@ -105,9 +105,10 @@ struct Dialogue {
}
}
void selectOption(size_t i) {
void select(size_t i) {
menu.clear();
skip(i + 1);
options.clear();
update();
}
void update() {
@ -124,11 +125,11 @@ struct Dialogue {
jump(unit.text.items);
update();
} else if (unit.kind == DialogueUnitKind.menu) {
options.clear();
menu.clear();
const(char)[] view = unit.text.items;
while (view.length != 0) {
auto option = trim(skipValue(view, DialogueUnitKind.menu));
options.append(option);
menu.append(option);
}
}
}

View file

@ -8,8 +8,8 @@ module popka.example.basic;
public import popka.example.camera;
public import popka.example.coins;
public import popka.example.hello;
public import popka.example.dialogue;
public import popka.example.hello;
void runEveryExample() {
runHelloExample();

View file

@ -3,12 +3,9 @@
/// An example that shows how to use the dialogue system of Popka.
// TODO: Example might need some work.
module popka.example.dialogue;
import popka.basic;
import popka.game.dialogue;
void runDialogueExample() {
openWindow(640, 480);
@ -28,6 +25,7 @@ void runDialogueExample() {
> Mia
| Hello!
| Nice to meet you!
| My name is Mia.
@ Point1
. Point2
@ -50,11 +48,10 @@ void runDialogueExample() {
dialogue.update();
}
if (dialogue.canUpdate) {
if (dialogue.hasOptions) {
foreach (i, key; "123456789"[0 .. dialogue.options.length]) {
if (dialogue.hasMenu) {
foreach (i, key; digitChars[1 .. 1 + dialogue.options.length]) {
if (isPressed(key)) {
dialogue.selectOption(i);
dialogue.update();
dialogue.select(i);
break;
}
}
@ -64,18 +61,21 @@ void runDialogueExample() {
}
// Draw the game.
if (dialogue.hasOptions) {
foreach (i, option; dialogue.options.items) {
if (dialogue.hasMenu) {
foreach (i, option; dialogue.options) {
drawDebugText("{}. {}".fmt(i + 1, option), Vec2(8, 8 + i * 14));
}
} else if (dialogue.canUpdate) {
drawDebugText("{}: {}".fmt(dialogue.actor, dialogue.text));
} else {
drawDebugText("No more dialogue.");
drawDebugText("The dialogue has ended.");
}
drawDebugText("Press R to restart.", Vec2(8, 140));
drawRect(Rect(0, resolution.y * 0.5, resolution.x, 1), lightGray);
drawDebugText(
"Press a number to pick an option.\nPress space to continue.\nPress R to restart.",
Vec2(8, resolution.y - 14 * 3 - 8)
);
}
// Free all the game resources.
dialogue.free();
freeWindow();