newRound() and Game Over
+ Bit Font for score + improved API for move and collision + miscs
This commit is contained in:
12
memo.txt
Normal file
12
memo.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
- ball speed up
|
||||||
|
- on newRound()
|
||||||
|
- speed reset
|
||||||
|
- ball direction based on player hit location
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- node.js server for http access (and javascipt modules files split)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- gamesocket with node.js
|
||||||
BIN
src/Bit5x3.woff
Normal file
BIN
src/Bit5x3.woff
Normal file
Binary file not shown.
BIN
src/Bit5x3.woff2
Normal file
BIN
src/Bit5x3.woff2
Normal file
Binary file not shown.
@@ -3,6 +3,14 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<style>
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Bit5x3';
|
||||||
|
src: url('Bit5x3.woff2') format('woff2'),
|
||||||
|
url('Bit5x3.woff') format('woff');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #222425;
|
background-color: #222425;
|
||||||
|
|||||||
355
src/pong.ts
355
src/pong.ts
@@ -3,6 +3,7 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
let gridDisplay = false;
|
let gridDisplay = false;
|
||||||
|
let ballInPlay = true;
|
||||||
|
|
||||||
let pong: gameArea;
|
let pong: gameArea;
|
||||||
|
|
||||||
@@ -11,8 +12,8 @@ let wall_bottom: Rectangle;
|
|||||||
let player1: Player;
|
let player1: Player;
|
||||||
let player2: Player;
|
let player2: Player;
|
||||||
let ball: Ball;
|
let ball: Ball;
|
||||||
let score1: TextElem;
|
let score1: TextNumericValue;
|
||||||
let score2: TextElem;
|
let score2: TextNumericValue;
|
||||||
let midLine: Line;
|
let midLine: Line;
|
||||||
|
|
||||||
let w_grid_mid: Rectangle;
|
let w_grid_mid: Rectangle;
|
||||||
@@ -29,46 +30,64 @@ function startGame()
|
|||||||
// Const
|
// Const
|
||||||
const w = pong.canvas.width;
|
const w = pong.canvas.width;
|
||||||
const h = pong.canvas.height;
|
const h = pong.canvas.height;
|
||||||
const w_mid = w/2;
|
const w_mid = Math.floor(w/2);
|
||||||
const h_mid = h/2;
|
const h_mid = Math.floor(h/2);
|
||||||
const pw = w/50;
|
const pw = Math.floor(w/50);
|
||||||
const ph = pw*5;
|
const ph = pw*5;
|
||||||
const ball_size = pw; // const ball_size = w/50;
|
const ballSize = pw;
|
||||||
const score_size = w/16;
|
const scoreSize = Math.floor(w/16);
|
||||||
const midLineSize = w/150;
|
const midLineSize = Math.floor(w/150);
|
||||||
const wall_size = w/100;
|
const wallSize = Math.floor(w/100);
|
||||||
const grid_size = w/500;
|
const gridSize = Math.floor(w/500);
|
||||||
const playerSpeed = w/75;
|
const playerSpeed = Math.floor(w/75);
|
||||||
const ballSpeed = w/75;
|
const ballSpeed = Math.floor(w/75);
|
||||||
|
|
||||||
|
let pos = new VectorInteger();
|
||||||
// Component
|
// Component
|
||||||
wall_top = new Rectangle({x: 0, y: 0}, "grey", w, wall_size);
|
pos.x = 0; pos.y = 0;
|
||||||
wall_bottom = new Rectangle({x: 0, y: h-wall_size}, "grey", w, wall_size);
|
wall_top = new Rectangle(pos, "grey", w, wallSize);
|
||||||
|
pos.x = 0; pos.y = h-wallSize;
|
||||||
|
wall_bottom = new Rectangle(pos, "grey", w, wallSize);
|
||||||
|
|
||||||
player1 = new Player({x: 0+pw, y: h_mid-ph/2}, "white", pw, ph);
|
pos.x = 0+pw; pos.y = h_mid-ph/2;
|
||||||
player2 = new Player({x: w-pw-pw, y: h_mid-ph/2}, "white", pw, ph);
|
player1 = new Player(pos, "white", pw, ph);
|
||||||
|
pos.x = w-pw-pw; pos.y = h_mid-ph/2;
|
||||||
|
player2 = new Player(pos, "white", pw, ph);
|
||||||
player1.speed = playerSpeed;
|
player1.speed = playerSpeed;
|
||||||
player2.speed = playerSpeed;
|
player2.speed = playerSpeed;
|
||||||
|
|
||||||
ball = new Ball({x: w_mid-ball_size/2, y: h_mid-ball_size/2}, "white", ball_size);
|
pos.x = w_mid-ballSize/2; pos.y = h_mid-ballSize/2;
|
||||||
|
ball = new Ball(pos, "white", ballSize);
|
||||||
ball.speed = ballSpeed;
|
ball.speed = ballSpeed;
|
||||||
ball.dir.x = -0.8;
|
ball.dir.x = -0.8;
|
||||||
ball.dir.y = +0.2;
|
ball.dir.y = +0.2;
|
||||||
|
|
||||||
score1 = new TextElem({x: w_mid-w/8, y: w/12}, "white", score_size+"px");
|
pos.x = w_mid-w/8; pos.y = w/12;
|
||||||
score1.text = "0";
|
score1 = new TextNumericValue(pos, "white", scoreSize);
|
||||||
score2 = new TextElem({x: w_mid+w/8-score_size/2, y: w/12}, "white", score_size+"px");
|
pos.x = w_mid+w/8-scoreSize/2; pos.y = w/12;
|
||||||
score2.text = "0";
|
score2 = new TextNumericValue(pos, "white", scoreSize);
|
||||||
|
score1.value = 0;
|
||||||
|
score2.value = 0;
|
||||||
|
|
||||||
midLine = new Line({x: w_mid-midLineSize/2, y: 0+wall_size}, "white", midLineSize, h-wall_size*2, 15);
|
pos.x = w_mid-midLineSize/2; pos.y = 0+wallSize;
|
||||||
|
midLine = new Line(pos, "white", midLineSize, h-wallSize*2, 15);
|
||||||
|
|
||||||
// Grid
|
// Grid
|
||||||
w_grid_mid = new Rectangle({x: 0, y: h_mid}, "darkgreen", w, grid_size);
|
pos.x = 0; pos.y = h_mid;
|
||||||
w_grid_u1 = new Rectangle({x: 0, y: h/4}, "darkgreen", w, grid_size);
|
w_grid_mid = new Rectangle(pos, "darkgreen", w, gridSize);
|
||||||
w_grid_d1 = new Rectangle({x: 0, y: h-h/4}, "darkgreen", w, grid_size);
|
pos.x = 0; pos.y = h/4;
|
||||||
h_grid_mid = new Rectangle({x: w_mid, y: 0}, "darkgreen", grid_size, h);
|
w_grid_u1 = new Rectangle(pos, "darkgreen", w, gridSize);
|
||||||
h_grid_u1 = new Rectangle({x: w/4, y: 0}, "darkgreen", grid_size, h);
|
pos.x = 0; pos.y = h-h/4;
|
||||||
h_grid_d1 = new Rectangle({x: w-w/4, y: 0}, "darkgreen", grid_size, h);
|
w_grid_d1 = new Rectangle(pos, "darkgreen", w, gridSize);
|
||||||
|
pos.x = w_mid; pos.y = 0;
|
||||||
|
h_grid_mid = new Rectangle(pos, "darkgreen", gridSize, h);
|
||||||
|
pos.x = w/4; pos.y = 0;
|
||||||
|
h_grid_u1 = new Rectangle(pos, "darkgreen", gridSize, h);
|
||||||
|
pos.x = w-w/4; pos.y = 0;
|
||||||
|
h_grid_d1 = new Rectangle(pos, "darkgreen", gridSize, h);
|
||||||
|
|
||||||
|
score1.update(); // first Text draw init the custom font (graphic leftover ortherwise) (a better solution ?)
|
||||||
|
drawInit();
|
||||||
|
|
||||||
pong.start();
|
pong.start();
|
||||||
}
|
}
|
||||||
@@ -110,7 +129,6 @@ class gameArea {
|
|||||||
pong.keys.splice(i, 1);
|
pong.keys.splice(i, 1);
|
||||||
}
|
}
|
||||||
clear() {
|
clear() {
|
||||||
// @ts-ignore
|
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
}
|
}
|
||||||
stop() {
|
stop() {
|
||||||
@@ -118,48 +136,84 @@ class gameArea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad drawLine, TODO make a drawLine with fillRect()
|
|
||||||
// function drawLine(start, end, color, pattern)
|
|
||||||
// {
|
|
||||||
// let ctx = pong.ctx;
|
|
||||||
// ctx.beginPath();
|
|
||||||
// ctx.setLineDash(pattern);
|
|
||||||
// ctx.moveTo(start[0], start[1]);
|
|
||||||
// ctx.lineTo(end[0], end[1]);
|
|
||||||
// ctx.strokeStyle = color;
|
|
||||||
// ctx.stroke();
|
|
||||||
// }
|
|
||||||
|
|
||||||
function gameLoop()
|
function gameLoop()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
// I try to clear only what need to be update.
|
||||||
|
// Will revert to clear() all if not satisfactory.
|
||||||
|
pong.clear();
|
||||||
|
*/
|
||||||
handleInput();
|
handleInput();
|
||||||
|
|
||||||
ball.move();
|
if (ballInPlay)
|
||||||
if (ball.collision(wall_top) || ball.collision(wall_bottom))
|
{
|
||||||
ball.bounce();
|
ball.moveAndBounce([wall_top, wall_bottom, player1, player2]);
|
||||||
else if (ball.collision(player1))
|
if (ball.pos.x > pong.canvas.width) {
|
||||||
ball.bounce(player1);
|
ballInPlay = false;
|
||||||
else if (ball.collision(player2))
|
score1.clear();
|
||||||
ball.bounce(player2);
|
++score1.value;
|
||||||
|
setTimeout(newRound, 1000);
|
||||||
|
}
|
||||||
|
else if (ball.pos.x < 0 - ball.width) {
|
||||||
|
ballInPlay = false;
|
||||||
|
score2.clear();
|
||||||
|
++score2.value;
|
||||||
|
setTimeout(newRound, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function newRound()
|
||||||
|
{
|
||||||
|
// https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches
|
||||||
|
if (score1.value >= 11
|
||||||
|
|| score2.value >= 11)
|
||||||
|
{
|
||||||
|
if (Math.abs(score1.value - score2.value) >= 2)
|
||||||
|
{
|
||||||
|
if (score1.value > score2.value) {
|
||||||
|
alert("Player 1 WIN");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("Player 2 WIN");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ballInPlay = true;
|
||||||
|
ball.pos.x = pong.canvas.width/2;
|
||||||
|
ball.pos.y = pong.canvas.height/4 + Math.floor(random() * pong.canvas.height/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function random(min: number = 0, max: number = 1) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
function draw()
|
function draw()
|
||||||
{
|
{
|
||||||
pong.clear();
|
if (gridDisplay) {
|
||||||
|
|
||||||
if (gridDisplay)
|
|
||||||
drawGrid();
|
drawGrid();
|
||||||
|
}
|
||||||
|
midLine.update();
|
||||||
|
score1.update();
|
||||||
|
score2.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawStatic()
|
||||||
|
{
|
||||||
wall_top.update();
|
wall_top.update();
|
||||||
wall_bottom.update();
|
wall_bottom.update();
|
||||||
midLine.update();
|
midLine.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawInit()
|
||||||
|
{
|
||||||
|
pong.clear();
|
||||||
|
drawStatic();
|
||||||
player1.update();
|
player1.update();
|
||||||
player2.update();
|
player2.update();
|
||||||
ball.update();
|
|
||||||
score1.update();
|
|
||||||
score2.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawGrid()
|
function drawGrid()
|
||||||
@@ -181,6 +235,11 @@ function handleInput()
|
|||||||
|
|
||||||
if (keys.indexOf("g") != -1)
|
if (keys.indexOf("g") != -1)
|
||||||
{
|
{
|
||||||
|
if (gridDisplay)
|
||||||
|
{
|
||||||
|
pong.clear();
|
||||||
|
drawStatic();
|
||||||
|
}
|
||||||
gridDisplay = !gridDisplay;
|
gridDisplay = !gridDisplay;
|
||||||
pong.deleteKey("g");
|
pong.deleteKey("g");
|
||||||
}
|
}
|
||||||
@@ -190,28 +249,22 @@ function handleInput()
|
|||||||
function playerMove(keys: string[])
|
function playerMove(keys: string[])
|
||||||
{
|
{
|
||||||
player1.dir.y = 0;
|
player1.dir.y = 0;
|
||||||
if (keys.indexOf("w") != -1)
|
if (keys.indexOf("w") != -1) {
|
||||||
{ player1.dir.y += -1; }
|
player1.dir.y += -1;
|
||||||
if (keys.indexOf("s") != -1)
|
|
||||||
{ player1.dir.y += 1; }
|
|
||||||
player1.move();
|
|
||||||
if (player1.collision(wall_top) || player1.collision(wall_bottom))
|
|
||||||
{
|
|
||||||
player1.dir.y = player1.dir.y * -1;
|
|
||||||
player1.move();
|
|
||||||
}
|
}
|
||||||
|
if (keys.indexOf("s") != -1) {
|
||||||
|
player1.dir.y += 1;
|
||||||
|
}
|
||||||
|
player1.moveAndCollide([wall_top, wall_bottom]);
|
||||||
|
|
||||||
player2.dir.y = 0;
|
player2.dir.y = 0;
|
||||||
if (keys.indexOf("ArrowUp".toLowerCase()) != -1)
|
if (keys.indexOf("ArrowUp".toLowerCase()) != -1) {
|
||||||
{ player2.dir.y += -1; }
|
player2.dir.y += -1;
|
||||||
if (keys.indexOf("ArrowDown".toLowerCase()) != -1)
|
|
||||||
{ player2.dir.y += 1; }
|
|
||||||
player2.move();
|
|
||||||
if (player2.collision(wall_top) || player2.collision(wall_bottom))
|
|
||||||
{
|
|
||||||
player2.dir.y = player2.dir.y * -1;
|
|
||||||
player2.move();
|
|
||||||
}
|
}
|
||||||
|
if (keys.indexOf("ArrowDown".toLowerCase()) != -1) {
|
||||||
|
player2.dir.y += 1;
|
||||||
|
}
|
||||||
|
player2.moveAndCollide([wall_top, wall_bottom]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -219,27 +272,66 @@ function playerMove(keys: string[])
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// class.js
|
// class.js
|
||||||
|
|
||||||
type Vector = {
|
// type Vector = {
|
||||||
|
// x: number;
|
||||||
|
// y: number;
|
||||||
|
// }
|
||||||
|
|
||||||
|
class Vector {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
constructor(x: number = 0, y: number = 0) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class VectorInteger extends Vector {
|
||||||
|
// PLACEHOLDER
|
||||||
|
// VectorInteger with set/get dont work (No draw on the screen). Why ?
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
class VectorInteger {
|
||||||
|
// private _x: number = 0;
|
||||||
|
// private _y: number = 0;
|
||||||
|
// constructor(x: number = 0, y: number = 0) {
|
||||||
|
// this._x = x;
|
||||||
|
// this._y = y;
|
||||||
|
// }
|
||||||
|
// get x(): number {
|
||||||
|
// return this._x;
|
||||||
|
// }
|
||||||
|
// set x(v: number) {
|
||||||
|
// // this._x = Math.floor(v);
|
||||||
|
// this._x = v;
|
||||||
|
// }
|
||||||
|
// get y(): number {
|
||||||
|
// return this._y;
|
||||||
|
// }
|
||||||
|
// set y(v: number) {
|
||||||
|
// // this._y = Math.floor(v);
|
||||||
|
// this._y = v;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
interface Component {
|
interface Component {
|
||||||
pos: Vector;
|
pos: VectorInteger;
|
||||||
color: string;
|
color: string;
|
||||||
// ctx: CanvasRenderingContext2D;
|
// ctx: CanvasRenderingContext2D; // TODO: reference in place of global 'pong.ctx' call
|
||||||
update(): void;
|
update(): void;
|
||||||
|
clear(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Rectangle implements Component {
|
class Rectangle implements Component {
|
||||||
pos: Vector;
|
pos: VectorInteger;
|
||||||
color: string;
|
color: string;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
constructor(pos: Vector, color: string, width: number, height: number) {
|
constructor(pos: VectorInteger, color: string, width: number, height: number) {
|
||||||
this.pos = pos;
|
this.pos = Object.assign({}, pos);
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@@ -249,6 +341,13 @@ class Rectangle implements Component {
|
|||||||
ctx.fillStyle = this.color;
|
ctx.fillStyle = this.color;
|
||||||
ctx.fillRect(this.pos.x, this.pos.y, this.width, this.height);
|
ctx.fillRect(this.pos.x, this.pos.y, this.width, this.height);
|
||||||
}
|
}
|
||||||
|
clear(pos?: VectorInteger) {
|
||||||
|
let ctx = pong.ctx;
|
||||||
|
if (pos)
|
||||||
|
ctx.clearRect(pos.x, pos.y, this.width, this.height);
|
||||||
|
else
|
||||||
|
ctx.clearRect(this.pos.x, this.pos.y, this.width, this.height);
|
||||||
|
}
|
||||||
collision(collider: Rectangle): boolean { // Collision WIP. To redo
|
collision(collider: Rectangle): boolean { // Collision WIP. To redo
|
||||||
var myleft = this.pos.x;
|
var myleft = this.pos.x;
|
||||||
var myright = this.pos.x + (this.width);
|
var myright = this.pos.x + (this.width);
|
||||||
@@ -277,35 +376,65 @@ interface Moving {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Player extends Rectangle implements Moving {
|
class MovingRectangle extends Rectangle implements Moving {
|
||||||
dir: Vector = {x: 0.0, y: 0.0};
|
dir: Vector = {x: 0.0, y: 0.0};
|
||||||
speed: number = 1;
|
speed: number = 1;
|
||||||
constructor(pos: Vector, color: string, width: number, height: number) {
|
constructor(pos: VectorInteger, color: string, width: number, height: number) {
|
||||||
super(pos, color, width, height);
|
super(pos, color, width, height);
|
||||||
}
|
}
|
||||||
move() {
|
move() {
|
||||||
this.pos.x += this.dir.x * this.speed;
|
this.pos.x += this.dir.x * this.speed;
|
||||||
this.pos.y += this.dir.y * this.speed;
|
this.pos.y += this.dir.y * this.speed;
|
||||||
}
|
}
|
||||||
|
moveAndCollide(colliderArr: Rectangle[]) {
|
||||||
|
let oldPos = Object.assign({}, this.pos);
|
||||||
|
this.move();
|
||||||
|
if (colliderArr.some(this.collision, this))
|
||||||
|
{
|
||||||
|
this.pos.x = oldPos.x;
|
||||||
|
this.pos.y = oldPos.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.clear(oldPos);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Ball extends Rectangle implements Moving {
|
class Player extends MovingRectangle {
|
||||||
dir: Vector = {x: 0.0, y: 0.0};
|
constructor(pos: VectorInteger, color: string, width: number, height: number) {
|
||||||
speed: number = 1;
|
super(pos, color, width, height);
|
||||||
constructor(pos: Vector, color: string, size: number) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Ball extends MovingRectangle {
|
||||||
|
constructor(pos: VectorInteger, color: string, size: number) {
|
||||||
super(pos, color, size, size);
|
super(pos, color, size, size);
|
||||||
}
|
}
|
||||||
move() {
|
|
||||||
this.pos.x += this.dir.x * this.speed;
|
|
||||||
this.pos.y += this.dir.y * this.speed;
|
|
||||||
}
|
|
||||||
bounce(collider?: Rectangle) {
|
bounce(collider?: Rectangle) {
|
||||||
if (collider instanceof Player)
|
/* Could be more generic, but testing only player is enough,
|
||||||
|
because in Pong collider can only be Player or Wall. */
|
||||||
|
if (collider instanceof Player) {
|
||||||
this._bouncePlayer(collider);
|
this._bouncePlayer(collider);
|
||||||
else // Could be more generic, but it's OK, because in Pong collider can only be Player or Wall.
|
}
|
||||||
|
else {
|
||||||
this._bounceWall();
|
this._bounceWall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moveAndBounce(colliderArr: Rectangle[]) {
|
||||||
|
let oldPos = Object.assign({}, this.pos);
|
||||||
|
this.move();
|
||||||
|
let i = colliderArr.findIndex(this.collision, this);
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
this.bounce(colliderArr[i]);
|
||||||
|
this.move();
|
||||||
|
}
|
||||||
|
this.clear(oldPos);
|
||||||
|
this.update();
|
||||||
}
|
}
|
||||||
private _bounceWall() { // Should be enough for Wall
|
private _bounceWall() { // Should be enough for Wall
|
||||||
ball.dir.y = ball.dir.y * -1;
|
ball.dir.y = ball.dir.y * -1;
|
||||||
@@ -318,24 +447,50 @@ class Ball extends Rectangle implements Moving {
|
|||||||
|
|
||||||
// conflict with Text
|
// conflict with Text
|
||||||
class TextElem implements Component {
|
class TextElem implements Component {
|
||||||
pos: Vector;
|
pos: VectorInteger;
|
||||||
color: string;
|
color: string;
|
||||||
size: string;
|
size: number;
|
||||||
font: string = "Consolas";
|
font: string;
|
||||||
text: string = "";
|
text: string = "";
|
||||||
constructor(pos: Vector, color: string, size: string, font?: string) {
|
constructor(pos: VectorInteger, color: string, size: number, font: string = "Bit5x3") {
|
||||||
this.pos = pos;
|
this.pos = Object.assign({}, pos);
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
if (font)
|
|
||||||
this.font = font;
|
this.font = font;
|
||||||
}
|
}
|
||||||
update() {
|
update() {
|
||||||
let ctx = pong.ctx;
|
let ctx = pong.ctx;
|
||||||
ctx.font = this.size + " " + this.font;
|
ctx.font = this.size + "px" + " " + this.font;
|
||||||
ctx.fillStyle = this.color;
|
ctx.fillStyle = this.color;
|
||||||
ctx.fillText(this.text, this.pos.x, this.pos.y);
|
ctx.fillText(this.text, this.pos.x, this.pos.y);
|
||||||
}
|
}
|
||||||
|
clear() {
|
||||||
|
// clear no very accurate for Text
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics
|
||||||
|
let ctx = pong.ctx;
|
||||||
|
let textMetric = ctx.measureText(this.text);
|
||||||
|
// console.log("textMetric.width = "+textMetric.width);
|
||||||
|
// console.log("size = "+this.size);
|
||||||
|
// console.log("x = "+this.pos.x);
|
||||||
|
// console.log("y = "+this.pos.y);
|
||||||
|
ctx.clearRect(this.pos.x - 1, this.pos.y-this.size + 1, textMetric.width, this.size);
|
||||||
|
// +1 and -1 because float imprecision (and Math.floor() with VectorInteger dont work for the moment)
|
||||||
|
// (or maybe its textMetric imprecision ?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextNumericValue extends TextElem {
|
||||||
|
private _value: number = 0;
|
||||||
|
constructor(pos: VectorInteger, color: string, size: number, font?: string) {
|
||||||
|
super(pos, color, size, font);
|
||||||
|
}
|
||||||
|
get value() {
|
||||||
|
return this._value;
|
||||||
|
}
|
||||||
|
set value(v: number) {
|
||||||
|
this._value = v;
|
||||||
|
this.text = v.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -344,7 +499,7 @@ class Line extends Rectangle {
|
|||||||
segmentCount: number;
|
segmentCount: number;
|
||||||
segmentWidth: number;
|
segmentWidth: number;
|
||||||
segmentHeight: number;
|
segmentHeight: number;
|
||||||
constructor(pos: Vector, color: string, width: number, height: number, gapeCount?: number) {
|
constructor(pos: VectorInteger, color: string, width: number, height: number, gapeCount?: number) {
|
||||||
super(pos, color, width, height);
|
super(pos, color, width, height);
|
||||||
if (gapeCount)
|
if (gapeCount)
|
||||||
this.gapeCount = gapeCount;
|
this.gapeCount = gapeCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user