WIP multiBalls (need refactoring)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
|
import * as en from "../../shared_js/enums.js"
|
||||||
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
import { Vector, VectorInteger } from "../../shared_js/class/Vector.js";
|
||||||
import { TextElem, TextNumericValue } from "./Text.js";
|
import { TextElem, TextNumericValue } from "./Text.js";
|
||||||
import { RectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js";
|
import { RectangleClient, RacketClient, BallClient, Line } from "./RectangleClient.js";
|
||||||
@@ -11,14 +12,21 @@ class GameComponentsExtensionForClient extends GameComponents {
|
|||||||
playerLeft: RacketClient;
|
playerLeft: RacketClient;
|
||||||
playerRight: RacketClient;
|
playerRight: RacketClient;
|
||||||
ball: BallClient;
|
ball: BallClient;
|
||||||
constructor(ctx: CanvasRenderingContext2D)
|
ball2?: BallClient;
|
||||||
|
ball3?: BallClient;
|
||||||
|
constructor(options: en.MatchOptions, ctx: CanvasRenderingContext2D)
|
||||||
{
|
{
|
||||||
super();
|
super(options);
|
||||||
this.wallTop = new RectangleClient(this.wallTop.pos, this.wallTop.width, this.wallTop.height, ctx, "grey");
|
this.wallTop = new RectangleClient(this.wallTop.pos, this.wallTop.width, this.wallTop.height, ctx, "grey");
|
||||||
this.wallBottom = new RectangleClient(this.wallBottom.pos, this.wallBottom.width, this.wallBottom.height, ctx, "grey");
|
this.wallBottom = new RectangleClient(this.wallBottom.pos, this.wallBottom.width, this.wallBottom.height, ctx, "grey");
|
||||||
this.playerLeft = new RacketClient(this.playerLeft.pos, this.playerLeft.width, this.playerLeft.height, this.playerLeft.baseSpeed, ctx, "white");
|
this.playerLeft = new RacketClient(this.playerLeft.pos, this.playerLeft.width, this.playerLeft.height, this.playerLeft.baseSpeed, ctx, "white");
|
||||||
this.playerRight = new RacketClient(this.playerRight.pos, this.playerRight.width, this.playerRight.height, this.playerRight.baseSpeed, ctx, "white");
|
this.playerRight = new RacketClient(this.playerRight.pos, this.playerRight.width, this.playerRight.height, this.playerRight.baseSpeed, ctx, "white");
|
||||||
this.ball = new BallClient(this.ball.pos, this.ball.width, this.ball.baseSpeed, this.ball.speedIncrease, ctx, "white");
|
this.ball = new BallClient(this.ball.pos, this.ball.width, this.ball.baseSpeed, this.ball.speedIncrease, ctx, "white");
|
||||||
|
if (options & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
this.ball2 = new BallClient(this.ball2.pos, this.ball2.width, this.ball2.baseSpeed, this.ball2.speedIncrease, ctx, "white");
|
||||||
|
this.ball3 = new BallClient(this.ball3.pos, this.ball3.width, this.ball3.baseSpeed, this.ball3.speedIncrease, ctx, "white");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +43,9 @@ class GameComponentsClient extends GameComponentsExtensionForClient {
|
|||||||
h_grid_mid: RectangleClient;
|
h_grid_mid: RectangleClient;
|
||||||
h_grid_u1: RectangleClient;
|
h_grid_u1: RectangleClient;
|
||||||
h_grid_d1: RectangleClient;
|
h_grid_d1: RectangleClient;
|
||||||
constructor(ctx: CanvasRenderingContext2D)
|
constructor(options: en.MatchOptions, ctx: CanvasRenderingContext2D)
|
||||||
{
|
{
|
||||||
super(ctx);
|
super(options, ctx);
|
||||||
let pos = new VectorInteger;
|
let pos = new VectorInteger;
|
||||||
// Scores
|
// Scores
|
||||||
pos.assign(c.w_mid-c.scoreSize*1.6, c.scoreSize*1.5);
|
pos.assign(c.w_mid-c.scoreSize*1.6, c.scoreSize*1.5);
|
||||||
|
|||||||
@@ -20,4 +20,4 @@ export const soundPongVolume = 0.3; // between 0 and 1
|
|||||||
|
|
||||||
// TODO: replace by a selector on the website
|
// TODO: replace by a selector on the website
|
||||||
import * as en from "../shared_js/enums.js"
|
import * as en from "../shared_js/enums.js"
|
||||||
export const optionsPLACEHOLDER = en.MatchOptions.noOption;
|
export const optionsPLACEHOLDER = en.MatchOptions.multiBalls;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
import { pong, gc } from "./global.js"
|
import { pong, gc } from "./global.js"
|
||||||
|
import * as c from "./constants.js"
|
||||||
|
import * as en from "../shared_js/enums.js"
|
||||||
import { gridDisplay } from "./handleInput.js";
|
import { gridDisplay } from "./handleInput.js";
|
||||||
|
|
||||||
function drawLoop()
|
function drawLoop()
|
||||||
@@ -24,6 +26,11 @@ function drawDynamic()
|
|||||||
gc.playerLeft.update();
|
gc.playerLeft.update();
|
||||||
gc.playerRight.update();
|
gc.playerRight.update();
|
||||||
gc.ball.update();
|
gc.ball.update();
|
||||||
|
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
gc.ball2.update();
|
||||||
|
gc.ball3.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawStatic()
|
function drawStatic()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import * as c from "./constants.js";
|
import * as c from "./constants.js";
|
||||||
|
import * as en from "../shared_js/enums.js"
|
||||||
import { gc, clientInfo } from "./global.js";
|
import { gc, clientInfo } from "./global.js";
|
||||||
|
|
||||||
let actual_time: number = Date.now();
|
let actual_time: number = Date.now();
|
||||||
@@ -23,6 +24,11 @@ function gameLoop()
|
|||||||
|
|
||||||
// client prediction
|
// client prediction
|
||||||
gc.ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
gc.ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
||||||
|
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
gc.ball2.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
||||||
|
gc.ball3.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function opponentInterpolation(delta: number)
|
function opponentInterpolation(delta: number)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {socket} from "./ws.js"; socket; // no-op, just for loading
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const pong = new GameArea();
|
export const pong = new GameArea();
|
||||||
export const gc = new GameComponentsClient(pong.ctx);
|
export const gc = new GameComponentsClient(c.optionsPLACEHOLDER, pong.ctx);
|
||||||
|
|
||||||
function matchmaking()
|
function matchmaking()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,6 +93,17 @@ function gameUpdate(data: ev.EventGameUpdate)
|
|||||||
gc.ball.pos.assign(data.ball.x, data.ball.y);
|
gc.ball.pos.assign(data.ball.x, data.ball.y);
|
||||||
gc.ball.dir.assign(data.ball.dirX, data.ball.dirY);
|
gc.ball.dir.assign(data.ball.dirX, data.ball.dirY);
|
||||||
gc.ball.speed = data.ball.speed;
|
gc.ball.speed = data.ball.speed;
|
||||||
|
|
||||||
|
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
gc.ball2.pos.assign(data.ball2.x, data.ball2.y);
|
||||||
|
gc.ball2.dir.assign(data.ball2.dirX, data.ball2.dirY);
|
||||||
|
gc.ball2.speed = data.ball2.speed;
|
||||||
|
|
||||||
|
gc.ball3.pos.assign(data.ball3.x, data.ball3.y);
|
||||||
|
gc.ball3.dir.assign(data.ball3.dirX, data.ball3.dirY);
|
||||||
|
gc.ball3.speed = data.ball3.speed;
|
||||||
|
}
|
||||||
|
|
||||||
const predictionPos = new VectorInteger(clientInfo.racket.pos.x, clientInfo.racket.pos.y); // debug
|
const predictionPos = new VectorInteger(clientInfo.racket.pos.x, clientInfo.racket.pos.y); // debug
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
|
import * as en from "../../shared_js/enums.js"
|
||||||
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
import { GameComponents } from "../../shared_js/class/GameComponents.js";
|
||||||
|
|
||||||
class GameComponentsServer extends GameComponents {
|
class GameComponentsServer extends GameComponents {
|
||||||
scoreLeft: number = 0;
|
scoreLeft: number = 0;
|
||||||
scoreRight: number = 0;
|
scoreRight: number = 0;
|
||||||
ballInPlay: boolean = false;
|
constructor(options: en.MatchOptions)
|
||||||
constructor()
|
|
||||||
{
|
{
|
||||||
super();
|
super(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ClientPlayer } from "./Client";
|
|||||||
import { GameComponentsServer } from "./GameComponentsServer.js";
|
import { GameComponentsServer } from "./GameComponentsServer.js";
|
||||||
import { clientInputListener } from "../wsServer.js";
|
import { clientInputListener } from "../wsServer.js";
|
||||||
import { random } from "../utils.js";
|
import { random } from "../utils.js";
|
||||||
|
import { Ball } from "../../shared_js/class/Rectangle.js";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Arg "s: GameSession" replace "this: GameSession" for use with setTimeout(),
|
Arg "s: GameSession" replace "this: GameSession" for use with setTimeout(),
|
||||||
@@ -27,11 +28,17 @@ class GameSession {
|
|||||||
constructor(id: string, matchOptions: en.MatchOptions) {
|
constructor(id: string, matchOptions: en.MatchOptions) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.matchOptions = matchOptions;
|
this.matchOptions = matchOptions;
|
||||||
this.components = new GameComponentsServer();
|
this.components = new GameComponentsServer(this.matchOptions);
|
||||||
}
|
}
|
||||||
start() {
|
start() {
|
||||||
setTimeout(this.resume, c.matchStartDelay, this);
|
setTimeout(this.resume, c.matchStartDelay, this);
|
||||||
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay, this);
|
const gc = this.components;
|
||||||
|
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay, this, gc.ball);
|
||||||
|
if (this.matchOptions & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay + c.newRoundDelay*0.33, this, gc.ball2);
|
||||||
|
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay + c.newRoundDelay*0.66, this, gc.ball3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resume(s: GameSession) {
|
resume(s: GameSession) {
|
||||||
s.playersMap.forEach( (client) => {
|
s.playersMap.forEach( (client) => {
|
||||||
@@ -84,53 +91,74 @@ class GameSession {
|
|||||||
}); */
|
}); */
|
||||||
|
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
if (gc.ballInPlay)
|
s._ballMovement(s.delta_time, gc.ball);
|
||||||
|
if (s.matchOptions & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
s._ballMovement(s.delta_time, gc.ball2);
|
||||||
|
s._ballMovement(s.delta_time, gc.ball3);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
gc.ballArr.forEach( (ball) => {
|
||||||
|
s._ballMovement(s.delta_time, ball);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
private _ballMovement(delta: number, ball: Ball) {
|
||||||
|
const gc = this.components;
|
||||||
|
if (ball.ballInPlay)
|
||||||
{
|
{
|
||||||
gc.ball.moveAndBounce(s.delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
ball.moveAndBounce(delta, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
||||||
if (gc.ball.pos.x > c.w) {
|
if (ball.pos.x > c.w) {
|
||||||
gc.ballInPlay = false;
|
ball.ballInPlay = false;
|
||||||
++gc.scoreLeft;
|
++gc.scoreLeft;
|
||||||
s.playersMap.forEach( (client) => {
|
this.playersMap.forEach( (client) => {
|
||||||
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
|
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
|
||||||
});
|
});
|
||||||
setTimeout(s._newRound, c.newRoundDelay, s);
|
setTimeout(this._newRound, c.newRoundDelay, this, ball);
|
||||||
}
|
}
|
||||||
else if (gc.ball.pos.x < 0 - gc.ball.width) {
|
else if (ball.pos.x < 0 - ball.width) {
|
||||||
gc.ballInPlay = false;
|
ball.ballInPlay = false;
|
||||||
++gc.scoreRight;
|
++gc.scoreRight;
|
||||||
|
|
||||||
s.playersMap.forEach( (client) => {
|
this.playersMap.forEach( (client) => {
|
||||||
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
|
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
|
||||||
});
|
});
|
||||||
setTimeout(s._newRound, c.newRoundDelay, s);
|
setTimeout(this._newRound, c.newRoundDelay, this, ball);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private _clientsUpdate(s: GameSession) {
|
private _clientsUpdate(s: GameSession) {
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
const update: ev.EventGameUpdate = {
|
const update = new ev.EventGameUpdate();
|
||||||
type: en.EventTypes.gameUpdate,
|
update.playerLeft.y = gc.playerLeft.pos.y;
|
||||||
playerLeft: {
|
update.playerRight.y = gc.playerRight.pos.y;
|
||||||
y: gc.playerLeft.pos.y
|
|
||||||
},
|
update.ball.x = gc.ball.pos.x;
|
||||||
playerRight: {
|
update.ball.y = gc.ball.pos.y;
|
||||||
y: gc.playerRight.pos.y
|
update.ball.dirX = gc.ball.dir.x;
|
||||||
},
|
update.ball.dirY = gc.ball.dir.y;
|
||||||
ball:{
|
update.ball.speed = gc.ball.speed;
|
||||||
x: gc.ball.pos.x,
|
if (s.matchOptions & en.MatchOptions.multiBalls)
|
||||||
y: gc.ball.pos.y,
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
dirX: gc.ball.dir.x,
|
update.ball2.x = gc.ball2.pos.x;
|
||||||
dirY: gc.ball.dir.y,
|
update.ball2.y = gc.ball2.pos.y;
|
||||||
speed: gc.ball.speed
|
update.ball2.dirX = gc.ball2.dir.x;
|
||||||
},
|
update.ball2.dirY = gc.ball2.dir.y;
|
||||||
lastInputId: 0
|
update.ball2.speed = gc.ball2.speed;
|
||||||
};
|
|
||||||
|
update.ball3.x = gc.ball3.pos.x;
|
||||||
|
update.ball3.y = gc.ball3.pos.y;
|
||||||
|
update.ball3.dirX = gc.ball3.dir.x;
|
||||||
|
update.ball3.dirY = gc.ball3.dir.y;
|
||||||
|
update.ball3.speed = gc.ball3.speed;
|
||||||
|
}
|
||||||
|
|
||||||
s.playersMap.forEach( (client) => {
|
s.playersMap.forEach( (client) => {
|
||||||
update.lastInputId = client.lastInputId;
|
update.lastInputId = client.lastInputId;
|
||||||
client.socket.send(JSON.stringify(update));
|
client.socket.send(JSON.stringify(update));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private _newRound(s: GameSession) {
|
private _newRound(s: GameSession, ball: Ball) {
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
// https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches
|
// https://fr.wikipedia.org/wiki/Tennis_de_table#Nombre_de_manches
|
||||||
if (gc.scoreLeft >= 11 || gc.scoreRight >= 11)
|
if (gc.scoreLeft >= 11 || gc.scoreRight >= 11)
|
||||||
@@ -142,10 +170,10 @@ class GameSession {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gc.ball.pos.x = c.w_mid;
|
ball.pos.x = c.w_mid;
|
||||||
gc.ball.pos.y = Math.floor((c.h * 0.1) + random() * (c.h * 0.8));
|
ball.pos.y = Math.floor((c.h * 0.1) + random() * (c.h * 0.8));
|
||||||
gc.ball.speed = gc.ball.baseSpeed;
|
ball.speed = ball.baseSpeed;
|
||||||
gc.ballInPlay = true;
|
ball.ballInPlay = true;
|
||||||
}
|
}
|
||||||
private _matchEnd(s: GameSession) {
|
private _matchEnd(s: GameSession) {
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
|
|||||||
@@ -39,6 +39,20 @@ class EventGameUpdate extends ServerEvent {
|
|||||||
dirY: 0,
|
dirY: 0,
|
||||||
speed: 0
|
speed: 0
|
||||||
};
|
};
|
||||||
|
ball2? = { // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
dirX: 0,
|
||||||
|
dirY: 0,
|
||||||
|
speed: 0
|
||||||
|
};
|
||||||
|
ball3? = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
dirX: 0,
|
||||||
|
dirY: 0,
|
||||||
|
speed: 0
|
||||||
|
};
|
||||||
lastInputId = 0;
|
lastInputId = 0;
|
||||||
constructor() { // TODO: constructor that take GameComponentsServer maybe ?
|
constructor() { // TODO: constructor that take GameComponentsServer maybe ?
|
||||||
super(en.EventTypes.gameUpdate);
|
super(en.EventTypes.gameUpdate);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import * as c from "../constants.js"
|
import * as c from "../constants.js"
|
||||||
|
import * as en from "../../shared_js/enums.js"
|
||||||
import { VectorInteger } from "./Vector.js";
|
import { VectorInteger } from "./Vector.js";
|
||||||
import { Rectangle, Racket, Ball } from "./Rectangle.js";
|
import { Rectangle, Racket, Ball } from "./Rectangle.js";
|
||||||
|
|
||||||
@@ -9,7 +10,9 @@ class GameComponents {
|
|||||||
playerLeft: Racket;
|
playerLeft: Racket;
|
||||||
playerRight: Racket;
|
playerRight: Racket;
|
||||||
ball: Ball;
|
ball: Ball;
|
||||||
constructor()
|
ball2?: Ball;
|
||||||
|
ball3?: Ball;
|
||||||
|
constructor(options: en.MatchOptions)
|
||||||
{
|
{
|
||||||
let pos = new VectorInteger;
|
let pos = new VectorInteger;
|
||||||
|
|
||||||
@@ -26,6 +29,15 @@ class GameComponents {
|
|||||||
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
|
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
|
||||||
this.ball = new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease);
|
this.ball = new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease);
|
||||||
this.ball.dir.assign(-0.8, +0.2);
|
this.ball.dir.assign(-0.8, +0.2);
|
||||||
|
|
||||||
|
if (options & en.MatchOptions.multiBalls)
|
||||||
|
{ // ALTERNATIVE POSSIBLE, Array of balls
|
||||||
|
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
|
||||||
|
this.ball2 = new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease);
|
||||||
|
this.ball2.dir.assign(-0.8, +0.2);
|
||||||
|
this.ball3 = new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease);
|
||||||
|
this.ball3.dir.assign(-0.8, +0.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class Racket extends MovingRectangle {
|
|||||||
|
|
||||||
class Ball extends MovingRectangle {
|
class Ball extends MovingRectangle {
|
||||||
readonly speedIncrease: number;
|
readonly speedIncrease: number;
|
||||||
|
ballInPlay: boolean = false;
|
||||||
constructor(pos: VectorInteger, size: number, baseSpeed: number, speedIncrease: number) {
|
constructor(pos: VectorInteger, size: number, baseSpeed: number, speedIncrease: number) {
|
||||||
super(pos, size, size, baseSpeed);
|
super(pos, size, size, baseSpeed);
|
||||||
this.speedIncrease = speedIncrease;
|
this.speedIncrease = speedIncrease;
|
||||||
|
|||||||
Reference in New Issue
Block a user