opponent interpolation
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { gc } from "./global.js";
|
import { gc, clientInfo } from "./global.js";
|
||||||
|
|
||||||
let actual_time: number = Date.now();
|
let actual_time: number = Date.now();
|
||||||
let last_time: number;
|
let last_time: number;
|
||||||
@@ -7,17 +7,31 @@ let delta_time: number;
|
|||||||
|
|
||||||
function gameLoop()
|
function gameLoop()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
// I try to clear only what need to be update.
|
|
||||||
// Will revert to clear() all if not satisfactory.
|
|
||||||
pong.clear();
|
|
||||||
*/
|
|
||||||
last_time = actual_time;
|
last_time = actual_time;
|
||||||
actual_time = Date.now();
|
actual_time = Date.now();
|
||||||
delta_time = (actual_time - last_time) / 1000;
|
delta_time = (actual_time - last_time) / 1000;
|
||||||
|
|
||||||
|
// interpolation
|
||||||
|
// console.log(`dir.y: ${clientInfo.opponent.dir.y}, pos.y: ${clientInfo.opponent.pos.y}, opponentNextPos.y: ${clientInfo.opponentNextPos.y}`);
|
||||||
|
if (clientInfo.opponent.dir.y != 0 ) {
|
||||||
|
opponentInterpolation(delta_time);
|
||||||
|
}
|
||||||
|
|
||||||
// client prediction
|
// client 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function opponentInterpolation(delta: number)
|
||||||
|
{
|
||||||
|
// interpolation
|
||||||
|
clientInfo.opponent.moveAndCollide(delta, [gc.wallTop, gc.wallBottom]);
|
||||||
|
|
||||||
|
if ((clientInfo.opponent.dir.y > 0 && clientInfo.opponent.pos.y > clientInfo.opponentNextPos.y)
|
||||||
|
|| (clientInfo.opponent.dir.y < 0 && clientInfo.opponent.pos.y < clientInfo.opponentNextPos.y))
|
||||||
|
{
|
||||||
|
clientInfo.opponent.dir.y = 0;
|
||||||
|
clientInfo.opponent.pos.y = clientInfo.opponentNextPos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {gameLoop}
|
export {gameLoop}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { RacketClient } from "./class/RectangleClient.js";
|
|||||||
import { repeatInput } from "./handleInput.js";
|
import { repeatInput } from "./handleInput.js";
|
||||||
import { soundRoblox } from "./audio.js"
|
import { soundRoblox } from "./audio.js"
|
||||||
import { sleep } from "./utils.js";
|
import { sleep } from "./utils.js";
|
||||||
|
import { Vector, VectorInteger } from "../shared_js/class/Vector.js";
|
||||||
|
|
||||||
const wsPort = 8042;
|
const wsPort = 8042;
|
||||||
const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong";
|
const wsUrl = "ws://" + document.location.hostname + ":" + wsPort + "/pong";
|
||||||
@@ -17,6 +18,8 @@ class ClientInfo {
|
|||||||
id = "";
|
id = "";
|
||||||
side: en.PlayerSide;
|
side: en.PlayerSide;
|
||||||
racket: RacketClient;
|
racket: RacketClient;
|
||||||
|
opponent: RacketClient;
|
||||||
|
opponentNextPos: VectorInteger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clientInfo = new ClientInfo();
|
export const clientInfo = new ClientInfo();
|
||||||
@@ -43,12 +46,17 @@ function preMatchListener(this: WebSocket, event: MessageEvent) {
|
|||||||
break;
|
break;
|
||||||
case en.EventTypes.matchmakingComplete:
|
case en.EventTypes.matchmakingComplete:
|
||||||
clientInfo.side = (<ev.EventMatchmakingComplete>data).side;
|
clientInfo.side = (<ev.EventMatchmakingComplete>data).side;
|
||||||
if (clientInfo.side === en.PlayerSide.left) {
|
if (clientInfo.side === en.PlayerSide.left)
|
||||||
|
{
|
||||||
clientInfo.racket = gc.playerLeft;
|
clientInfo.racket = gc.playerLeft;
|
||||||
|
clientInfo.opponent = gc.playerRight;
|
||||||
}
|
}
|
||||||
else if (clientInfo.side === en.PlayerSide.right) {
|
else if (clientInfo.side === en.PlayerSide.right)
|
||||||
|
{
|
||||||
clientInfo.racket = gc.playerRight;
|
clientInfo.racket = gc.playerRight;
|
||||||
|
clientInfo.opponent = gc.playerLeft;
|
||||||
}
|
}
|
||||||
|
clientInfo.opponentNextPos = new VectorInteger(clientInfo.opponent.pos.x, clientInfo.opponent.pos.y);
|
||||||
clientInfo.racket.color = "darkgreen"; // for testing purpose
|
clientInfo.racket.color = "darkgreen"; // for testing purpose
|
||||||
socket.send(JSON.stringify( new ev.ClientEvent(en.EventTypes.clientPlayerReady) ));
|
socket.send(JSON.stringify( new ev.ClientEvent(en.EventTypes.clientPlayerReady) ));
|
||||||
matchmakingComplete();
|
matchmakingComplete();
|
||||||
@@ -66,7 +74,7 @@ function inGameListener(event: MessageEvent)
|
|||||||
const data: ev.ServerEvent = JSON.parse(event.data);
|
const data: ev.ServerEvent = JSON.parse(event.data);
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case en.EventTypes.gameUpdate:
|
case en.EventTypes.gameUpdate:
|
||||||
// setTimeout(gameUpdate, 1000, data as ev.EventGameUpdate); // artificial latency for testing purpose
|
// setTimeout(gameUpdate, 500, data as ev.EventGameUpdate); // artificial latency for testing purpose
|
||||||
gameUpdate(data as ev.EventGameUpdate);
|
gameUpdate(data as ev.EventGameUpdate);
|
||||||
break;
|
break;
|
||||||
case en.EventTypes.scoreUpdate:
|
case en.EventTypes.scoreUpdate:
|
||||||
@@ -82,14 +90,36 @@ function gameUpdate(data: ev.EventGameUpdate)
|
|||||||
{
|
{
|
||||||
console.log("gameUpdate");
|
console.log("gameUpdate");
|
||||||
|
|
||||||
gc.playerLeft.pos.y = data.playerLeft.y;
|
|
||||||
gc.playerRight.pos.y = data.playerRight.y;
|
|
||||||
|
|
||||||
gc.ball.pos.assign(data.ball.x, data.ball.y);
|
gc.ball.pos.assign(data.ball.x, data.ball.y);
|
||||||
gc.ball.dir.assign(data.ball.dirX, data.ball.dirY);
|
gc.ball.dir.assign(data.ball.dirX, data.ball.dirY);
|
||||||
gc.ball.speed = data.ball.speed;
|
gc.ball.speed = data.ball.speed;
|
||||||
|
if (clientInfo.side === en.PlayerSide.left) {
|
||||||
|
clientInfo.racket.pos.assign(clientInfo.racket.pos.x, data.playerLeft.y);
|
||||||
|
}
|
||||||
|
else if (clientInfo.side === en.PlayerSide.right) {
|
||||||
|
clientInfo.racket.pos.assign(clientInfo.racket.pos.x, data.playerRight.y);
|
||||||
|
}
|
||||||
|
|
||||||
repeatInput(data.lastInputId); // server reconciliation
|
// interpolation
|
||||||
|
clientInfo.opponent.pos.assign(clientInfo.opponentNextPos.x, clientInfo.opponentNextPos.y);
|
||||||
|
if (clientInfo.side === en.PlayerSide.left) {
|
||||||
|
clientInfo.opponentNextPos.assign(clientInfo.opponent.pos.x, data.playerRight.y);
|
||||||
|
}
|
||||||
|
else if (clientInfo.side === en.PlayerSide.right) {
|
||||||
|
clientInfo.opponentNextPos.assign(clientInfo.opponent.pos.x, data.playerLeft.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
clientInfo.opponent.dir = new Vector(
|
||||||
|
clientInfo.opponentNextPos.x - clientInfo.opponent.pos.x,
|
||||||
|
clientInfo.opponentNextPos.y - clientInfo.opponent.pos.y
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Math.abs(clientInfo.opponent.dir.x) + Math.abs(clientInfo.opponent.dir.y) !== 0) {
|
||||||
|
clientInfo.opponent.dir = clientInfo.opponent.dir.normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
// server reconciliation
|
||||||
|
repeatInput(data.lastInputId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function scoreUpdate(data: ev.EventScoreUpdate)
|
function scoreUpdate(data: ev.EventScoreUpdate)
|
||||||
|
|||||||
@@ -42,9 +42,7 @@ class MovingRectangle extends Rectangle implements Moving {
|
|||||||
this.speed = baseSpeed;
|
this.speed = baseSpeed;
|
||||||
}
|
}
|
||||||
move(delta: number) { // Math.floor WIP until VectorInteger debug
|
move(delta: number) { // Math.floor WIP until VectorInteger debug
|
||||||
// console.log("delta: "+ delta);
|
// console.log(`delta: ${delta}, speed: ${this.speed}, speed*delta: ${this.speed * delta}`);
|
||||||
// console.log("speed: "+ this.speed);
|
|
||||||
// console.log("speed*delta: "+ this.speed * delta);
|
|
||||||
this.pos.x += Math.floor(this.dir.x * this.speed * delta);
|
this.pos.x += Math.floor(this.dir.x * this.speed * delta);
|
||||||
this.pos.y += Math.floor(this.dir.y * this.speed * delta);
|
this.pos.y += Math.floor(this.dir.y * this.speed * delta);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user