Skip to content

Commit

Permalink
Merge pull request #11 from ufocoder/mouse-rotation
Browse files Browse the repository at this point in the history
Lookup by mouse - v1.0.0)
  • Loading branch information
ufocoder authored May 22, 2024
2 parents 787a764 + 489b7f9 commit 2f29e34
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 79 deletions.
2 changes: 2 additions & 0 deletions src/lib/ecs/components/MoveComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export default class MoveComponent implements Component {
direction = {
forward: false,
back: false,
left: false,
right: false,
};

constructor(moveSpeed: number = 0) {
Expand Down
9 changes: 3 additions & 6 deletions src/lib/ecs/components/RotateComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import { Component } from "src/lib/ecs/Component";

export default class RotateComponent implements Component {
rotationSpeed: number;

direction = {
left: false,
right: false,
};
rotationFactor: number;

constructor(rotationSpeed: number = 0) {
constructor(rotationSpeed = 0) {
this.rotationSpeed = rotationSpeed;
this.rotationFactor = 0;
}
}
2 changes: 1 addition & 1 deletion src/lib/ecs/systems/AISystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class AISystem extends System {
entityAI.lastAttackTime = 0;
}

if (entityAI.lastAttackTime >= 1) {
if (entityAI.lastAttackTime >= 0.5) {
this.soundManager.play('zombie-attack');
cameraHealth.current = Math.max(0, cameraHealth.current - entityAI.damagePerSecond);
entityAI.lastAttackTime = 0;
Expand Down
99 changes: 60 additions & 39 deletions src/lib/ecs/systems/ControlSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,40 @@ import System from "src/lib/ecs/System";
import MoveComponent from "src/lib/ecs/components/MoveComponent";
import RotateComponent from "src/lib/ecs/components/RotateComponent";
import { Entity } from "../Entity";
import ECS from "..";

const keyCodes = {
up: "KeyW",
down: "KeyS",
left: "KeyA",
right: "KeyD",
const keyCodes: Record<string, string> = {
KeyW: 'up',
KeyS: 'down',
KeyA: 'left',
KeyD: 'right',
};

export default class ControlSystem extends System {
componentsRequired = new Set([MoveComponent, RotateComponent]);

direction = {
protected readonly container: HTMLElement;

direction: Record<string, boolean> = {
up: false,
down: false,
left: false,
right: false,
};

pointerStartX: number | undefined;
rotationFactor = 0;
isPointerLocked = false;

constructor(ecs: ECS, container: HTMLElement) {
super(ecs);

this.container = container;
}

start(): void {
this.createListeners();
this.requestPointerLock();
}

update(_: number, entities: Set<Entity>) {
Expand All @@ -30,63 +44,70 @@ export default class ControlSystem extends System {
const rotateComponent = components.get(RotateComponent);
const moveComponent = components.get(MoveComponent);

rotateComponent.direction.left = this.direction.left;
rotateComponent.direction.right = this.direction.right;
rotateComponent.rotationFactor = this.rotationFactor;

moveComponent.direction.forward = this.direction.up;
moveComponent.direction.back = this.direction.down;
moveComponent.direction.left = this.direction.left;
moveComponent.direction.right = this.direction.right;
});
}

this.rotationFactor = 0;
}

destroy(): void {
document.exitPointerLock();
this.destroyListeners();
}

activateDirectionByKeyCode = (keyCode: string) => {
if (keyCode === keyCodes.up) {
this.direction.up = true;
}
if (keyCode === keyCodes.down) {
this.direction.down = true;
}
if (keyCode === keyCodes.left) {
this.direction.left = true;
}
if (keyCode === keyCodes.right) {
this.direction.right = true;
}
};
setDirection(keyCode: string, value: boolean) {
const direction = keyCodes[keyCode];

deactivateDirectionByKeyCode = (keyCode: string) => {
if (keyCode === keyCodes.up) {
this.direction.up = false;
}
if (keyCode === keyCodes.down) {
this.direction.down = false;
if (!direction) {
return;
}
if (keyCode === keyCodes.left) {
this.direction.left = false;
}
if (keyCode === keyCodes.right) {
this.direction.right = false;
}
};

this.direction[direction] = value;
}

handleDocumentKeyDown = (e: KeyboardEvent) => {
this.activateDirectionByKeyCode(e.code);
this.setDirection(e.code, true);
};

handleDocumentKeyUp = (e: KeyboardEvent) => {
this.deactivateDirectionByKeyCode(e.code);
this.setDirection(e.code, false);
};

handleDocumentMouseMove = (e: MouseEvent) => {
this.rotationFactor = e.movementX;
};

handlePointerLockChange = () => {
if (this.isPointerLocked) {
document.addEventListener("mousemove", this.handleDocumentMouseMove);
} else {
document.removeEventListener("mousemove", this.handleDocumentMouseMove);
}

this.isPointerLocked = !this.isPointerLocked;
}

requestPointerLock = () => {
this.container.requestPointerLock();
this.isPointerLocked = true;
};

createListeners() {
document.addEventListener("keydown", this.handleDocumentKeyDown);
document.addEventListener("keyup", this.handleDocumentKeyUp);
document.addEventListener("pointerlockchange", this.handlePointerLockChange);
this.container.addEventListener("click", this.requestPointerLock);
}

destroyListeners() {
document.removeEventListener("keydown", this.handleDocumentKeyDown);
document.removeEventListener("keyup", this.handleDocumentKeyUp);
document.removeEventListener("pointerlockchange", this.handlePointerLockChange);
this.container.removeEventListener("click", this.requestPointerLock);
}
}
}
47 changes: 16 additions & 31 deletions src/lib/ecs/systems/MoveSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,9 @@ export default class MoveSystem extends System {
protected rotate(dt: number, entity: Entity) {
const components = this.ecs.getComponents(entity)
const angleComponent = components.get(AngleComponent);
const rotateComponent = components.get(RotateComponent);
const { rotationFactor, rotationSpeed } = components.get(RotateComponent);

let k = 0;

if (rotateComponent.direction.right) {
k = 1;
}

if (rotateComponent.direction.left) {
k = -1;
}

if (k) {
angleComponent.angle = normalizeAngle(angleComponent.angle + k * rotateComponent.rotationSpeed * dt);
}
angleComponent.angle = normalizeAngle(angleComponent.angle + rotationFactor * rotationSpeed * dt);
}

protected move(dt: number, entity: Entity) {
Expand All @@ -86,23 +74,20 @@ export default class MoveSystem extends System {

const angleComponent = components.get(AngleComponent);
const positionComponent = components.get(PositionComponent);
const moveComponent = components.get(MoveComponent);

let k = 0;

if (moveComponent.direction.forward) {
k = 1;
}

if (moveComponent.direction.back) {
k = -1;
}

if (k) {
const playerCos = Math.cos(degreeToRadians(angleComponent.angle));
const playerSin = Math.sin(degreeToRadians(angleComponent.angle));
const newX = positionComponent.x + k * playerCos * moveComponent.moveSpeed * dt;
const newY = positionComponent.y + k * playerSin * moveComponent.moveSpeed * dt;
const {
direction: { forward, back, right, left },
moveSpeed,
} = components.get(MoveComponent);

const k = Number(forward) - Number(back);
const n = Number(right) - Number(left);

if (k || n) {
const playerAngle = degreeToRadians(angleComponent.angle);
const playerCos = Math.cos(playerAngle);
const playerSin = Math.sin(playerAngle);
const newX = positionComponent.x + (k * playerCos + n * playerSin) * moveSpeed * dt;
const newY = positionComponent.y + (k * playerSin + n * playerCos) * moveSpeed * dt;

if (newX <= 0 || newX > this.cols) {
return
Expand Down
1 change: 1 addition & 0 deletions src/lib/ecs/systems/UISystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default class UISystem extends System {

start() {
this.container.appendChild(this.canvas.element);
this.canvas.element.requestPointerLock();
}

update() {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function createWorld(ecs: ECS, level: Level, textureManager: TextureManag
ecs.addComponent(player, new HealthComponent(level.player.health, level.player.health));
ecs.addComponent(player, new AngleComponent(level.player.angle));
ecs.addComponent(player, new MoveComponent(3));
ecs.addComponent(player, new RotateComponent(360 / 4.5));
ecs.addComponent(player, new RotateComponent(360 / 15));
ecs.addComponent(player, new CameraComponent(60));
ecs.addComponent(player, new MinimapComponent('black'));

Expand Down
2 changes: 1 addition & 1 deletion src/scenes/LevelScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class LevelScene implements BaseScene {

const ecs = new ECS();

ecs.addSystem(new ControlSystem(ecs));
ecs.addSystem(new ControlSystem(ecs, container));
ecs.addSystem(new AISystem(ecs, level, soundManager));
ecs.addSystem(new MoveSystem(ecs, level));
ecs.addSystem(new AnimationSystem(ecs));
Expand Down

0 comments on commit 2f29e34

Please sign in to comment.