diff --git a/make.sh b/make.sh
index f4ad7416..5a4999f6 100644
--- a/make.sh
+++ b/make.sh
@@ -1,4 +1,11 @@
#!/bin/bash
npx tsc
+
mkdir -p www
-cp ./src/client/*.js ./src/client/*.html ./www/
\ No newline at end of file
+cp ./src/client/*.html ./www/
+
+mkdir -p www/js
+cp ./src/client/*.js ./www/js/
+
+mkdir -p www/js/class
+cp ./src/client/class/*.js ./www/js/class/
diff --git a/src/client/class/GameArea.ts b/src/client/class/GameArea.ts
new file mode 100644
index 00000000..fc775c58
--- /dev/null
+++ b/src/client/class/GameArea.ts
@@ -0,0 +1,36 @@
+
+class GameArea {
+ keys: string[];
+ interval: number = 0;
+ canvas: HTMLCanvasElement;
+ ctx: CanvasRenderingContext2D;
+ constructor() {
+ this.keys = [];
+ this.canvas = document.createElement("canvas");
+ this.ctx = this.canvas.getContext("2d") as CanvasRenderingContext2D;
+ /* ratio 5/3 (1.66) */
+ const ratio = 1.66666;
+ this.canvas.width = 1500;
+ this.canvas.height = this.canvas.width / ratio;
+ let container = document.getElementById("canvas-container");
+ if (container)
+ container.insertBefore(this.canvas, container.childNodes[0]);
+ }
+ addKey(key: string) {
+ key = key.toLowerCase();
+ var i = this.keys.indexOf(key);
+ if (i == -1)
+ this.keys.push(key);
+ }
+ deleteKey(key: string) {
+ key = key.toLowerCase();
+ var i = this.keys.indexOf(key);
+ if (i != -1)
+ this.keys.splice(i, 1);
+ }
+ clear() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ }
+}
+
+export {GameArea}
diff --git a/src/client/class.ts b/src/client/class/Rectangle.ts
similarity index 61%
rename from src/client/class.ts
rename to src/client/class/Rectangle.ts
index 929f293c..743eedca 100644
--- a/src/client/class.ts
+++ b/src/client/class/Rectangle.ts
@@ -1,60 +1,6 @@
-// type Vector = {
-// x: number;
-// y: number;
-// }
-
-class Vector {
- x: number;
- y: number;
- constructor(x: number = 0, y: number = 0) {
- this.x = x;
- this.y = y;
- }
- assign(x: number, y: number) {
- 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 {
- pos: VectorInteger;
- color: string;
- ctx: CanvasRenderingContext2D; // TODO: reference in place of global 'pong.ctx' call
- update(): void;
- clear(): void;
-}
-
+import {Vector, VectorInteger} from "./Vector.js";
+import {Component, Moving} from "./interface.js";
class Rectangle implements Component {
ctx: CanvasRenderingContext2D;
@@ -99,14 +45,6 @@ class Rectangle implements Component {
}
}
-
-interface Moving {
- dir: Vector;
- speed: number;
- move(): void;
-}
-
-
class MovingRectangle extends Rectangle implements Moving {
dir: Vector = new Vector(0,0);
speed: number;
@@ -136,14 +74,12 @@ class MovingRectangle extends Rectangle implements Moving {
}
}
-
class Player extends MovingRectangle {
constructor(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, width: number, height: number, baseSpeed: number) {
super(ctx, pos, color, width, height, baseSpeed);
}
}
-
class Ball extends MovingRectangle {
constructor(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, size: number, baseSpeed: number) {
super(ctx, pos, color, size, size, baseSpeed);
@@ -180,55 +116,6 @@ class Ball extends MovingRectangle {
}
}
-// conflict with Text
-class TextElem implements Component {
- ctx: CanvasRenderingContext2D;
- pos: VectorInteger;
- color: string;
- size: number;
- font: string;
- text: string = "";
- constructor(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, size: number, font: string = "Bit5x3") {
- this.ctx = ctx;
- this.pos = Object.assign({}, pos);
- this.color = color;
- this.size = size;
- this.font = font;
- }
- update() {
- this.ctx.font = this.size + "px" + " " + this.font;
- this.ctx.fillStyle = this.color;
- this.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 textMetric = this.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);
- this.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(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, size: number, font?: string) {
- super(ctx, pos, color, size, font);
- }
- get value() {
- return this._value;
- }
- set value(v: number) {
- this._value = v;
- this.text = v.toString();
- }
-}
-
-
class Line extends Rectangle {
gapeCount: number = 0;
segmentCount: number;
@@ -264,4 +151,4 @@ class Line extends Rectangle {
}
}
-export {Vector, VectorInteger, Rectangle, MovingRectangle, Player, Ball, TextElem, TextNumericValue, Line}
+export {Rectangle, MovingRectangle, Player, Ball, Line}
diff --git a/src/client/class/Text.ts b/src/client/class/Text.ts
new file mode 100644
index 00000000..4c7e675a
--- /dev/null
+++ b/src/client/class/Text.ts
@@ -0,0 +1,53 @@
+
+import {Vector, VectorInteger} from "./Vector.js";
+import {Component, Moving} from "./interface.js";
+
+// conflict with Text
+class TextElem implements Component {
+ ctx: CanvasRenderingContext2D;
+ pos: VectorInteger;
+ color: string;
+ size: number;
+ font: string;
+ text: string = "";
+ constructor(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, size: number, font: string = "Bit5x3") {
+ this.ctx = ctx;
+ this.pos = Object.assign({}, pos);
+ this.color = color;
+ this.size = size;
+ this.font = font;
+ }
+ update() {
+ this.ctx.font = this.size + "px" + " " + this.font;
+ this.ctx.fillStyle = this.color;
+ this.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 textMetric = this.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);
+ this.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(ctx: CanvasRenderingContext2D, pos: VectorInteger, color: string, size: number, font?: string) {
+ super(ctx, pos, color, size, font);
+ }
+ get value() {
+ return this._value;
+ }
+ set value(v: number) {
+ this._value = v;
+ this.text = v.toString();
+ }
+}
+
+export {TextElem, TextNumericValue}
diff --git a/src/client/class/Vector.ts b/src/client/class/Vector.ts
new file mode 100644
index 00000000..278394a1
--- /dev/null
+++ b/src/client/class/Vector.ts
@@ -0,0 +1,45 @@
+
+class Vector {
+ x: number;
+ y: number;
+ constructor(x: number = 0, y: number = 0) {
+ this.x = x;
+ this.y = y;
+ }
+ assign(x: number, y: number) {
+ 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;
+ // }
+}
+*/
+
+export {Vector, VectorInteger}
diff --git a/src/client/class/interface.ts b/src/client/class/interface.ts
new file mode 100644
index 00000000..a06ef28e
--- /dev/null
+++ b/src/client/class/interface.ts
@@ -0,0 +1,18 @@
+
+import {Vector, VectorInteger} from "./Vector.js";
+
+interface Component {
+ pos: VectorInteger;
+ color: string;
+ ctx: CanvasRenderingContext2D;
+ update(): void;
+ clear(): void;
+}
+
+interface Moving {
+ dir: Vector;
+ speed: number;
+ move(): void;
+}
+
+export {Component, Moving}
diff --git a/src/client/draw.ts b/src/client/draw.ts
new file mode 100644
index 00000000..5cacdfa5
--- /dev/null
+++ b/src/client/draw.ts
@@ -0,0 +1,40 @@
+import * as g from "./pong.js"
+import {gridDisplay} from "./handleInput.js";
+
+function draw()
+{
+ if (gridDisplay) {
+ drawGrid();
+ }
+ g.midLine.update();
+ g.score1.update();
+ g.score2.update();
+}
+
+function drawStatic()
+{
+ g.wall_top.update();
+ g.wall_bottom.update();
+ g.midLine.update();
+}
+
+function drawInit()
+{
+ g.pong.clear();
+ drawStatic();
+ g.player1.update();
+ g.player2.update();
+}
+
+function drawGrid()
+{
+ g.w_grid_mid.update();
+ g.w_grid_u1.update();
+ g.w_grid_d1.update();
+
+ g.h_grid_mid.update();
+ g.h_grid_u1.update();
+ g.h_grid_d1.update();
+}
+
+export {draw, drawStatic, drawInit, drawGrid}
diff --git a/src/client/gameLoop.ts b/src/client/gameLoop.ts
new file mode 100644
index 00000000..fdecf9ab
--- /dev/null
+++ b/src/client/gameLoop.ts
@@ -0,0 +1,60 @@
+import * as g from "./pong.js"
+import * as d from "./draw.js";
+import {random} from "./utils.js";
+import {handleInput} from "./handleInput.js";
+
+let ballInPlay = true;
+
+function gameLoop()
+{
+ /*
+ // I try to clear only what need to be update.
+ // Will revert to clear() all if not satisfactory.
+ pong.clear();
+ */
+ handleInput();
+
+ if (ballInPlay)
+ {
+ g.ball.moveAndBounce([g.wall_top, g.wall_bottom, g.player1, g.player2]);
+ if (g.ball.pos.x > g.pong.canvas.width) {
+ ballInPlay = false;
+ g.score1.clear();
+ ++g.score1.value;
+ setTimeout(newRound, 1500);
+ }
+ else if (g.ball.pos.x < 0 - g.ball.width) {
+ ballInPlay = false;
+ g.score2.clear();
+ ++g.score2.value;
+ setTimeout(newRound, 1500);
+ }
+ }
+
+ d.draw();
+}
+
+function newRound()
+{
+ // https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches
+ if (g.score1.value >= 11
+ || g.score2.value >= 11)
+ {
+ if (Math.abs(g.score1.value - g.score2.value) >= 2)
+ {
+ if (g.score1.value > g.score2.value) {
+ alert("Player 1 WIN");
+ }
+ else {
+ alert("Player 2 WIN");
+ }
+ return;
+ }
+ }
+ g.ball.pos.x = g.pong.canvas.width/2;
+ g.ball.pos.y = (g.pong.canvas.height * 0.1) + Math.floor(random() * (g.pong.canvas.height * 0.8));
+ g.ball.speed = g.ball.baseSpeed;
+ ballInPlay = true;
+}
+
+export {gameLoop}
diff --git a/src/client/handleInput.ts b/src/client/handleInput.ts
new file mode 100644
index 00000000..c8beda70
--- /dev/null
+++ b/src/client/handleInput.ts
@@ -0,0 +1,46 @@
+import * as g from "./pong.js"
+import * as d from "./draw.js";
+
+let gridDisplay = false;
+
+function handleInput()
+{
+ var keys = g.pong.keys;
+ if (keys.length == 0)
+ return;
+
+ if (keys.indexOf("g") != -1)
+ {
+ if (gridDisplay)
+ {
+ g.pong.clear();
+ d.drawStatic();
+ }
+ gridDisplay = !gridDisplay;
+ g.pong.deleteKey("g");
+ }
+ playerMove(keys);
+}
+
+function playerMove(keys: string[])
+{
+ g.player1.dir.y = 0;
+ if (keys.indexOf("w") != -1) {
+ g.player1.dir.y += -1;
+ }
+ if (keys.indexOf("s") != -1) {
+ g.player1.dir.y += 1;
+ }
+ g.player1.moveAndCollide([g.wall_top, g.wall_bottom]);
+
+ g.player2.dir.y = 0;
+ if (keys.indexOf("ArrowUp".toLowerCase()) != -1) {
+ g.player2.dir.y += -1;
+ }
+ if (keys.indexOf("ArrowDown".toLowerCase()) != -1) {
+ g.player2.dir.y += 1;
+ }
+ g.player2.moveAndCollide([g.wall_top, g.wall_bottom]);
+}
+
+export {handleInput, gridDisplay}
diff --git a/src/client/pong.html b/src/client/pong.html
index 22e61091..976f2aa4 100644
--- a/src/client/pong.html
+++ b/src/client/pong.html
@@ -4,9 +4,9 @@