WIP multiBalls (need refactoring)

This commit is contained in:
LuckyLaszlo
2022-12-01 15:55:40 +01:00
parent 6e572f2fb5
commit c8c3111ed4
11 changed files with 132 additions and 45 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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;