feat(pong): made changes to allow local play
This commit is contained in:
parent
9947970f63
commit
4ec44420db
5 changed files with 66 additions and 11 deletions
|
|
@ -15,7 +15,9 @@ declare module 'ft_state' {
|
|||
}
|
||||
}
|
||||
|
||||
document.addEventListener("ft:pageChange", () => {
|
||||
document.addEventListener("ft:pageChange", (newUrl) => {
|
||||
// we are still on a pong page => keep the socket around !
|
||||
if (newUrl.detail.startsWith('/app/pong') || newUrl.detail.startsWith('/pong')) return;
|
||||
if (window.__state.pongSock !== undefined) window.__state.pongSock.close();
|
||||
window.__state.pongSock = undefined;
|
||||
});
|
||||
|
|
@ -59,6 +61,7 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
|
||||
let socket = getSocket();
|
||||
|
||||
let currentGame: GameUpdate | null = null;
|
||||
// keys handler
|
||||
const keys: Record<string, boolean> = {};
|
||||
|
||||
|
|
@ -70,17 +73,23 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
});
|
||||
|
||||
setInterval(() => { // key sender
|
||||
if (currentGame === null) return;
|
||||
let packet: GameMove = {
|
||||
move: null,
|
||||
moveRight: null,
|
||||
}
|
||||
if ((keys['w'] !== keys['s'])) {
|
||||
packet.move = keys['w'] ? 'up' : 'down';
|
||||
}
|
||||
if (currentGame.local && (keys['o'] !== keys['l'])) {
|
||||
packet.moveRight = keys['o'] ? 'up' : 'down';
|
||||
}
|
||||
|
||||
socket.emit('gameMove', packet);
|
||||
}, 1000 / 60);
|
||||
|
||||
const render = (state: GameUpdate) => {
|
||||
currentGame = state;
|
||||
//batLeft.style.transform = `translateY(${state.left.paddle.y}px) translateX(${state.left.paddle.x}px)`;
|
||||
batLeft.style.top = `${state.left.paddle.y}px`;
|
||||
batLeft.style.left = `${state.left.paddle.x}px`;
|
||||
|
|
@ -101,12 +110,15 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
score.innerText = `${state.left.score} | ${state.right.score}`
|
||||
}
|
||||
|
||||
socket.on('gameEnd', () => currentGame = null);
|
||||
|
||||
socket.on('gameUpdate', (state: GameUpdate) => render(state));
|
||||
socket.on('newGame', (state) => render(state));
|
||||
socket.on('newGame', (state: GameUpdate) => render(state));
|
||||
|
||||
socket.on('updateInformation', (e) => showInfo(`UpdateInformation: t=${e.totalUser};q=${e.inQueue}`));
|
||||
socket.on('queueEvent', (e) => showInfo(`QueueEvent: ${e}`));
|
||||
socket.emit('enqueue');
|
||||
//socket.emit('enqueue');
|
||||
socket.emit('localGame');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ export type GameUpdate = {
|
|||
right: { id: string, paddle: PaddleData, score: number };
|
||||
|
||||
ball: { x: number, y: number, size: number };
|
||||
local: boolean,
|
||||
}
|
||||
|
||||
export type GameMove = {
|
||||
move: 'up' | 'down' | null,
|
||||
// only used in local games
|
||||
moveRight: 'up' | 'down' | null,
|
||||
}
|
||||
|
||||
export interface ClientToServer {
|
||||
|
|
@ -32,6 +35,7 @@ export interface ClientToServer {
|
|||
debugInfo: () => void;
|
||||
gameMove: (up: GameMove) => void;
|
||||
connectedToGame: (gameId: string) => void;
|
||||
localGame: () => void,
|
||||
};
|
||||
|
||||
export interface ServerToClient {
|
||||
|
|
|
|||
|
|
@ -119,6 +119,13 @@ export class Pong {
|
|||
public ball: Ball = new Ball(Pong.GAME_WIDTH / 2, Pong.GAME_HEIGHT / 2, Pong.BALL_START_ANGLES[this.ballAngleIdx++]);
|
||||
|
||||
public score: [number, number] = [0, 0];
|
||||
public local: boolean = false;
|
||||
|
||||
public static makeLocal(owner: UserId): Pong {
|
||||
const game = new Pong(owner, owner);
|
||||
game.local = true;
|
||||
return game;
|
||||
}
|
||||
|
||||
constructor(
|
||||
public userLeft: UserId,
|
||||
|
|
@ -202,13 +209,14 @@ export class Pong {
|
|||
return null;
|
||||
}
|
||||
|
||||
public movePaddle(user: UserId, dir: 'up' | 'down') {
|
||||
const paddle =
|
||||
user === this.userLeft
|
||||
? this.leftPaddle
|
||||
: user == this.userRight
|
||||
? this.rightPaddle
|
||||
: null;
|
||||
public movePaddle(user: UserId | ('left' | 'right'), dir: 'up' | 'down') {
|
||||
let paddle: Paddle | null = null;
|
||||
if (this.local) {
|
||||
if (user === 'left') { paddle = this.leftPaddle; }
|
||||
else if (user === 'right') { paddle = this.rightPaddle; }
|
||||
}
|
||||
else if (user === this.userLeft) { paddle = this.leftPaddle; }
|
||||
else if (user === this.userRight) { paddle = this.rightPaddle; }
|
||||
if (paddle === null) return;
|
||||
paddle.move(dir);
|
||||
paddle.clamp(0, Pong.GAME_HEIGHT);
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ export type GameUpdate = {
|
|||
right: { id: string, paddle: PaddleData, score: number };
|
||||
|
||||
ball: { x: number, y: number, size: number };
|
||||
local: boolean,
|
||||
}
|
||||
|
||||
export type GameMove = {
|
||||
move: 'up' | 'down' | null,
|
||||
// only used in local games
|
||||
moveRight: 'up' | 'down' | null,
|
||||
}
|
||||
|
||||
export interface ClientToServer {
|
||||
|
|
@ -32,6 +35,7 @@ export interface ClientToServer {
|
|||
debugInfo: () => void;
|
||||
gameMove: (up: GameMove) => void;
|
||||
connectedToGame: (gameId: string) => void;
|
||||
localGame: () => void,
|
||||
};
|
||||
|
||||
export interface ServerToClient {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ class StateI {
|
|||
left: { id: g.userLeft, score: g.score[0], paddle: { x: g.leftPaddle.x, y: g.leftPaddle.y, width: g.leftPaddle.width, height: g.leftPaddle.height } },
|
||||
right: { id: g.userRight, score: g.score[1], paddle: { x: g.rightPaddle.x, y: g.rightPaddle.y, width: g.rightPaddle.width, height: g.rightPaddle.height } },
|
||||
ball: { x: g.ball.x, y: g.ball.y, size: g.ball.size },
|
||||
local: g.local,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +77,27 @@ class StateI {
|
|||
}
|
||||
}
|
||||
|
||||
private newLocalGame(sock: SSocket) {
|
||||
const user = this.users.get(sock.authUser.id);
|
||||
if (!user) return;
|
||||
|
||||
const gameId = newUUID() as unknown as GameId;
|
||||
const g = Pong.makeLocal(user.id);
|
||||
const iState: GameUpdate = StateI.getGameUpdateData(gameId, g);
|
||||
|
||||
user.socket.emit('newGame', iState);
|
||||
this.games.set(gameId, g);
|
||||
|
||||
user.currentGame = gameId;
|
||||
|
||||
g.gameUpdate = setInterval(() => {
|
||||
g.tick();
|
||||
this.gameUpdate(gameId, user.socket);
|
||||
if (g.checkWinner() !== null) { this.cleanupGame(gameId, g); }
|
||||
}, 1000 / StateI.UPDATE_INTERVAL_FRAMES);
|
||||
|
||||
}
|
||||
|
||||
private gameUpdate(id: GameId, sock: SSocket) {
|
||||
// does the game we want to update the client exists ?
|
||||
if (!this.games.has(id)) return;
|
||||
|
|
@ -94,7 +116,11 @@ class StateI {
|
|||
if (user.currentGame === null || !this.games.has(user.currentGame)) return;
|
||||
const game = this.games.get(user.currentGame)!;
|
||||
|
||||
if (u.move !== null) { game.movePaddle(user.id, u.move); }
|
||||
if (game.local) {
|
||||
if (u.move !== null) { game.movePaddle('left', u.move); }
|
||||
if (u.moveRight !== null) { game.movePaddle('right', u.moveRight); }
|
||||
}
|
||||
else if (u.move !== null) { game.movePaddle(user.id, u.move); }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -119,6 +145,7 @@ class StateI {
|
|||
socket.on('dequeue', () => this.dequeueUser(socket));
|
||||
|
||||
socket.on('gameMove', (e) => this.gameMove(socket, e));
|
||||
socket.on('localGame', () => this.newLocalGame(socket));
|
||||
}
|
||||
|
||||
private updateClient(socket: SSocket): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue