UserInterface with TextMessages implemented.

This commit is contained in:
Mal 2020-02-24 21:09:21 +01:00
parent 88d1c0db87
commit 479a150f9d
9 changed files with 167 additions and 41 deletions

View File

@ -12,7 +12,9 @@ import ImageLoader from "./ImageLoader.js";
import Level from "./Level.js"; import Level from "./Level.js";
import InterfaceEvent from "./events/InterfaceEvent.js"; import InterfaceEvent from "./events/InterfaceEvent.js";
import UrlParam from "./UrlParam.js"; import UrlParam from "./UrlParam.js";
import TextBox from "./TextBox.js"; import UserInterface from "./ui/UserInterface.js";
import TextMessageGisela from "./ui/TextMessageGisela.js";
import TextMessageMrCroc from "./ui/TextMessageMrCroc.js";
function MainLoop(timestamp) function MainLoop(timestamp)
{ {
@ -105,10 +107,7 @@ function MainLoop(timestamp)
architecture.draw(context, camera); architecture.draw(context, camera);
mrCroc.draw(context, camera); mrCroc.draw(context, camera);
gisela.draw(context, camera); gisela.draw(context, camera);
userInterface.draw(context);
if (gameFinished) {
textBoxGameFinished.draw(context, window.innerWidth * 0.5, window.innerHeight - 100);
}
lastRendered = timestamp; lastRendered = timestamp;
} }
@ -123,7 +122,8 @@ function MainLoop(timestamp)
lastTimestamp = undefined; lastTimestamp = undefined;
lastRendered = undefined; lastRendered = undefined;
textBoxGameFinished.updateLines(window.innerWidth - 40, context); textBoxGameFinished.updateLines(window.innerWidth - 40, context);
textBoxGameFinished.animate(); textBoxGameFinished.animate(75);
userInterface.addTextBox(textBoxGameFinished);
} }
window.requestAnimationFrame(MainLoop); window.requestAnimationFrame(MainLoop);
@ -157,7 +157,9 @@ let mrCroc, gisela, architecture;
let camera = new Camera(); let camera = new Camera();
let gameFinished = false; let gameFinished = false;
let hasPlayerLeftArchitecture = false; let hasPlayerLeftArchitecture = false;
let textBoxGameStart;
let textBoxGameFinished; let textBoxGameFinished;
let userInterface = new UserInterface();
let KeyLeft = new Key('ArrowLeft'); let KeyLeft = new Key('ArrowLeft');
let KeyRight = new Key('ArrowRight'); let KeyRight = new Key('ArrowRight');
@ -197,19 +199,16 @@ window.addEventListener(
); );
context = canvas.getContext('2d'); context = canvas.getContext('2d');
textBoxGameFinished = new TextBox( textBoxGameFinished = new TextMessageGisela(
'Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."', 'Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."',
window.innerWidth - 40,
context context
); );
textBoxGameFinished.font = 'Silkscreen';
textBoxGameFinished.verticalAlignment = 'bottom'; textBoxGameStart = new TextMessageMrCroc('Mr. Croc: "Where is Gisela? I have to find her!"', context);
textBoxGameFinished.alignment = 1; textBoxGameStart.animate(75, 1000);
textBoxGameFinished.hasShadow = true; textBoxGameStart.show(1000);
textBoxGameFinished.textSize = 48; textBoxGameStart.hide(10000);
textBoxGameFinished.hasBorder = true; userInterface.addTextBox(textBoxGameStart);
textBoxGameFinished.colorText = 'yellow';
textBoxGameFinished.colorBorder = 'black';
architecture = RetroArchitecture.createFromData(level); architecture = RetroArchitecture.createFromData(level);
camera.borderRight = architecture.columns * architecture.tileWidth; camera.borderRight = architecture.columns * architecture.tileWidth;

9
js/ui/TextAlignment.js Normal file
View File

@ -0,0 +1,9 @@
const TextAlignment = {
LEFT: 0,
CENTER: 1,
RIGHT: 2,
TOP: 3,
BOTTOM: 4,
};
export default TextAlignment;

View File

@ -1,20 +1,23 @@
import TextLine from "./TextLine.js"; import TextLine from "./TextLine.js";
import TextAlignment from "./TextAlignment.js";
import UserInterfaceElement from "./UserInterfaceElement.js";
export default class TextBox export default class TextBox extends UserInterfaceElement
{ {
constructor(text, width, context) constructor(text, width, context)
{ {
super();
this.text = text; this.text = text;
this.width = width; this.width = width;
this.colorText = 'red'; this.colorText = 'red';
this.colorShadow = 'black'; this.colorShadow = 'black';
this.colorBorder = 'black'; this.colorBorder = 'black';
this.hasShadow = false; this.hasShadow = true;
this.hasBorder = false; this.hasBorder = true;
this.font = 'Silkscreen'; this.font = 'Silkscreen';
this.textSize = 32; this.textSize = 48;
this.alignment = 0; this.alignment = TextAlignment.CENTER;
this.verticalAlignment = 'top'; this.verticalAlignment = TextAlignment.BOTTOM;
this.lines = []; this.lines = [];
this.updateLines(width, context); this.updateLines(width, context);
@ -26,25 +29,34 @@ export default class TextBox
this.lines = this.getLinesForWidth(this.text, context, width) this.lines = this.getLinesForWidth(this.text, context, width)
} }
animate(msForChar = 100) animate(msForChar = 100, timeoutMilliseconds = 0)
{ {
let milliseconds = 0; let milliseconds = 0;
for (let l = 0; l < this.lines.length; l++) { setTimeout(
this.lines[l].chars = 0; () => {
setTimeout( for (let l = 0; l < this.lines.length; l++) {
() => { this.lines[l].chars = 0;
this.lines[l].animate(msForChar); setTimeout(
}, milliseconds () => {
); this.lines[l].animate(msForChar);
}, milliseconds
);
milliseconds += this.lines[l].text.length * msForChar; milliseconds += this.lines[l].text.length * msForChar;
} }
}, timeoutMilliseconds
);
} }
draw(context, x, y) draw(context, x = null, y = null)
{ {
if (this.verticalAlignment === 'bottom') { if (x === null && y === null) {
x = this.position.x;
y = this.position.y;
}
if (this.verticalAlignment === TextAlignment.BOTTOM) {
let currentHeight = y; let currentHeight = y;
for (let l = this.lines.length - 1; l >= 0; l--) { for (let l = this.lines.length - 1; l >= 0; l--) {

View File

@ -1,10 +1,9 @@
import TextAlignment from "./TextAlignment.js";
export default class TextLine export default class TextLine
{ {
constructor(text) constructor(text)
{ {
this.LEFT = 0;
this.CENTER = 1;
this.RIGHT = 2;
this.text = text; this.text = text;
this.estimatedTextWidth = null; this.estimatedTextWidth = null;
this.colorText = 'red'; this.colorText = 'red';
@ -13,7 +12,7 @@ export default class TextLine
this.font = 'sans-serif'; this.font = 'sans-serif';
this.alphaText = 1.0; this.alphaText = 1.0;
this.size = 32; this.size = 32;
this.alignment = this.LEFT; this.alignment = TextAlignment.LEFT;
this.chars = this.text.length; this.chars = this.text.length;
this.hasShadow = false; this.hasShadow = false;
this.hasBorder = false; this.hasBorder = false;
@ -44,12 +43,12 @@ export default class TextLine
} }
switch (this.alignment) { switch (this.alignment) {
case this.LEFT: case TextAlignment.LEFT:
break; break;
case this.CENTER: case TextAlignment.CENTER:
x -= this.estimatedTextWidth * 0.5; x -= this.estimatedTextWidth * 0.5;
break; break;
case this.RIGHT: case TextAlignment.RIGHT:
x -= this.estimatedTextWidth; x -= this.estimatedTextWidth;
break; break;
} }

24
js/ui/TextMessage.js Normal file
View File

@ -0,0 +1,24 @@
import TextBox from "./TextBox.js";
import GeometryPoint from "../geometry/GeometryPoint.js";
export default class TextMessage extends TextBox
{
constructor(text, context) {
super(text, window.innerWidth - 40, context);
this.update();
this.context = context;
}
update()
{
this.defaultWidth = window.innerWidth - 40;
this.defaultPosition = new GeometryPoint(window.innerWidth * 0.5, window.innerHeight - 100);
}
render()
{
this.update();
this.setPosition(this.defaultPosition.x, this.defaultPosition.y);
this.updateLines(this.defaultWidth, this.context);
}
}

View File

@ -0,0 +1,10 @@
import TextMessage from "./TextMessage.js";
export default class TextMessageGisela extends TextMessage
{
constructor(text, context) {
super(text, context);
this.colorText = '#ffd400';
this.render();
}
}

View File

@ -0,0 +1,10 @@
import TextMessage from "./TextMessage.js";
export default class TextMessageMrCroc extends TextMessage
{
constructor(text, context) {
super(text, context);
this.colorText = '#15de00';
this.render();
}
}

25
js/ui/UserInterface.js Normal file
View File

@ -0,0 +1,25 @@
export default class UserInterface
{
constructor()
{
this.textBoxes = [];
}
addTextBox(textBox)
{
this.textBoxes.push(textBox);
return this.textBoxes.length - 1;
}
draw(context)
{
this.textBoxes.forEach(
(textBox) => {
if (textBox.isVisible) {
textBox.draw(context);
}
}
)
}
}

View File

@ -0,0 +1,38 @@
import GeometryPoint from "../geometry/GeometryPoint.js";
export default class UserInterfaceElement
{
constructor()
{
this.position = new GeometryPoint(0, 0);
this.isVisible = true;
}
setPosition(x, y)
{
this.position.x = x;
this.position.y = y;
}
hide(timeoutMilliseconds = 0)
{
setTimeout(
() => {
this.isVisible = false
}, timeoutMilliseconds
);
}
show(timeoutMilliseconds = 0)
{
if (timeoutMilliseconds > 0) {
this.isVisible = false;
}
setTimeout(
() => {
this.isVisible = true;
}, timeoutMilliseconds
);
}
}