Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/apis/arena.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Arena {
ratio,
scaling.screenToCanvas(new Vector(_window.innerWidth, _window.innerHeight))
);
const arenaSize = Vector.round(scaling.toArenaUnits(arenaDim));
const arenaSize = scaling.toArenaUnits(arenaDim);
this.#size = arenaSize.x;
}, 16);
}
Expand Down
17 changes: 13 additions & 4 deletions src/apis/camera.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { Vector } from '../core/vector';

import { arena } from './arena';
import { game } from './game';
import { minimap } from './minimap';

class Camera {
#position: Vector;

constructor() {
game.on('frame_end', () => {
const center = Vector.add(minimap.viewportPos, Vector.unscale(2, minimap.viewportDim));
const cameraPos = Vector.subtract(center, minimap.minimapPos);
const normalized = Vector.divide(cameraPos, minimap.minimapDim);
this.#position = arena.scale(normalized);
});
}

get position(): Vector {
const center = Vector.add(minimap.viewportPos, Vector.unscale(2, minimap.viewportDim));
const cameraPos = Vector.subtract(center, minimap.minimapPos);
const normalized = Vector.divide(cameraPos, minimap.minimapDim);
return arena.scale(normalized);
return this.#position;
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/apis/game.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { CanvasKit } from '../core/canvas_kit';
import { EventEmitter } from '../core/event_emitter';

/**
* Events:
* - frame: Emitted every frame. Can be used for things that should be executed on every frame
* - frame_end: Emitted after `frame` and is mainly used internally to update position variables
*/
class Game extends EventEmitter {
#ready = false;

Expand All @@ -17,6 +22,7 @@ class Game extends EventEmitter {
}

super.emit('frame');
super.emit('frame_end');
}

#onready(): void {
Expand Down
2 changes: 1 addition & 1 deletion src/apis/player_movement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PlayerMovement extends Movement {
constructor() {
super();

game.on('frame', () => super.updatePos(arena.scale(minimap.arrowPos)));
game.on('frame_end', () => super.updatePos(arena.scale(minimap.arrowPos)));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/apis/scaling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Scaling {
* @returns {Vector} The vector in arena units
*/
toArenaUnits(v: Vector): Vector {
return Vector.unscale(this.#scalingFactor, v);
return Vector.round(Vector.unscale(this.#scalingFactor, v));
}

/**
Expand All @@ -61,7 +61,7 @@ class Scaling {
* @returns {Vector} The vector in canvas units
*/
toCanvasUnits(v: Vector): Vector {
return Vector.scale(this.#scalingFactor, v);
return Vector.round(Vector.scale(this.#scalingFactor, v));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/extensions/debug_tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class DebugTool extends Extension {
}

#_drawParent(entity: Entity, position: Vector) {
if (entity.parent === null) {
if (entity.parent == null) {
return;
}

Expand Down
72 changes: 36 additions & 36 deletions src/extensions/entity_manager.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import { CanvasKit } from '../core/canvas_kit';
import { CanvasKit, Vector } from '../core';
import { game, playerMovement, scaling } from '../apis';
import { Entity, EntityType, EntityColor, TeamColors } from '../types/entity';
import { Extension } from './extension';
import { Vector } from '../core/vector';

import { game } from '../apis/game';
import { playerMovement } from '../apis/player_movement';
import { scaling } from '../apis/scaling';
const random_id = () => Math.random().toString(36).slice(2, 5);

/**
* Entity Manager is used to access the information about the entities, that are currently drawn on the screen.
* To access the entities the EntityManager exposes the EntityManager.entities field.
*/
class EntityManager extends Extension {
#entities: Entity[] = [];
#entitiesUpdated: Entity[] = [];
#entitiesLastFrame: Entity[] = this.#entities;

constructor() {
super(() => {
game.on('frame', () => {
this.#entities = this.#entitiesUpdated;
this.#entitiesUpdated = [];
game.on('frame_end', () => {
this.#entitiesLastFrame = this.#entities;
this.#entities = [];
});

this.#triangleHook();
Expand Down Expand Up @@ -53,58 +51,60 @@ class EntityManager extends Extension {
}

/**
* Adds the entity to `#entitiesUpdated`.
* Adds the entity to `#entities`.
*
* Will either find the entity in `#entities` or create a new `Entity`.
* Will either find the entity in `#entitiesLastFrame` or create a new `Entity`.
*/
#add(type: EntityType, position: Vector, extras: object = {}) {
const entityIndex = this.#findEntity(type, position);

let entity: Entity;
if (entityIndex === -1) {
let parent = null;
if (type == EntityType.Bullet) {
// TODO: we want to change this to EntityType.Barrel in the future?
const parentIndex = this.#findEntity(EntityType.Player, position, 300);
if (parentIndex >= 0) {
parent = this.entities[parentIndex];
}
}
let entity = this.#findEntity(type, position);

if (!entity) {
const parent = this.#findParent(type, position);

entity = new Entity(type, parent, {
id: Math.random().toString(36).slice(2, 5),
id: random_id(),
timestamp: performance.now(),
...extras,
});
} else {
entity = this.#entities[entityIndex];
}
//TODO: remove radius from extras
entity.extras.radius = (extras as any).radius;

entity.updatePos(position);
this.#entitiesUpdated.push(entity);
this.#entities.push(entity);
}

/**
* If an entity is newly created, try to find it's parent entity.
*/
#findParent(type: EntityType, position: Vector): Entity {
if (type == EntityType.Bullet) {
// TODO: do we want to change the parent entity to EntityType.Barrel in the future?
return this.#findEntity(EntityType.Player, position, 300);
}
}

/**
* Searches `#entities` for the entity that is closest to `position` and
* returns the __index__ of that entity or __-1__ if there is no match.
* Searches `#entitiesLastFrame` for the entity that is closest to `position`
* @returns the entity or null if there is no match.
*/
#findEntity(type: EntityType, position: Vector, tolerance: number = 42): number {
let result = -1;
#findEntity(type: EntityType, position: Vector, tolerance: number = 42): Entity {
let result = null;
let shortestDistance = Infinity;

this.#entities.forEach((x, i) => {
if (x.type !== type) return;
this.#entitiesLastFrame.forEach((entity, i) => {
if (entity.type !== type) return;

const distance = Vector.distance(x.position, position);
const distance = Vector.distance(entity.position, position);

if (distance < shortestDistance) {
shortestDistance = distance;
result = i;
result = entity;
}
});

if (shortestDistance > tolerance) {
return -1;
return null;
}

return result;
Expand Down