Skip to content

Commit

Permalink
Factor player controls into hot-reloadable game module
Browse files Browse the repository at this point in the history
  • Loading branch information
rexim committed Jul 1, 2024
1 parent fa43a83 commit eea45b5
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 72 deletions.
27 changes: 27 additions & 0 deletions game.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 32 additions & 1 deletion game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,20 @@ function castRay(scene: Scene, p1: Vector2, p2: Vector2): Vector2 {
export interface Player {
position: Vector2;
direction: number;
movingForward: boolean;
movingBackward: boolean;
turningLeft: boolean;
turningRight: boolean;
}

export function createPlayer(position: Vector2, direction: number): Player {
return {
position: position,
direction: direction,
movingForward: false,
movingBackward: false,
turningLeft: false,
turningRight: false,
}
}

Expand Down Expand Up @@ -450,6 +458,30 @@ function renderFloorIntoImageData(imageData: ImageData, player: Player, scene: S
}

export function renderGameIntoImageData(ctx: CanvasRenderingContext2D, backCtx: OffscreenCanvasRenderingContext2D, backImageData: ImageData, deltaTime: number, player: Player, scene: Scene) {
let velocity = Vector2.zero();
let angularVelocity = 0.0;
if (player.movingForward) {
velocity = velocity.add(Vector2.angle(player.direction).scale(PLAYER_SPEED))
}
if (player.movingBackward) {
velocity = velocity.sub(Vector2.angle(player.direction).scale(PLAYER_SPEED))
}
if (player.turningLeft) {
angularVelocity -= Math.PI;
}
if (player.turningRight) {
angularVelocity += Math.PI;
}
player.direction = player.direction + angularVelocity*deltaTime;
const nx = player.position.x + velocity.x*deltaTime;
if (sceneCanRectangleFitHere(scene, new Vector2(nx, player.position.y), Vector2.scalar(PLAYER_SIZE))) {
player.position.x = nx;
}
const ny = player.position.y + velocity.y*deltaTime;
if (sceneCanRectangleFitHere(scene, new Vector2(player.position.x, ny), Vector2.scalar(PLAYER_SIZE))) {
player.position.y = ny;
}

const minimapPosition = Vector2.zero().add(canvasSize(ctx).scale(0.03));
const cellSize = ctx.canvas.width*0.03;
const minimapSize = sceneSize(scene).scale(cellSize);
Expand All @@ -467,4 +499,3 @@ export function renderGameIntoImageData(ctx: CanvasRenderingContext2D, backCtx:
ctx.fillStyle = "white"
ctx.fillText(`${Math.floor(1/deltaTime)}`, 100, 100);
}

43 changes: 8 additions & 35 deletions index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 8 additions & 36 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,23 @@ async function loadImageData(url: string): Promise<ImageData> {
if (backCtx === null) throw new Error("2D context is not supported");
backCtx.imageSmoothingEnabled = false;

let movingForward = false;
let movingBackward = false;
let turningLeft = false;
let turningRight = false;

window.addEventListener("keydown", (e) => {
if (!e.repeat) {
switch (e.code) {
case 'KeyW': movingForward = true; break;
case 'KeyS': movingBackward = true; break;
case 'KeyA': turningLeft = true; break;
case 'KeyD': turningRight = true; break;
case 'KeyW': player.movingForward = true; break;
case 'KeyS': player.movingBackward = true; break;
case 'KeyA': player.turningLeft = true; break;
case 'KeyD': player.turningRight = true; break;
}
}
});
window.addEventListener("keyup", (e) => {
if (!e.repeat) {
switch (e.code) {
case 'KeyW': movingForward = false; break;
case 'KeyS': movingBackward = false; break;
case 'KeyA': turningLeft = false; break;
case 'KeyD': turningRight = false; break;
case 'KeyW': player.movingForward = false; break;
case 'KeyS': player.movingBackward = false; break;
case 'KeyA': player.turningLeft = false; break;
case 'KeyD': player.turningRight = false; break;
}
}
});
Expand All @@ -103,29 +98,6 @@ async function loadImageData(url: string): Promise<ImageData> {
const frame = (timestamp: number) => {
const deltaTime = (timestamp - prevTimestamp)/1000;
prevTimestamp = timestamp;
let velocity = game.Vector2.zero();
let angularVelocity = 0.0;
if (movingForward) {
velocity = velocity.add(game.Vector2.angle(player.direction).scale(game.PLAYER_SPEED))
}
if (movingBackward) {
velocity = velocity.sub(game.Vector2.angle(player.direction).scale(game.PLAYER_SPEED))
}
if (turningLeft) {
angularVelocity -= Math.PI;
}
if (turningRight) {
angularVelocity += Math.PI;
}
player.direction = player.direction + angularVelocity*deltaTime;
const nx = player.position.x + velocity.x*deltaTime;
if (game.sceneCanRectangleFitHere(scene, new game.Vector2(nx, player.position.y), game.Vector2.scalar(game.PLAYER_SIZE))) {
player.position.x = nx;
}
const ny = player.position.y + velocity.y*deltaTime;
if (game.sceneCanRectangleFitHere(scene, new game.Vector2(player.position.x, ny), game.Vector2.scalar(game.PLAYER_SIZE))) {
player.position.y = ny;
}
game.renderGameIntoImageData(ctx, backCtx, backImageData, deltaTime, player, scene);
window.requestAnimationFrame(frame);
}
Expand Down

0 comments on commit eea45b5

Please sign in to comment.