multiBalls refactoring with ballsArr[]
This commit is contained in:
@@ -11,9 +11,7 @@ class GameComponentsExtensionForClient extends GameComponents {
|
|||||||
wallBottom: RectangleClient;
|
wallBottom: RectangleClient;
|
||||||
playerLeft: RacketClient;
|
playerLeft: RacketClient;
|
||||||
playerRight: RacketClient;
|
playerRight: RacketClient;
|
||||||
ball: BallClient;
|
ballsArr: BallClient[];
|
||||||
ball2?: BallClient;
|
|
||||||
ball3?: BallClient;
|
|
||||||
constructor(options: en.MatchOptions, ctx: CanvasRenderingContext2D)
|
constructor(options: en.MatchOptions, ctx: CanvasRenderingContext2D)
|
||||||
{
|
{
|
||||||
super(options);
|
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.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");
|
|
||||||
if (options & en.MatchOptions.multiBalls)
|
const newBallsArr: BallClient[] = [];
|
||||||
{ // ALTERNATIVE POSSIBLE, Array of balls
|
this.ballsArr.forEach((ball) => {
|
||||||
this.ball2 = new BallClient(this.ball2.pos, this.ball2.width, this.ball2.baseSpeed, this.ball2.speedIncrease, ctx, "white");
|
newBallsArr.push(new BallClient(ball.pos, ball.width, ball.baseSpeed, ball.speedIncrease, ctx, "white"));
|
||||||
this.ball3 = new BallClient(this.ball3.pos, this.ball3.width, this.ball3.baseSpeed, this.ball3.speedIncrease, ctx, "white");
|
});
|
||||||
}
|
this.ballsArr = newBallsArr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,12 +25,9 @@ function drawDynamic()
|
|||||||
gc.scoreRight.update();
|
gc.scoreRight.update();
|
||||||
gc.playerLeft.update();
|
gc.playerLeft.update();
|
||||||
gc.playerRight.update();
|
gc.playerRight.update();
|
||||||
gc.ball.update();
|
gc.ballsArr.forEach((ball) => {
|
||||||
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
ball.update();
|
||||||
{ // ALTERNATIVE POSSIBLE, Array of balls
|
});
|
||||||
gc.ball2.update();
|
|
||||||
gc.ball3.update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawStatic()
|
function drawStatic()
|
||||||
|
|||||||
@@ -23,12 +23,9 @@ function gameLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// client prediction
|
// client prediction
|
||||||
gc.ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
gc.ballsArr.forEach((ball) => {
|
||||||
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
ball.moveAndBounce(delta_time, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
||||||
{ // 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)
|
||||||
|
|||||||
@@ -90,20 +90,17 @@ function gameUpdate(data: ev.EventGameUpdate)
|
|||||||
{
|
{
|
||||||
console.log("gameUpdate");
|
console.log("gameUpdate");
|
||||||
|
|
||||||
gc.ball.pos.assign(data.ball.x, data.ball.y);
|
data.ballsArr.forEach((ball, i) => {
|
||||||
gc.ball.dir.assign(data.ball.dirX, data.ball.dirY);
|
gc.ballsArr[i].pos.assign(ball.x, ball.y);
|
||||||
gc.ball.speed = data.ball.speed;
|
gc.ballsArr[i].dir.assign(ball.dirX, ball.dirY);
|
||||||
|
gc.ballsArr[i].speed = ball.speed;
|
||||||
if (c.optionsPLACEHOLDER & en.MatchOptions.multiBalls)
|
});
|
||||||
{ // ALTERNATIVE POSSIBLE, Array of balls
|
/* // Equivalent to
|
||||||
gc.ball2.pos.assign(data.ball2.x, data.ball2.y);
|
gc.ballsArr.forEach((ball, i) => {
|
||||||
gc.ball2.dir.assign(data.ball2.dirX, data.ball2.dirY);
|
ball.pos.assign(data.ballsArr[i].x, data.ballsArr[i].y);
|
||||||
gc.ball2.speed = data.ball2.speed;
|
ball.dir.assign(data.ballsArr[i].dirX, data.ballsArr[i].dirY);
|
||||||
|
ball.speed = data.ballsArr[i].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
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class GameSession {
|
|||||||
clientsUpdateInterval: NodeJS.Timer | number = 0;
|
clientsUpdateInterval: NodeJS.Timer | number = 0;
|
||||||
components: GameComponentsServer;
|
components: GameComponentsServer;
|
||||||
matchOptions: en.MatchOptions;
|
matchOptions: en.MatchOptions;
|
||||||
|
matchEnded: boolean = false;
|
||||||
|
|
||||||
actual_time: number;
|
actual_time: number;
|
||||||
last_time: number;
|
last_time: number;
|
||||||
@@ -31,14 +32,14 @@ class GameSession {
|
|||||||
this.components = new GameComponentsServer(this.matchOptions);
|
this.components = new GameComponentsServer(this.matchOptions);
|
||||||
}
|
}
|
||||||
start() {
|
start() {
|
||||||
setTimeout(this.resume, c.matchStartDelay, this);
|
|
||||||
const gc = this.components;
|
const gc = this.components;
|
||||||
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay, this, gc.ball);
|
setTimeout(this.resume, c.matchStartDelay, this);
|
||||||
if (this.matchOptions & en.MatchOptions.multiBalls)
|
|
||||||
{ // ALTERNATIVE POSSIBLE, Array of balls
|
let timeout = c.matchStartDelay + c.newRoundDelay;
|
||||||
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay + c.newRoundDelay*0.33, this, gc.ball2);
|
gc.ballsArr.forEach((ball) => {
|
||||||
setTimeout(this._newRound, c.matchStartDelay + c.newRoundDelay + c.newRoundDelay*0.66, this, gc.ball3);
|
setTimeout(this._newRound, timeout, this, ball);
|
||||||
}
|
timeout += c.newRoundDelay*0.5;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
resume(s: GameSession) {
|
resume(s: GameSession) {
|
||||||
s.playersMap.forEach( (client) => {
|
s.playersMap.forEach( (client) => {
|
||||||
@@ -91,34 +92,25 @@ class GameSession {
|
|||||||
}); */
|
}); */
|
||||||
|
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
s._ballMovement(s.delta_time, gc.ball);
|
gc.ballsArr.forEach((ball) => {
|
||||||
if (s.matchOptions & en.MatchOptions.multiBalls)
|
s._ballMovement(s.delta_time, ball);
|
||||||
{ // 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) {
|
private _ballMovement(delta: number, ball: Ball) {
|
||||||
const gc = this.components;
|
const gc = this.components;
|
||||||
if (ball.ballInPlay)
|
if (ball.ballInPlay)
|
||||||
{
|
{
|
||||||
ball.moveAndBounce(delta, [gc.wallTop, gc.wallBottom, gc.playerLeft, gc.playerRight]);
|
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;
|
ball.ballInPlay = false;
|
||||||
++gc.scoreLeft;
|
if (this.matchEnded) {
|
||||||
this.playersMap.forEach( (client) => {
|
return;
|
||||||
client.socket.send(JSON.stringify(new ev.EventScoreUpdate(gc.scoreLeft, gc.scoreRight)));
|
}
|
||||||
});
|
|
||||||
setTimeout(this._newRound, c.newRoundDelay, this, ball);
|
if (ball.pos.x > c.w) { ++gc.scoreLeft; }
|
||||||
}
|
else if (ball.pos.x < 0 - ball.width) { ++gc.scoreRight; }
|
||||||
else if (ball.pos.x < 0 - ball.width) {
|
|
||||||
ball.ballInPlay = false;
|
|
||||||
++gc.scoreRight;
|
|
||||||
|
|
||||||
this.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)));
|
||||||
@@ -132,26 +124,15 @@ class GameSession {
|
|||||||
const update = new ev.EventGameUpdate();
|
const update = new ev.EventGameUpdate();
|
||||||
update.playerLeft.y = gc.playerLeft.pos.y;
|
update.playerLeft.y = gc.playerLeft.pos.y;
|
||||||
update.playerRight.y = gc.playerRight.pos.y;
|
update.playerRight.y = gc.playerRight.pos.y;
|
||||||
|
gc.ballsArr.forEach((ball) => {
|
||||||
update.ball.x = gc.ball.pos.x;
|
update.ballsArr.push({
|
||||||
update.ball.y = gc.ball.pos.y;
|
x: ball.pos.x,
|
||||||
update.ball.dirX = gc.ball.dir.x;
|
y: ball.pos.y,
|
||||||
update.ball.dirY = gc.ball.dir.y;
|
dirX: ball.dir.x,
|
||||||
update.ball.speed = gc.ball.speed;
|
dirY: ball.dir.y,
|
||||||
if (s.matchOptions & en.MatchOptions.multiBalls)
|
speed: ball.speed
|
||||||
{ // 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) => {
|
s.playersMap.forEach( (client) => {
|
||||||
update.lastInputId = client.lastInputId;
|
update.lastInputId = client.lastInputId;
|
||||||
@@ -176,6 +157,7 @@ class GameSession {
|
|||||||
ball.ballInPlay = true;
|
ball.ballInPlay = true;
|
||||||
}
|
}
|
||||||
private _matchEnd(s: GameSession) {
|
private _matchEnd(s: GameSession) {
|
||||||
|
s.matchEnded = true;
|
||||||
const gc = s.components;
|
const gc = s.components;
|
||||||
|
|
||||||
let eventEnd: ev.EventMatchEnd;
|
let eventEnd: ev.EventMatchEnd;
|
||||||
|
|||||||
@@ -32,27 +32,13 @@ class EventGameUpdate extends ServerEvent {
|
|||||||
playerRight = {
|
playerRight = {
|
||||||
y: 0
|
y: 0
|
||||||
};
|
};
|
||||||
ball = {
|
ballsArr: {
|
||||||
x: 0,
|
x: number,
|
||||||
y: 0,
|
y: number,
|
||||||
dirX: 0,
|
dirX: number,
|
||||||
dirY: 0,
|
dirY: number,
|
||||||
speed: 0
|
speed: number
|
||||||
};
|
}[] = [];
|
||||||
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);
|
||||||
|
|||||||
@@ -3,15 +3,14 @@ import * as c from "../constants.js"
|
|||||||
import * as en from "../../shared_js/enums.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";
|
||||||
|
import { clamp, random } from "../utils.js";
|
||||||
|
|
||||||
class GameComponents {
|
class GameComponents {
|
||||||
wallTop: Rectangle;
|
wallTop: Rectangle;
|
||||||
wallBottom: Rectangle;
|
wallBottom: Rectangle;
|
||||||
playerLeft: Racket;
|
playerLeft: Racket;
|
||||||
playerRight: Racket;
|
playerRight: Racket;
|
||||||
ball: Ball;
|
ballsArr: Ball[] = [];
|
||||||
ball2?: Ball;
|
|
||||||
ball3?: Ball;
|
|
||||||
constructor(options: en.MatchOptions)
|
constructor(options: en.MatchOptions)
|
||||||
{
|
{
|
||||||
let pos = new VectorInteger;
|
let pos = new VectorInteger;
|
||||||
@@ -26,18 +25,27 @@ class GameComponents {
|
|||||||
pos.assign(c.w-c.pw-c.pw, c.h_mid-c.ph/2);
|
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);
|
this.playerRight = new Racket(pos, c.pw, c.ph, c.racketSpeed);
|
||||||
|
|
||||||
pos.assign(-c.ballSize, -c.ballSize); // ball out =)
|
let ballsCount = 1;
|
||||||
this.ball = new Ball(pos, c.ballSize, c.ballSpeed, c.ballSpeedIncrease);
|
if (options & en.MatchOptions.multiBalls) {
|
||||||
this.ball.dir.assign(-0.8, +0.2);
|
ballsCount = c.multiBallsCount;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,3 +19,5 @@ export const normalizedSpeed = false; // for consistency in speed independent of
|
|||||||
|
|
||||||
export const matchStartDelay = 3000; // millisecond
|
export const matchStartDelay = 3000; // millisecond
|
||||||
export const newRoundDelay = 1500; // millisecond
|
export const newRoundDelay = 1500; // millisecond
|
||||||
|
|
||||||
|
export const multiBallsCount = 3;
|
||||||
|
|||||||
@@ -7,4 +7,13 @@ function sleep (ms: number) {
|
|||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
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}
|
||||||
|
|||||||
Reference in New Issue
Block a user