feat: partially implement storymode
This commit is contained in:
parent
520fb8837e
commit
425f8b29b5
BIN
dist/shattered_sword_assets/images/Logo.png
vendored
Normal file
BIN
dist/shattered_sword_assets/images/Logo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
19
dist/shattered_sword_assets/jsons/samplestory.json
vendored
Normal file
19
dist/shattered_sword_assets/jsons/samplestory.json
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"type": "image",
|
||||||
|
"key": "hiro",
|
||||||
|
"path": "shattered_sword_assets/images/Logo.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"texts": [
|
||||||
|
{
|
||||||
|
"speaker": "Hiro",
|
||||||
|
"content": "Hello world!"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"speaker": "world",
|
||||||
|
"content": "Hello Hiro!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
114
src/shattered_sword/Scenes/Layers/StoryLayer.ts
Normal file
114
src/shattered_sword/Scenes/Layers/StoryLayer.ts
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// import Vec2 from "../../../Wolfie2D/DataTypes/Vec2";
|
||||||
|
// import Sprite from "../../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||||
|
// import Label, { HAlign } from "../../../Wolfie2D/Nodes/UIElements/Label";
|
||||||
|
// import { UIElementType } from "../../../Wolfie2D/Nodes/UIElements/UIElementTypes";
|
||||||
|
// import Layer from "../../../Wolfie2D/Scene/Layer";
|
||||||
|
// import Scene from "../../../Wolfie2D/Scene/Scene";
|
||||||
|
// import Color from "../../../Wolfie2D/Utils/Color";
|
||||||
|
// import Story from "../../Tools/DataTypes/Story";
|
||||||
|
// import StorySceneTester from "../StorySceneTester";
|
||||||
|
|
||||||
|
// export default class StoryLayer extends Layer {
|
||||||
|
// private progress: number;
|
||||||
|
// private sprites: Array<Sprite>;
|
||||||
|
// private currentSpeaker: string;
|
||||||
|
// private currentContent: string;
|
||||||
|
|
||||||
|
|
||||||
|
// constructor(scene: Scene, name: string, story: Story) {
|
||||||
|
// super(scene, name);
|
||||||
|
// this.story = story;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static async storyLayerFactory(scene: StorySceneTester, name: string, storyPath: string): Promise<StoryLayer> {
|
||||||
|
// const response = await (await fetch(storyPath)).json();
|
||||||
|
// let instance = new StoryLayer(scene, name, response);
|
||||||
|
// instance.story.resources.forEach((resource) => {
|
||||||
|
// switch (resource.type) {
|
||||||
|
// case "image":
|
||||||
|
// instance.scene.load.image(resource.key, resource.path);
|
||||||
|
// break;
|
||||||
|
// case "spritesheet":
|
||||||
|
// instance.scene.load.spritesheet(resource.key, resource.path);
|
||||||
|
// break;
|
||||||
|
// case "audio":
|
||||||
|
// instance.scene.load.audio(resource.key, resource.path);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// instance.currentSpeaker = instance.story.texts[0].speaker;
|
||||||
|
// instance.currentContent = instance.story.texts[0].content;
|
||||||
|
|
||||||
|
// instance.textLabel = <Label>instance.scene.add.uiElement(UIElementType.LABEL, "story", { position: new Vec2(100, 300), text: (instance.currentSpeaker + instance.currentContent) });
|
||||||
|
// // instance.textLabel.textColor = new Color(0, 0, 0, 1);
|
||||||
|
// // instance.textLabel.font = "PixelSimple";
|
||||||
|
// // instance.textLabel.fontSize = 40;
|
||||||
|
// // instance.textLabel.setHAlign(HAlign.LEFT);
|
||||||
|
// scene.isInStoryMode = true;
|
||||||
|
// return instance;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// hasNext(): boolean {
|
||||||
|
// return this.progress + 1 < this.story.texts.length;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// update(): void {
|
||||||
|
// if (!this.hasNext()) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// this.progress++;
|
||||||
|
// console.log(this.progress);
|
||||||
|
// // this.currentSpeaker = this.story.texts[this.progress].speaker;
|
||||||
|
// // this.currentContent = this.story.texts[this.progress].content;
|
||||||
|
// // this.textLabel.text = (this.currentSpeaker + this.currentContent);
|
||||||
|
// // let tmp = undefined;
|
||||||
|
// // if (this.story.texts[this.progress].actions) {
|
||||||
|
// // this.story.texts[this.progress].actions.forEach(action => {
|
||||||
|
// // switch (action.type) {
|
||||||
|
// // case "loadSprite":
|
||||||
|
// // tmp = this.scene.add.sprite(action.key, "UI");
|
||||||
|
// // tmp.position.set(action.positon[0], action.positon[1]);
|
||||||
|
// // tmp.scale.set(action.scale[0], action.scale[1]);
|
||||||
|
// // this.sprites.push(tmp);
|
||||||
|
// // break;
|
||||||
|
// // case "loadSprite":
|
||||||
|
// // tmp = this.scene.add.sprite(action.key, "UI");
|
||||||
|
// // tmp.position.set(action.positon[0], action.positon[1]);
|
||||||
|
// // tmp.scale.set(action.scale[0], action.scale[1]);
|
||||||
|
// // this.sprites.push(tmp);
|
||||||
|
// // break;
|
||||||
|
// // case "move":
|
||||||
|
// // tmp = this.sprites.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 "show":
|
||||||
|
// // tmp = this.sprites.find(function (sprite) {
|
||||||
|
// // return sprite.imageId === action.key;
|
||||||
|
// // });
|
||||||
|
// // tmp.visible = true;
|
||||||
|
// // break;
|
||||||
|
// // case "hide":
|
||||||
|
// // tmp = this.sprites.find(function (sprite) {
|
||||||
|
// // return sprite.imageId === action.key;
|
||||||
|
// // });
|
||||||
|
// // tmp.visible = false;
|
||||||
|
// // break;
|
||||||
|
// // default:
|
||||||
|
// // break;
|
||||||
|
// // }
|
||||||
|
// // })
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// unload(): void {
|
||||||
|
// this.sprites.forEach(sprite => {
|
||||||
|
// sprite.destroy();
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -11,6 +11,7 @@ import Color from "../../Wolfie2D/Utils/Color";
|
||||||
import Layer from "../../Wolfie2D/Scene/Layer";
|
import Layer from "../../Wolfie2D/Scene/Layer";
|
||||||
import Label from "../../Wolfie2D/Nodes/UIElements/Label";
|
import Label from "../../Wolfie2D/Nodes/UIElements/Label";
|
||||||
import MainMenu from "./MainMenu";
|
import MainMenu from "./MainMenu";
|
||||||
|
import StorySceneTester from "./StorySceneTester";
|
||||||
|
|
||||||
|
|
||||||
export default class Levels extends Scene {
|
export default class Levels extends Scene {
|
||||||
|
@ -59,12 +60,12 @@ export default class Levels extends Scene {
|
||||||
level5.backgroundColor = Color.TRANSPARENT;
|
level5.backgroundColor = Color.TRANSPARENT;
|
||||||
level5.onClickEventId = "level5";
|
level5.onClickEventId = "level5";
|
||||||
|
|
||||||
const level6 = this.add.uiElement(UIElementType.BUTTON, "primary", {position: new Vec2(center.x, center.y + 100), text: "level 6"});
|
const StorySceneTester = this.add.uiElement(UIElementType.BUTTON, "primary", {position: new Vec2(center.x, center.y + 100), text: "StorySceneTester"});
|
||||||
level6.size.set(200, 50);
|
StorySceneTester.size.set(200, 50);
|
||||||
level6.borderWidth = 2;
|
StorySceneTester.borderWidth = 2;
|
||||||
level6.borderColor = Color.WHITE;
|
StorySceneTester.borderColor = Color.WHITE;
|
||||||
level6.backgroundColor = Color.TRANSPARENT;
|
StorySceneTester.backgroundColor = Color.TRANSPARENT;
|
||||||
level6.onClickEventId = "level6";
|
StorySceneTester.onClickEventId = "StorySceneTester";
|
||||||
|
|
||||||
const back = this.add.uiElement(UIElementType.BUTTON, "primary", {position: new Vec2(center.x, center.y + 250), text: "Back"});
|
const back = this.add.uiElement(UIElementType.BUTTON, "primary", {position: new Vec2(center.x, center.y + 250), text: "Back"});
|
||||||
back.size.set(200, 50);
|
back.size.set(200, 50);
|
||||||
|
@ -78,7 +79,7 @@ export default class Levels extends Scene {
|
||||||
this.receiver.subscribe("level3");
|
this.receiver.subscribe("level3");
|
||||||
this.receiver.subscribe("level4");
|
this.receiver.subscribe("level4");
|
||||||
this.receiver.subscribe("level5");
|
this.receiver.subscribe("level5");
|
||||||
this.receiver.subscribe("level6");
|
this.receiver.subscribe("StorySceneTester");
|
||||||
this.receiver.subscribe("back");
|
this.receiver.subscribe("back");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +109,8 @@ export default class Levels extends Scene {
|
||||||
this.sceneManager.changeToScene(MainMenu, {});
|
this.sceneManager.changeToScene(MainMenu, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event.type === "level6"){
|
if(event.type === "StorySceneTester"){
|
||||||
this.sceneManager.changeToScene(MainMenu, {});
|
this.sceneManager.changeToScene(StorySceneTester, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event.type === "back"){
|
if(event.type === "back"){
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
import Scene from "../../Wolfie2D/Scene/Scene";
|
|
||||||
|
|
||||||
export default class StoryMode extends Scene {
|
|
||||||
// TODO
|
|
||||||
}
|
|
101
src/shattered_sword/Scenes/StorySceneTester.ts
Normal file
101
src/shattered_sword/Scenes/StorySceneTester.ts
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import Input from "../../Wolfie2D/Input/Input";
|
||||||
|
import Scene from "../../Wolfie2D/Scene/Scene";
|
||||||
|
import Label, { HAlign } from "../../Wolfie2D/Nodes/UIElements/Label";
|
||||||
|
import Story from "../Tools/DataTypes/Story";
|
||||||
|
import { UIElementType } from "../../Wolfie2D/Nodes/UIElements/UIElementTypes";
|
||||||
|
import Vec2 from "../../Wolfie2D/DataTypes/Vec2";
|
||||||
|
import Color from "../../Wolfie2D/Utils/Color";
|
||||||
|
import Layer from "../../Wolfie2D/Scene/Layer";
|
||||||
|
import Sprite from "../../Wolfie2D/Nodes/Sprites/Sprite";
|
||||||
|
|
||||||
|
export default class StorySceneTester extends Scene {
|
||||||
|
private isInStoryMode: boolean = false;
|
||||||
|
private storytextLabel: Label;
|
||||||
|
private storyLayer: Layer;
|
||||||
|
private primary: Layer;
|
||||||
|
private story: Story;
|
||||||
|
private storyProgress: number;
|
||||||
|
private storySprites: Array<Sprite>;
|
||||||
|
private currentSpeaker: string;
|
||||||
|
private currentContent: string;
|
||||||
|
|
||||||
|
startScene(): void {
|
||||||
|
this.primary = this.addUILayer("primary");
|
||||||
|
this.storyLayer = this.addUILayer("story");
|
||||||
|
|
||||||
|
const center = this.viewport.getCenter();
|
||||||
|
const loadStory = this.add.uiElement(UIElementType.BUTTON, "primary", { position: new Vec2(center.x, center.y), text: "LoadStory" });
|
||||||
|
loadStory.size.set(200, 50);
|
||||||
|
loadStory.borderWidth = 2;
|
||||||
|
loadStory.borderColor = Color.WHITE;
|
||||||
|
loadStory.backgroundColor = Color.TRANSPARENT;
|
||||||
|
loadStory.onClickEventId = "loadStory";
|
||||||
|
|
||||||
|
|
||||||
|
this.receiver.subscribe("loadStory");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async storyLoader(storyPath: string) {
|
||||||
|
const response = await (await fetch(storyPath)).json();
|
||||||
|
this.story = <Story>response;
|
||||||
|
this.story.resources.forEach((resource) => {
|
||||||
|
switch (resource.type) {
|
||||||
|
case "image":
|
||||||
|
this.load.image(resource.key, resource.path);
|
||||||
|
break;
|
||||||
|
case "spritesheet":
|
||||||
|
this.load.spritesheet(resource.key, resource.path);
|
||||||
|
break;
|
||||||
|
case "audio":
|
||||||
|
this.load.audio(resource.key, resource.path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.currentSpeaker = this.story.texts[0].speaker;
|
||||||
|
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.textColor = Color.WHITE;
|
||||||
|
this.storytextLabel.font = "PixelSimple";
|
||||||
|
this.storytextLabel.fontSize = 20;
|
||||||
|
this.storytextLabel.setHAlign(HAlign.LEFT);
|
||||||
|
this.storyProgress = 0;
|
||||||
|
this.isInStoryMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNextStory(): boolean {
|
||||||
|
return this.isInStoryMode && this.storyProgress + 1 < this.story.texts.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStory() {
|
||||||
|
if (this.isInStoryMode && this.hasNextStory()) {
|
||||||
|
this.storyProgress ++;
|
||||||
|
this.currentSpeaker = this.story.texts[this.storyProgress].speaker;
|
||||||
|
this.currentContent = this.story.texts[this.storyProgress].content;
|
||||||
|
this.storytextLabel.text = this.currentSpeaker+':\n\n'+this.currentContent;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.isInStoryMode = false;
|
||||||
|
this.storyProgress = Infinity;
|
||||||
|
this.storytextLabel.destroy();
|
||||||
|
this.story = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScene(deltaT: number): void {
|
||||||
|
while (this.receiver.hasNextEvent()) {
|
||||||
|
let event = this.receiver.getNextEvent();
|
||||||
|
if (event.type === "loadStory" && !this.isInStoryMode) {
|
||||||
|
this.storyLoader("shattered_sword_assets/jsons/samplestory.json");
|
||||||
|
console.log("loading story");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Input.isMouseJustPressed() && this.isInStoryMode) {
|
||||||
|
this.updateStory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,10 +6,16 @@ export default class MapTemplate {
|
||||||
rooms: Array<RoomTemplate>;
|
rooms: Array<RoomTemplate>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Entrance {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
width: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class RoomTemplate {
|
export class RoomTemplate {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
bottomLayer: Array<number>;
|
bottomLayer: Array<number>;
|
||||||
topLayer: Array<number>;
|
topLayer: Array<number>;
|
||||||
entrances: Array<[x: number, y: number, width: number]>
|
entrances: Array<Entrance>;
|
||||||
}
|
}
|
23
src/shattered_sword/Tools/DataTypes/Story.ts
Normal file
23
src/shattered_sword/Tools/DataTypes/Story.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
export class Resource {
|
||||||
|
type: string;
|
||||||
|
key: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Text {
|
||||||
|
speaker: string;
|
||||||
|
content: string;
|
||||||
|
actions?: Array<Action>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Action {
|
||||||
|
type: "loadSprite" | "loadAnimatedSprite" | "move" | "show" | "hide";
|
||||||
|
key: string;
|
||||||
|
positon?: [number, number];
|
||||||
|
scale?: [number, number];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Story {
|
||||||
|
resources: Array<Resource>;
|
||||||
|
texts: Array<Text>;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user