TextBox implemented and cleaning.

This commit is contained in:
Mal 2020-02-24 00:19:21 +01:00
parent bd5ec13ea3
commit 3ffc786989
7 changed files with 220 additions and 9 deletions

View File

@ -4,11 +4,16 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Mr. Crocs Adventures</title> <title>Mr. Crocs Adventures</title>
<style> <style>
@font-face {
font-family: Silkscreen;
src: url("fonts/slkscr.ttf")
}
#canvas { #canvas {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
background-color: #6096ff; cursor: none;
} }
</style> </style>
<link rel="shortcut icon" type="image/png" href="favicon.png"> <link rel="shortcut icon" type="image/png" href="favicon.png">

View File

@ -79,8 +79,6 @@ export default class FrameRateMeasurer
} }
); );
console.log(this.frameDurations);
return closestDistance.frameRate; return closestDistance.frameRate;
} }
} }

106
js/TextBox.js Normal file
View File

@ -0,0 +1,106 @@
import TextLine from "./TextLine.js";
export default class TextBox
{
constructor(text, width, context)
{
this.text = text;
this.width = width;
this.colorText = 'red';
this.colorShadow = 'black';
this.colorBorder = 'black';
this.hasShadow = false;
this.hasBorder = false;
this.font = 'Silkscreen';
this.textSize = 32;
this.alignment = 0;
this.verticalAlignment = 'top';
this.lines = [];
this.updateLines(width, context);
}
updateLines(width, context)
{
context.font = this.textSize + 'px ' + this.font;
this.lines = this.getLinesForWidth(this.text, context, width)
}
animate(msForChar = 100)
{
let milliseconds = 0;
for (let l = 0; l < this.lines.length; l++) {
this.lines[l].chars = 0;
setTimeout(
() => {
this.lines[l].animate(msForChar);
}, milliseconds
);
milliseconds += this.lines[l].text.length * msForChar;
}
}
draw(context, x, y)
{
if (this.verticalAlignment === 'bottom') {
let currentHeight = y;
for (let l = this.lines.length - 1; l >= 0; l--) {
if (this.lines[l].chars > 0) {
this.lines[l].draw(context, x, currentHeight);
currentHeight -= this.textSize;
}
}
return;
}
this.lines.forEach(
(line, index) => {
line.draw(context, x, y + this.textSize * index);
}
)
}
getLinesForWidth(text, context, width)
{
let words = text.split(' ');
let lines = [];
let buffer = words[0];
for (let w = 1; w < words.length; w++) {
let bufferNew = buffer === '' ? words[w] : buffer + ' ' + words[w];
if (context.measureText(bufferNew).width > width) {
lines.push(this.getLine(buffer));
bufferNew = words[w];
}
buffer = bufferNew;
}
if (buffer !== '') {
lines.push(this.getLine(buffer));
}
return lines;
}
getLine(text)
{
let line = new TextLine(text);
line.font = this.font;
line.size = this.textSize;
line.colorText = this.colorText;
line.colorShadow = this.colorShadow;
line.alignment = this.alignment;
line.hasShadow = this.hasShadow;
line.hasBorder = this.hasBorder;
line.colorBorder = this.colorBorder;
return line;
}
}

87
js/TextLine.js Normal file
View File

@ -0,0 +1,87 @@
export default class TextLine
{
constructor(text)
{
this.LEFT = 0;
this.CENTER = 1;
this.RIGHT = 2;
this.text = text;
this.estimatedTextWidth = null;
this.colorText = 'red';
this.colorShadow = 'black';
this.colorBorder = 'black';
this.font = 'sans-serif';
this.alphaText = 1.0;
this.size = 32;
this.alignment = this.LEFT;
this.chars = this.text.length;
this.hasShadow = false;
this.hasBorder = false;
}
animate(msPerChar = 100)
{
this.chars = 0;
let process = setInterval(
() => {
this.chars++;
if (this.chars === this.text.length) {
clearInterval(process);
}
}, msPerChar
);
}
draw(context, x, y)
{
context.font = this.size + 'px ' + this.font;
context.globalAlpha = this.alphaText;
if (this.estimatedTextWidth === null) {
this.estimatedTextWidth = Math.ceil(context.measureText(this.text).width);
}
switch (this.alignment) {
case this.LEFT:
break;
case this.CENTER:
x -= this.estimatedTextWidth * 0.5;
break;
case this.RIGHT:
x -= this.estimatedTextWidth;
break;
}
this.drawShadow(context, x, y);
let text = this.text;
if (this.chars !== null && this.chars < this.text.length) {
text = this.text.substr(0, this.chars);
}
context.fillStyle = this.colorText;
context.fillText(text, x, y + this.size);
this.drawBorder(context, x, y, text);
}
drawBorder(context, x, y, text)
{
if (this.hasBorder) {
context.strokeStyle = this.colorBorder;
context.strokeWidth = '1px';
context.strokeText(text, x, y + this.size);
}
}
drawShadow(context, x, y)
{
if (this.hasShadow) {
context.fillStyle = this.colorShadow;
context.fillText(this.text.substr(0, this.chars), x + 2, y + this.size + 2);
}
}
}

View File

@ -3,7 +3,6 @@ export default class UrlParam
constructor() constructor()
{ {
this.url = document.location.toString(); this.url = document.location.toString();
console.log(this.url);
this.params = UrlParam.getParamsFromUrl(this.url); this.params = UrlParam.getParamsFromUrl(this.url);
} }

View File

@ -12,6 +12,7 @@ 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";
function MainLoop(timestamp) function MainLoop(timestamp)
{ {
@ -101,11 +102,14 @@ function MainLoop(timestamp)
/* Drawing */ /* Drawing */
if (timestamp - lastRendered >= frameDuration) { if (timestamp - lastRendered >= frameDuration) {
context.clearRect(0, 0, window.innerWidth, window.innerHeight); context.clearRect(0, 0, window.innerWidth, window.innerHeight);
architecture.draw(context, camera); architecture.draw(context, camera);
mrCroc.draw(context, camera); mrCroc.draw(context, camera);
gisela.draw(context, camera); gisela.draw(context, camera);
if (gameFinished) {
textBoxGameFinished.draw(context, window.innerWidth * 0.5, window.innerHeight - 100);
}
lastRendered = timestamp; lastRendered = timestamp;
} }
@ -118,8 +122,7 @@ function MainLoop(timestamp)
KeyJump.pressed = false; KeyJump.pressed = false;
lastTimestamp = undefined; lastTimestamp = undefined;
lastRendered = undefined; lastRendered = undefined;
textBoxGameFinished.animate();
alert('Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."');
} }
window.requestAnimationFrame(MainLoop); window.requestAnimationFrame(MainLoop);
@ -153,6 +156,7 @@ 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 textBoxGameFinished;
let KeyLeft = new Key('ArrowLeft'); let KeyLeft = new Key('ArrowLeft');
let KeyRight = new Key('ArrowRight'); let KeyRight = new Key('ArrowRight');
@ -192,6 +196,20 @@ window.addEventListener(
); );
context = canvas.getContext('2d'); context = canvas.getContext('2d');
textBoxGameFinished = new TextBox(
'Gisela: "Thanks for showing up, Mr. Croc, but I\'m not in danger."',
window.innerWidth - 40,
context
);
textBoxGameFinished.font = 'Silkscreen';
textBoxGameFinished.verticalAlignment = 'bottom';
textBoxGameFinished.alignment = 1;
textBoxGameFinished.hasShadow = true;
textBoxGameFinished.textSize = 48;
textBoxGameFinished.hasBorder = true;
textBoxGameFinished.colorText = 'yellow';
textBoxGameFinished.colorBorder = 'black';
textBoxGameFinished.updateLines(window.innerWidth - 40, context);
architecture = RetroArchitecture.createFromData(level); architecture = RetroArchitecture.createFromData(level);
camera.borderRight = architecture.columns * architecture.tileWidth; camera.borderRight = architecture.columns * architecture.tileWidth;
@ -206,7 +224,6 @@ window.addEventListener(
window.addEventListener( window.addEventListener(
InterfaceEvent.FRAME_RATE_MEASURED, InterfaceEvent.FRAME_RATE_MEASURED,
(event) => { (event) => {
console.log(event);
fps = event.frameRate; fps = event.frameRate;
frameDuration = 1000 / fps; frameDuration = 1000 / fps;
window.requestAnimationFrame(MainLoop); window.requestAnimationFrame(MainLoop);

View File

@ -31,7 +31,6 @@ export default class DialogNewTerrain extends Dialog
TilorswiftEvent.TILESET_SELECTED, TilorswiftEvent.TILESET_SELECTED,
(event) => { (event) => {
this.terrainIndex = event.tilesetIndex; this.terrainIndex = event.tilesetIndex;
console.log(event.tilesetIndex);
} }
); );
} }