fix: change line in text label and avoid reloading same resource

This commit is contained in:
Renge 2022-04-06 14:22:51 -04:00
parent c62bd6b209
commit ada01b6b8d
4 changed files with 114 additions and 47 deletions

View File

@ -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": [
{

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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 = <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 = <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.font = "PixelSimple";
@ -110,12 +121,20 @@ export default class SceneWithStory extends Scene {
// tmp.scale.set(action.scale[0], action.scale[1]);
// this.storySprites.push(tmp);
// });
this.load.singleImage(action.key, action.path, () => {
if (this.load.getImage(action.key)) {
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);
})
}
else {
this.load.singleImage(action.key, action.path, () => {
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);
@ -152,7 +171,7 @@ export default class SceneWithStory extends Scene {
}
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;
this.storytextLabel.text = this.currentSpeaker?(this.currentSpeaker+":"):"" + '\n' + this.currentContent;
}
else {
this.currentMode = Mode.GAME_MODE;
@ -175,7 +194,7 @@ export default class SceneWithStory extends Scene {
this.storySprites = undefined;
this.story = undefined;
this.storytextLabel = undefined;
this.storyLayer = undefined;
// this.storyLayer = undefined;
}
}