+ client prediction
This commit is contained in:
LuckyLaszlo
2022-11-22 00:06:07 +01:00
parent 04203f4f9d
commit 2b9058ad49
43 changed files with 53 additions and 15 deletions

12
src/client/audio.ts Normal file
View File

@@ -0,0 +1,12 @@
import * as c from "./constants.js"
export const soundPong: HTMLAudioElement[] = [];
for (let i = 0; i <= 32; i++) {
soundPong.push(new Audio("http://localhost:8080/sound/pong/"+i+".mp3"));
soundPong[i].volume = c.soundPongVolume;
}
export const soundRoblox = new Audio("http://localhost:8080/sound/roblox-oof.mp3");
soundRoblox.volume = c.soundRobloxVolume;

View File

@@ -2,6 +2,8 @@
import {Vector, VectorInteger} from "../../shared_js/class/Vector.js";
import {Component, GraphicComponent, Moving} from "../../shared_js/class/interface.js";
import { Rectangle, MovingRectangle, Racket, Ball } from "../../shared_js/class/Rectangle.js";
import {soundPong, soundRoblox} from "../audio.js"
import { random } from "../utils.js";
function updateRectangle(this: RectangleClient) {
this.ctx.fillStyle = this.color;
@@ -87,6 +89,14 @@ class BallClient extends Ball implements GraphicComponent {
this.update = updateRectangle;
this.clear = clearRectangle;
}
bounce(collider?: Rectangle) {
this._bounceAlgo(collider);
soundPong[ Math.floor(random(0, soundPong.length)) ].play();
}
/* protected _bouncePlayer(collider: Racket) {
this._bouncePlayerAlgo(collider);
soundRoblox.play();
} */
}
function updateLine(this: Line) {

View File

@@ -8,3 +8,5 @@ export const gridSize = Math.floor(w/500);
// min interval on Firefox seems to be 15. Chrome can go lower.
export const gameLoopIntervalMS = 15; // millisecond
export const soundRobloxVolume = 0.3; // between 0 and 1
export const soundPongVolume = 0.3; // between 0 and 1

View File

@@ -1,3 +1,4 @@
import {gc} from "./global.js";
import * as d from "./draw.js";
import {handleInput} from "./handleInput.js";
@@ -19,7 +20,7 @@ function gameLoop()
handleInput(delta_time);
// 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]);
d.draw();
}

View File

@@ -27,24 +27,23 @@ function handleInput(delta: number)
function playerMove(delta: number, keys: string[])
{
if (keys.indexOf("w") != -1) {
if (keys.indexOf("w") != -1 || keys.indexOf("ArrowUp".toLowerCase()) != -1) {
socket.send(JSON.stringify(new EventInput(InputEnum.up)));
}
if (keys.indexOf("s") != -1) {
if (keys.indexOf("s") != -1 || keys.indexOf("ArrowDown".toLowerCase()) != -1) {
socket.send(JSON.stringify(new EventInput(InputEnum.down)));
}
// prediction
/* const racket = clientInfo.racket;
const racket = clientInfo.racket;
racket.dir.y = 0;
if (keys.indexOf("w") != -1) {
if (keys.indexOf("w") != -1 || keys.indexOf("ArrowUp".toLowerCase()) != -1) {
racket.dir.y += -1;
}
if (keys.indexOf("s") != -1) {
if (keys.indexOf("s") != -1 || keys.indexOf("ArrowDown".toLowerCase()) != -1) {
racket.dir.y += 1;
}
racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]); */
racket.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]);
}
export {handleInput}

View File

@@ -9,8 +9,7 @@ import {countdown} from "./utils.js";
import {socket} from "./ws.js"; socket; // no-op
/* Keys
Racket 1: W/S
Racket 2: Up/Down
Racket: W/S OR Up/Down
Grid On-Off: G
*/
@@ -42,7 +41,5 @@ function resumeGame()
pong.interval = window.setInterval(gameLoop, c.gameLoopIntervalMS);
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
export {matchmaking, matchmakingComplete, startGame}

View File

@@ -5,6 +5,8 @@ import {matchmaking, matchmakingComplete, startGame} from "./pong.js";
import * as en from "../shared_js/enums.js"
import { Racket } from "../shared_js/class/Rectangle.js";
import { sleep } from "./utils.js";
import * as c from "./constants.js"
import {soundRoblox} from "./audio.js"
const wsPort = 8042;
const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong";
@@ -88,6 +90,12 @@ async function gameUpdate(data: ev.EventGameUpdate)
function scoreUpdate(data: ev.EventScoreUpdate)
{
if (clientInfo.side === en.PlayerSide.left && data.scoreRight > gc.scoreRight.value) {
soundRoblox.play();
}
else if (clientInfo.side === en.PlayerSide.right && data.scoreLeft > gc.scoreLeft.value) {
soundRoblox.play();
}
gc.scoreLeft.value = data.scoreLeft;
gc.scoreRight.value = data.scoreRight;
}

View File

@@ -23,9 +23,12 @@ const server = http.createServer((req, res) => {
if (path.extname(filename) === ".html") {
res.writeHead(200, {"Content-Type": "text/html"});
}
if (path.extname(filename) === ".js") {
else if (path.extname(filename) === ".js") {
res.writeHead(200, {"Content-Type": "application/javascript"});
}
else if (path.extname(filename) === ".mp3") {
res.writeHead(200, {"Content-Type": "audio/mpeg"});
}
res.write(data);
return res.end();
});

View File

@@ -69,6 +69,9 @@ class Ball extends MovingRectangle {
super(pos, size, size, baseSpeed);
}
bounce(collider?: Rectangle) {
this._bounceAlgo(collider);
}
protected _bounceAlgo(collider?: Rectangle) {
/* Could be more generic, but testing only Racket is enough,
because in Pong collider can only be Racket or Wall. */
if (collider instanceof Racket) {
@@ -87,10 +90,13 @@ class Ball extends MovingRectangle {
this.move(delta);
}
}
private _bounceWall() { // Should be enough for Wall
protected _bounceWall() { // Should be enough for Wall
this.dir.y = this.dir.y * -1;
}
private _bouncePlayer(collider: Racket) { // WIP
protected _bouncePlayer(collider: Racket) {
this._bouncePlayerAlgo(collider);
}
protected _bouncePlayerAlgo(collider: Racket) { // WIP
// Bounce for Racket need to be more complexe than this
this.speed += this.baseSpeed/20;
this.dir.x = this.dir.x * -1;

BIN
www/sound/pong/0.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/1.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/10.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/11.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/12.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/13.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/14.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/15.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/16.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/17.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/18.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/19.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/2.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/20.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/21.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/22.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/23.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/24.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/25.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/26.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/27.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/28.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/29.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/3.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/30.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/31.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/32.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/4.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/5.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/6.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/7.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/8.mp3 Normal file

Binary file not shown.

BIN
www/sound/pong/9.mp3 Normal file

Binary file not shown.

BIN
www/sound/roblox-oof.mp3 Normal file

Binary file not shown.