diff --git a/dist/shattered_sword_assets/jsons/samplestory.json b/dist/shattered_sword_assets/jsons/samplestory.json index d584239..d39953e 100644 --- a/dist/shattered_sword_assets/jsons/samplestory.json +++ b/dist/shattered_sword_assets/jsons/samplestory.json @@ -44,7 +44,7 @@ ] }, { - "speaker": "world", + "speaker": "", "content": "this should hide the image", "actions": [ { @@ -54,7 +54,7 @@ ] }, { - "speaker": "world", + "speaker": "", "content": "this should show it again", "actions": [ { diff --git a/src/Wolfie2D/Rendering/CanvasRendering/UIElementRenderer.ts b/src/Wolfie2D/Rendering/CanvasRendering/UIElementRenderer.ts index 56c872e..503910e 100644 --- a/src/Wolfie2D/Rendering/CanvasRendering/UIElementRenderer.ts +++ b/src/Wolfie2D/Rendering/CanvasRendering/UIElementRenderer.ts @@ -15,7 +15,7 @@ export default class UIElementRenderer { protected scene: Scene; protected ctx: CanvasRenderingContext2D; - constructor(ctx: CanvasRenderingContext2D){ + constructor(ctx: CanvasRenderingContext2D) { this.resourceManager = ResourceManager.getInstance(); this.ctx = ctx; } @@ -33,33 +33,81 @@ export default class UIElementRenderer { * @param label The label to render */ renderLabel(label: Label): void { + // // If the size is unassigned (by the user or automatically) assign it + // label.handleInitialSizing(this.ctx); + + // // Grab the global alpha so we can adjust it for this render + // let previousAlpha = this.ctx.globalAlpha; + + // // Get the font and text position in label + // this.ctx.font = label.getFontString(); + // let offset = label.calculateTextOffset(this.ctx); + + // // Stroke and fill a rounded rect and give it text + // this.ctx.globalAlpha = label.backgroundColor.a; + // this.ctx.fillStyle = label.calculateBackgroundColor().toStringRGBA(); + // this.ctx.fillRoundedRect(-label.size.x/2, -label.size.y/2, + // label.size.x, label.size.y, label.borderRadius); + + // this.ctx.strokeStyle = label.calculateBorderColor().toStringRGBA(); + // this.ctx.globalAlpha = label.borderColor.a; + // this.ctx.lineWidth = label.borderWidth; + // this.ctx.strokeRoundedRect(-label.size.x/2, -label.size.y/2, + // label.size.x, label.size.y, label.borderRadius); + + // this.ctx.fillStyle = label.calculateTextColor(); + // this.ctx.globalAlpha = label.textColor.a; + // this.ctx.fillText(label.text, offset.x - label.size.x/2, offset.y - label.size.y/2); + + // this.ctx.globalAlpha = previousAlpha; // If the size is unassigned (by the user or automatically) assign it + let lines = label.text.split('\n'); + let tempText = label.text; + if (lines.length > 1) { + let max = 0; + let maxLengthIndex = 0; + for (let i = 0; i < lines.length; i++) { + if (lines[i].length > max) { + max = lines[i].length; + maxLengthIndex = i; + } + } + label.text = lines[maxLengthIndex]; + } label.handleInitialSizing(this.ctx); - - // Grab the global alpha so we can adjust it for this render - let previousAlpha = this.ctx.globalAlpha; + // Grab the global alpha so we can adjust it for this render + let previousAlpha = this.ctx.globalAlpha; // Get the font and text position in label - this.ctx.font = label.getFontString(); - let offset = label.calculateTextOffset(this.ctx); + this.ctx.font = label.getFontString(); + let offset = label.calculateTextOffset(this.ctx); - // Stroke and fill a rounded rect and give it text - this.ctx.globalAlpha = label.backgroundColor.a; - this.ctx.fillStyle = label.calculateBackgroundColor().toStringRGBA(); - this.ctx.fillRoundedRect(-label.size.x/2, -label.size.y/2, - label.size.x, label.size.y, label.borderRadius); - - this.ctx.strokeStyle = label.calculateBorderColor().toStringRGBA(); - this.ctx.globalAlpha = label.borderColor.a; - this.ctx.lineWidth = label.borderWidth; - this.ctx.strokeRoundedRect(-label.size.x/2, -label.size.y/2, - label.size.x, label.size.y, label.borderRadius); + // Stroke and fill a rounded rect and give it text + this.ctx.globalAlpha = label.backgroundColor.a; + this.ctx.fillStyle = label.calculateBackgroundColor().toStringRGBA(); + this.ctx.fillRoundedRect(-label.size.x / 2, -label.size.y / 2, + label.size.x, label.size.y, label.borderRadius); - this.ctx.fillStyle = label.calculateTextColor(); - this.ctx.globalAlpha = label.textColor.a; - this.ctx.fillText(label.text, offset.x - label.size.x/2, offset.y - label.size.y/2); - - this.ctx.globalAlpha = previousAlpha; + this.ctx.strokeStyle = label.calculateBorderColor().toStringRGBA(); + this.ctx.globalAlpha = label.borderColor.a; + this.ctx.lineWidth = label.borderWidth; + this.ctx.strokeRoundedRect(-label.size.x / 2, -label.size.y / 2, + label.size.x, label.size.y + ((lines.length - 1) * label.fontSize), label.borderRadius); + + this.ctx.fillStyle = label.calculateTextColor(); + this.ctx.globalAlpha = label.textColor.a; + if (lines.length === 1) { + this.ctx.fillText(label.text, offset.x - label.size.x / 2, (offset.y - label.size.y / 2)); + } else { + for (let i = 0; i < lines.length; i++) { + let additionalY = i * (label.size.y / 2 + (label.fontSize === 40 ? 20 : 10)); + label.text = lines[i]; + offset = label.calculateTextOffset(this.ctx); + this.ctx.fillText(lines[i], (offset.x - label.size.x / 2), (offset.y - label.size.y / 2 + additionalY)); + } + } + this.ctx.globalAlpha = previousAlpha; + label.text = tempText; } /** @@ -75,24 +123,24 @@ export default class UIElementRenderer { * @param slider The slider to render */ renderSlider(slider: Slider): void { - // Grab the global alpha so we can adjust it for this render - let previousAlpha = this.ctx.globalAlpha; - this.ctx.globalAlpha = slider.getLayer().getAlpha(); + // Grab the global alpha so we can adjust it for this render + let previousAlpha = this.ctx.globalAlpha; + this.ctx.globalAlpha = slider.getLayer().getAlpha(); // Calcualate the slider size let sliderSize = new Vec2(slider.size.x, 2); // Draw the slider - this.ctx.fillStyle = slider.sliderColor.toString(); - this.ctx.fillRoundedRect(-sliderSize.x/2, -sliderSize.y/2, + this.ctx.fillStyle = slider.sliderColor.toString(); + this.ctx.fillRoundedRect(-sliderSize.x / 2, -sliderSize.y / 2, sliderSize.x, sliderSize.y, slider.borderRadius); // Calculate the nib size and position - let x = MathUtils.lerp(-slider.size.x/2, slider.size.x/2, slider.getValue()); + let x = MathUtils.lerp(-slider.size.x / 2, slider.size.x / 2, slider.getValue()); // Draw the nib - this.ctx.fillStyle = slider.nibColor.toString(); - this.ctx.fillRoundedRect(x-slider.nibSize.x/2, -slider.nibSize.y/2, + this.ctx.fillStyle = slider.nibColor.toString(); + this.ctx.fillRoundedRect(x - slider.nibSize.x / 2, -slider.nibSize.y / 2, slider.nibSize.x, slider.nibSize.y, slider.borderRadius); // Reset the alpha @@ -105,19 +153,19 @@ export default class UIElementRenderer { */ renderTextInput(textInput: TextInput): void { // Show a cursor sometimes - if(textInput.focused && textInput.cursorCounter % 60 > 30){ + if (textInput.focused && textInput.cursorCounter % 60 > 30) { textInput.text += "|"; } this.renderLabel(textInput); - if(textInput.focused){ - if(textInput.cursorCounter % 60 > 30){ + if (textInput.focused) { + if (textInput.cursorCounter % 60 > 30) { textInput.text = textInput.text.substring(0, textInput.text.length - 1); } textInput.cursorCounter += 1; - if(textInput.cursorCounter >= 60){ + if (textInput.cursorCounter >= 60) { textInput.cursorCounter = 0; } } diff --git a/src/Wolfie2D/ResourceManager/ResourceManager.ts b/src/Wolfie2D/ResourceManager/ResourceManager.ts index 96b749b..7870df1 100644 --- a/src/Wolfie2D/ResourceManager/ResourceManager.ts +++ b/src/Wolfie2D/ResourceManager/ResourceManager.ts @@ -198,9 +198,9 @@ export default class ResourceManager { */ public getImage(key: string): HTMLImageElement { let image = this.images.get(key); - if (image === undefined) { - throw `There is no image associated with key "${key}"` - } + // if (image === undefined) { + // throw `There is no image associated with key "${key}"` + // } return image; } diff --git a/src/shattered_sword/Scenes/SceneWithStory.ts b/src/shattered_sword/Scenes/SceneWithStory.ts index 77fed97..a864940 100644 --- a/src/shattered_sword/Scenes/SceneWithStory.ts +++ b/src/shattered_sword/Scenes/SceneWithStory.ts @@ -41,6 +41,8 @@ export default class SceneWithStory extends Scene { loadStory.borderColor = Color.WHITE; loadStory.backgroundColor = Color.TRANSPARENT; loadStory.onClickEventId = "loadStory"; + this.storyLayer = this.addUILayer("story"); + this.storyLayer.disable(); this.receiver.subscribe("loadStory"); @@ -53,9 +55,12 @@ export default class SceneWithStory extends Scene { * @param storyPath The path to the story JSON */ async storyLoader(storyPath: string) { - this.storyLayer = this.addUILayer("story"); + // I may want to load multiple stories in a single scene, but this + // Layer with name story already exists + // so can i detect whether this layer exists? const response = await (await fetch(storyPath)).json(); this.story = response; + console.log("story:", this.story); if (this.story.bgm) { this.storyBGMs = new Array; this.story.bgm.forEach((bgm) => { @@ -65,15 +70,21 @@ export default class SceneWithStory extends Scene { // console.log("finished loading audio"); // this.emitter.fireEvent(GameEventType.PLAY_SOUND, { key: bgm.key, loop: false, holdReference: true }); // }); - this.load.singleAudio(bgm.key, bgm.path, () => { + + if (this.load.getAudio(bgm.key)) { this.emitter.fireEvent(GameEventType.PLAY_SOUND, { key: bgm.key, loop: false, holdReference: true }); - }) + } + else { + this.load.singleAudio(bgm.key, bgm.path, () => { + this.emitter.fireEvent(GameEventType.PLAY_SOUND, { key: bgm.key, loop: false, holdReference: true }); + }) + } this.storyBGMs.push(bgm.key); }) } this.currentSpeaker = this.story.texts[0].speaker; this.currentContent = this.story.texts[0].content; - + this.storyLayer.enable(); this.storytextLabel =