1
0
Fork 0
spacetac/src/core/ArenaGrid.ts

106 lines
3.1 KiB
TypeScript
Raw Normal View History

2018-03-21 22:09:26 +00:00
module TK.SpaceTac {
/**
* Abstract grid for the arena where the battle takes place
*
2018-07-09 14:59:17 +00:00
* The grid is used to snap arena coordinates on grid vertices, for ships and targets
*
* The default implementation does not enforce any grid or unit (leaves coordinates as they are)
2018-03-21 22:09:26 +00:00
*/
2018-07-09 14:59:17 +00:00
export class ArenaGrid {
/**
* Get the base unit of measurement between two points
*/
getUnit(): number {
return 1;
}
/**
* Check that an arena location is on a grid vertex
*/
check(loc: IArenaLocation): boolean {
return arenaDistance(loc, this.snap(loc)) < 1e-8;
}
/**
* Snap a floating point arena location to a grid vertex
*/
snap(loc: IArenaLocation): IArenaLocation {
return loc;
}
/**
* Measure the distance between two points
*
* This returns a distance in grid units
*/
measure(loc1: IArenaLocation, loc2: IArenaLocation): number {
return arenaDistance(this.snap(loc1), this.snap(loc2));
}
2018-07-10 14:23:32 +00:00
/**
* Check that a location is in range of another
*/
inRange(loc1: IArenaLocation, loc2: IArenaLocation, range: number): boolean {
return this.measure(loc1, loc2) - range < 1e-8;
}
2018-03-21 22:09:26 +00:00
}
2018-07-09 09:38:42 +00:00
/**
2018-07-09 14:59:17 +00:00
* Pixel unbounded grid
2018-07-09 09:38:42 +00:00
*
2018-07-09 14:59:17 +00:00
* This will only round the coordinates to the pixels, with an optional unit for distance measurements
2018-07-09 09:38:42 +00:00
*/
2018-07-09 14:59:17 +00:00
export class PixelGrid extends ArenaGrid {
constructor(protected readonly unit = 1) {
super();
}
2018-07-10 14:23:32 +00:00
getUnit(): number {
return this.unit;
}
2018-07-09 09:38:42 +00:00
snap(loc: IArenaLocation): IArenaLocation {
return new ArenaLocation(Math.round(loc.x), Math.round(loc.y));
}
2018-07-09 14:59:17 +00:00
measure(loc1: IArenaLocation, loc2: IArenaLocation): number {
2018-07-12 14:16:39 +00:00
// FIXME
2018-07-10 14:23:32 +00:00
let d = super.measure(loc1, loc2) / this.unit;
let r = Math.round(d);
if (r >= d) {
2018-07-12 14:16:39 +00:00
return Math.ceil(d);
} else if (d - r < 1e-8) {
2018-07-10 14:23:32 +00:00
return r;
} else {
2018-07-12 14:16:39 +00:00
return Math.floor(d);
2018-07-10 14:23:32 +00:00
}
2018-07-09 14:59:17 +00:00
}
2018-07-09 09:38:42 +00:00
}
2018-03-21 22:09:26 +00:00
/**
* Hexagonal unbounded arena grid
*
* This grid is composed of regular hexagons where all vertices are at a same distance "unit" of the hexagon center
*/
2018-07-09 14:59:17 +00:00
export class HexagonalArenaGrid extends PixelGrid {
private readonly yunit: number;
constructor(unit: number, yfactor = Math.sqrt(0.75)) {
super(unit);
2018-03-21 22:09:26 +00:00
this.yunit = unit * yfactor;
}
snap(loc: IArenaLocation): IArenaLocation {
let yr = Math.round(loc.y / this.yunit);
let xr: number;
if (yr % 2 == 0) {
xr = Math.round(loc.x / this.unit);
} else {
xr = Math.round((loc.x - 0.5 * this.unit) / this.unit) + 0.5;
}
return new ArenaLocation((xr * this.unit) || 0, (yr * this.yunit) || 0);
}
}
}