feat: almost implemented story layer (TODO: BGM)

This commit is contained in:
Renge 2022-04-03 14:29:42 -04:00
parent 33420bc866
commit 018904cc90
4 changed files with 152 additions and 37 deletions

View File

@ -1,19 +1,67 @@
{ {
"resources": [ "bgm": [
{ {
"type": "image", "key": "test",
"key": "hiro", "path": "shattered_sword_assets/sounds/test.mp3"
"path": "shattered_sword_assets/images/Logo.png"
} }
], ],
"texts": [ "texts": [
{ {
"speaker": "Hiro", "speaker": "Hiro",
"content": "Hello world!" "content": "Hello\r\n\nworld!",
"actions": [
{
"type": "loadSprite",
"key": "hiro",
"path": "shattered_sword_assets/images/Logo.png",
"positon": [
500,
500
],
"scale": [
1,
1
]
}
]
}, },
{ {
"speaker": "world", "speaker": "world",
"content": "Hello Hiro!" "content": "Hello Hiro!",
"actions": [
{
"type": "moveSprite",
"key": "hiro",
"positon": [
100,
100
],
"scale": [
2,
2
]
}
]
},
{
"speaker": "world",
"content": "this should hide the image",
"actions": [
{
"type": "hideSprite",
"key": "hiro"
}
]
},
{
"speaker": "world",
"content": "this should show it again",
"actions": [
{
"type": "showSprite",
"key": "hiro"
}
]
} }
] ]
} }

Binary file not shown.

View File

@ -7,15 +7,23 @@ import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
import Color from "../../Wolfie2D/Utils/Color"; import Color from "../../Wolfie2D/Utils/Color";
import Layer from "../../Wolfie2D/Scene/Layer"; import Layer from "../../Wolfie2D/Scene/Layer";
import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite"; import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite";
import MapTemplate from "../Tools/DataTypes/MapTemplate";
import { GameEventType } from "../../Wolfie2D/Events/GameEventType";
enum Mode {
GAME_MODE = "GameMode",
STORY_MODE = "StoryMode",
PAUSE_MODE = "PauseMode",
}
export default class StorySceneTester extends Scene { export default class StorySceneTester extends Scene {
private isInStoryMode: boolean = false; private currentMode: Mode = Mode.GAME_MODE;
private storytextLabel: Label; private storytextLabel: Label;
private storyLayer: Layer; private storyLayer: Layer;
private primary: Layer; private primary: Layer;
private story: Story; private story: Story;
private storyProgress: number; private storyProgress: number;
private storySprites: Array<Sprite>; private storySprites: Array<Sprite>;
private storyBGMs: Array<string>;
private currentSpeaker: string; private currentSpeaker: string;
private currentContent: string; private currentContent: string;
@ -40,61 +48,120 @@ export default class StorySceneTester extends Scene {
async storyLoader(storyPath: string) { async storyLoader(storyPath: string) {
const response = await (await fetch(storyPath)).json(); const response = await (await fetch(storyPath)).json();
this.story = <Story>response; this.story = <Story>response;
this.story.resources.forEach((resource) => { if (this.story.bgm) {
switch (resource.type) { this.storyBGMs = new Array;
case "image": this.story.bgm.forEach((bgm) => {
this.load.image(resource.key, resource.path); this.load.audio(bgm.key, bgm.path);
break; console.log("audio:", bgm.key, "path:", bgm.path);
case "spritesheet": this.load.loadResourcesFromQueue(() => {
this.load.spritesheet(resource.key, resource.path); console.log("finished loading audio");
break; this.emitter.fireEvent(GameEventType.PLAY_SOUND, { key: bgm.key, loop: false, holdReference: true });
case "audio": });
this.load.audio(resource.key, resource.path); this.storyBGMs.push(bgm.key);
break; })
default: }
break;
}
});
this.currentSpeaker = this.story.texts[0].speaker; this.currentSpeaker = this.story.texts[0].speaker;
this.currentContent = this.story.texts[0].content; this.currentContent = this.story.texts[0].content;
this.storytextLabel = <Label>this.add.uiElement(UIElementType.LABEL, "story", { position: new Vec2(this.viewport.getHalfSize().x, this.viewport.getHalfSize().y + 240), text: (this.currentSpeaker + ': \n\n' + this.currentContent) }); this.storytextLabel = <Label>this.add.uiElement(UIElementType.LABEL, "story", { position: new Vec2(this.viewport.getHalfSize().x, this.viewport.getHalfSize().y + 240), text: "" });
this.storytextLabel.textColor = Color.WHITE; this.storytextLabel.textColor = Color.WHITE;
this.storytextLabel.font = "PixelSimple"; this.storytextLabel.font = "PixelSimple";
this.storytextLabel.fontSize = 20; this.storytextLabel.fontSize = 20;
this.storytextLabel.setHAlign(HAlign.LEFT); this.storytextLabel.setHAlign(HAlign.LEFT);
this.storyProgress = 0; this.storyProgress = -1;
this.isInStoryMode = true; this.storySprites = new Array;
this.currentMode = Mode.STORY_MODE;
this.updateStory();
} }
hasNextStory(): boolean { hasNextStory(): boolean {
return this.isInStoryMode && this.storyProgress + 1 < this.story.texts.length; return this.currentMode === Mode.STORY_MODE && this.storyProgress + 1 < this.story.texts.length;
} }
updateStory() { updateStory() {
if (this.isInStoryMode && this.hasNextStory()) { if (this.currentMode === Mode.STORY_MODE && this.hasNextStory()) {
this.storyProgress ++; this.storyProgress++;
let tmp = undefined;
if (this.story.texts[this.storyProgress].actions) {
this.story.texts[this.storyProgress].actions.forEach(action => {
switch (action.type) {
case "loadSprite":
this.load.image(action.key, action.path);
this.load.loadResourcesFromQueue(() => {
tmp = this.add.sprite(action.key, "story");
tmp.position.set(action.positon[0], action.positon[1]);
tmp.scale.set(action.scale[0], action.scale[1]);
this.storySprites.push(tmp);
});
break;
case "loadAnimatedSprite":
this.load.spritesheet(action.key, action.path);
this.load.loadResourcesFromQueue(() => {
tmp = this.add.animatedSprite(action.key, "story");
tmp.position.set(action.positon[0], action.positon[1]);
tmp.scale.set(action.scale[0], action.scale[1]);
this.storySprites.push(tmp);
});
break;
case "moveSprite":
tmp = this.storySprites.find(function (sprite) {
return sprite.imageId === action.key;
});
tmp.position.set(action.positon[0], action.positon[1]);
tmp.scale.set(action.scale[0], action.scale[1]);
break;
case "showSprite":
tmp = this.storySprites.find(function (sprite) {
return sprite.imageId === action.key;
});
tmp.visible = true;
break;
case "hideSprite":
tmp = this.storySprites.find(function (sprite) {
return sprite.imageId === action.key;
});
tmp.visible = false;
break;
default:
break;
}
})
}
this.currentSpeaker = this.story.texts[this.storyProgress].speaker; this.currentSpeaker = this.story.texts[this.storyProgress].speaker;
this.currentContent = this.story.texts[this.storyProgress].content; this.currentContent = this.story.texts[this.storyProgress].content;
this.storytextLabel.text = this.currentSpeaker+':\n\n'+this.currentContent; this.storytextLabel.text = this.currentSpeaker + ':\n\n' + this.currentContent;
} }
else { else {
this.isInStoryMode = false; this.currentMode = Mode.GAME_MODE;
this.storyProgress = Infinity; this.storyProgress = Infinity;
this.storytextLabel.destroy(); this.storytextLabel.destroy();
if (this.storySprites) {
this.storySprites.forEach((sprite) => {
sprite.visible = false;
sprite.destroy();
});
}
if (this.storyBGMs) {
this.storyBGMs.forEach((bgm) => {
this.emitter.fireEvent(GameEventType.STOP_SOUND, { key: bgm });
console.log("sound stopped:", bgm);
});
}
this.storyBGMs = undefined;
this.storySprites = undefined;
this.story = undefined; this.story = undefined;
this.storytextLabel = undefined;
} }
} }
updateScene(deltaT: number): void { updateScene(deltaT: number): void {
while (this.receiver.hasNextEvent()) { while (this.receiver.hasNextEvent()) {
let event = this.receiver.getNextEvent(); let event = this.receiver.getNextEvent();
if (event.type === "loadStory" && !this.isInStoryMode) { if (event.type === "loadStory" && this.currentMode === Mode.GAME_MODE) {
this.storyLoader("shattered_sword_assets/jsons/samplestory.json"); this.storyLoader("shattered_sword_assets/jsons/samplestory.json");
console.log("loading story");
} }
} }
if (Input.isMouseJustPressed() && this.isInStoryMode) { if (Input.isMouseJustPressed() && this.currentMode === Mode.STORY_MODE) {
this.updateStory(); this.updateStory();
} }
} }

View File

@ -1,5 +1,4 @@
export class Resource { export class BGM {
type: string;
key: string; key: string;
path: string; path: string;
} }
@ -11,13 +10,14 @@ export class Text {
} }
export class Action { export class Action {
type: "loadSprite" | "loadAnimatedSprite" | "move" | "show" | "hide"; type: "loadSprite" | "loadAnimatedSprite" | "moveSprite" | "showSprite" | "hideSprite";
key: string; key: string;
path?: string;
positon?: [number, number]; positon?: [number, number];
scale?: [number, number]; scale?: [number, number];
} }
export default class Story { export default class Story {
resources: Array<Resource>; bgm?: Array<BGM>;
texts: Array<Text>; texts: Array<Text>;
} }