multiBalls refactoring with ballsArr[]

This commit is contained in:
LuckyLaszlo
2022-12-01 17:48:34 +01:00
parent c8c3111ed4
commit f73932c131
9 changed files with 97 additions and 121 deletions

View File

@@ -11,9 +11,7 @@ class GameComponentsExtensionForClient extends GameComponents {
wallBottom: RectangleClient;
playerLeft: RacketClient;
playerRight: RacketClient;
ball: BallClient;
ball2?: BallClient;
ball3?: BallClient;
ballsArr: BallClient[];
constructor(options: en.MatchOptions, ctx: CanvasRenderingContext2D)
{
super(options);
@@ -21,12 +19,12 @@ class GameComponentsExtensionForClient extends GameComponents {
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");
}
const newBallsArr: BallClient[] = [];
this.ballsArr.forEach((ball) => {
newBallsArr.push(new BallClient(ball.pos, ball.width, ball.baseSpeed, ball.speedIncrease, ctx, "white"));
});
this.ballsArr = newBallsArr;
}
}

View File

@@ -25,12 +25,9 @@ function drawDynamic()
gc.scoreRight.update();
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();
}
gc.ballsArr.forEach((ball) => {
ball.update();
});
}
function drawStatic()

View File

@@ -23,12 +23,9 @@ 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]);
}
gc.ballsArr.forEach((ball) => {
ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
});
}
function opponentInterpolation(delta: number)

View File

@@ -90,20 +90,17 @@ function gameUpdate(data: ev.EventGameUpdate)
{
console.log("gameUpdate");
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;
}
data.ballsArr.forEach((ball, i) => {
gc.ballsArr[i].pos.assign(ball.x, ball.y);
gc.ballsArr[i].dir.assign(ball.dirX, ball.dirY);
gc.ballsArr[i].speed = ball.speed;
});
/* // Equivalent to
gc.ballsArr.forEach((ball, i) => {
ball.pos.assign(data.ballsArr[i].x, data.ballsArr[i].y);
ball.dir.assign(data.ballsArr[i].dirX, data.ballsArr[i].dirY);
ball.speed = data.ballsArr[i].speed;
}); */
const predictionPos = new VectorInteger(clientInfo.racket.pos.x, clientInfo.racket.pos.y); // debug

View File

@@ -20,6 +20,7 @@ class GameSession {
clientsUpdateInterval: NodeJS.Timer | number = 0;
components: GameComponentsServer;
matchOptions: en.MatchOptions;
matchEnded: boolean = false;
actual_time: number;
last_time: number;
@@ -31,14 +32,14 @@ class GameSession {
this.components = new GameComponentsServer(this.matchOptions);
}
start() {
setTimeout(this.resume, c.matchStartDelay, 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);
}
setTimeout(this.resume, c.matchStartDelay, this);
let timeout = c.matchStartDelay + c.newRoundDelay;
gc.ballsArr.forEach((ball) => {
setTimeout(this._newRound, timeout, this, ball);
timeout += c.newRoundDelay*0.5;
});
}
resume(s: GameSession) {
s.playersMap.forEach( (client) => {
@@ -91,35 +92,26 @@ class GameSession {
}); */
const gc = s.components;
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);
});
*/
gc.ballsArr.forEach((ball) => {
s._ballMovement(s.delta_time, ball);
});
}
private _ballMovement(delta: number, ball: Ball) {
const gc = this.components;
if (ball.ballInPlay)
{
ball.moveAndBounce(delta, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
if (ball.pos.x > c.w) {
if (ball.pos.x > c.w
|| ball.pos.x < 0 - ball.width)
{
ball.ballInPlay = false;
++gc.scoreLeft;
this.playersMap.forEach( (client) => {
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
});
setTimeout(this._newRound, c.newRoundDelay, this, ball);
}
else if (ball.pos.x < 0 - ball.width) {
ball.ballInPlay = false;
++gc.scoreRight;
if (this.matchEnded) {
return;
}
if (ball.pos.x > c.w) { ++gc.scoreLeft; }
else if (ball.pos.x < 0 - ball.width) { ++gc.scoreRight; }
this.playersMap.forEach( (client) => {
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
});
@@ -132,27 +124,16 @@ class GameSession {
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;
}
gc.ballsArr.forEach((ball) => {
update.ballsArr.push({
x: ball.pos.x,
y: ball.pos.y,
dirX: ball.dir.x,
dirY: ball.dir.y,
speed: ball.speed
});
});
s.playersMap.forEach( (client) => {
update.lastInputId = client.lastInputId;
client.socket.send(JSON.stringify(update));
@@ -176,6 +157,7 @@ class GameSession {
ball.ballInPlay = true;
}
private _matchEnd(s: GameSession) {
s.matchEnded = true;
const gc = s.components;
let eventEnd: ev.EventMatchEnd;

View File

@@ -32,27 +32,13 @@ class EventGameUpdate extends ServerEvent {
playerRight = {
y: 0
};
ball = {
x: 0,
y: 0,
dirX: 0,
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
};
ballsArr: {
x: number,
y: number,
dirX: number,
dirY: number,
speed: number
}[] = [];
lastInputId = 0;
constructor() { // TODO: constructor that take GameComponentsServer maybe ?
super(en.EventTypes.gameUpdate);

View File

@@ -3,15 +3,14 @@ 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";
import { clamp, random } from "../utils.js";
class GameComponents {
wallTop: Rectangle;
wallBottom: Rectangle;
playerLeft: Racket;
playerRight: Racket;
ball: Ball;
ball2?: Ball;
ball3?: Ball;
ballsArr: Ball[] = [];
constructor(options: en.MatchOptions)
{
let pos = new VectorInteger;
@@ -26,18 +25,27 @@ class GameComponents {
pos.assign(c.w-c.pw-c.pw, c.h_mid-c.ph/2);
this.playerRight = new Racket(pos, c.pw, c.ph, c.racketSpeed);
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);
let ballsCount = 1;
if (options & en.MatchOptions.multiBalls) {
ballsCount = c.multiBallsCount;
}
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
while (this.ballsArr.length < ballsCount) {
this.ballsArr.push(new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease))
}
this.ballsArr.forEach((ball) => {
ball.dir.x = 1;
if (random() > 0.5) {
ball.dir.x *= -1;
}
ball.dir.y = clamp(random(), 0, 0.2);
if (random() > 0.5) {
ball.dir.y *= -1;
}
ball.dir = ball.dir.normalized();
});
}
}

View File

@@ -19,3 +19,5 @@ export const normalizedSpeed = false; // for consistency in speed independent of
export const matchStartDelay = 3000; // millisecond
export const newRoundDelay = 1500; // millisecond
export const multiBallsCount = 3;

View File

@@ -7,4 +7,13 @@ function sleep (ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export {random, sleep}
function clamp(n: number, min: number, max: number) : number
{
if (n < min)
n = min;
else if (n > max)
n = max;
return (n);
}
export {random, sleep, clamp}