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