more straightforward approach to providing location data for wrapped maps

This commit is contained in:
Gavin McDonald
2019-01-12 22:50:36 -05:00
parent a5bcda516a
commit 064bf10e98
7 changed files with 132 additions and 101 deletions

View File

@@ -23,8 +23,6 @@ export default class Cartographer {
'setOriginX',
'setOriginY',
'pixelToTile',
'zoom',
'remap',
@@ -157,11 +155,6 @@ export default class Cartographer {
}
}
pixelToTile (point) {
const tile = this._pixelToTile(point);
return this.wrap ? this.teleport(tile) : tile;
}
zoom (event) {
const scaleOrig = this.scale;

View File

@@ -6,7 +6,11 @@ import {rangeInclusive, invSqrt2} from './utils.js';
import Point from './point.js';
import Square from './square.js';
const tilePointToSquare = ({tilePoint, pixelPoint}) => ({tilePoint: new Square(tilePoint), pixelPoint});
const tilePointToSquare = ({tilePoint, mapPoint, pixelPoint}) => ({
tilePoint: tilePoint instanceof Square ? tilePoint : new Square(tilePoint),
mapPoint: mapPoint instanceof Square ? mapPoint : new Square(mapPoint),
pixelPoint,
});
export default class CartographerFlatXY extends Cartographer {
constructor(settings) {
@@ -29,7 +33,7 @@ export default class CartographerFlatXY extends Cartographer {
'calculateVerticalScale',
'tileToPixel',
'_pixelToTile',
'pixelToTile',
'teleport',
'inBounds',
@@ -81,13 +85,13 @@ export default class CartographerFlatXY extends Cartographer {
tileToPixel(square) {
square = square instanceof Square ? square : new Square(...arguments);
const x = square.getX() * this.minWidth();
const y = square.getY() * this.minWidth();
const x = (square.getX() * this.minWidth()) + this.originX;
const y = this.originY - (square.getY() * this.minWidth());
return new Point(x + this.originX, this.originY - y);
return new Point(x, y);
}
_pixelToTile (point) {
pixelToTile (point) {
point = point instanceof Point ? point : new Point(...arguments);
const pixelX = point.getX() - this.originX;
@@ -100,6 +104,8 @@ export default class CartographerFlatXY extends Cartographer {
}
teleport ({x, y}) {
if (!this.wrap) return new Point(x, y);
x = x % this.width;
y = y % this.height;
@@ -121,15 +127,15 @@ export default class CartographerFlatXY extends Cartographer {
}
enforceBoundries ({tilePoint, pixelPoint}) {
return this.wrap ? ({tilePoint: this.teleport(tilePoint), pixelPoint}) :
this.inBounds(tilePoint) ? ({tilePoint, pixelPoint}) :
null;
return this.wrap ? {tilePoint, mapPoint: this.teleport(tilePoint), pixelPoint} :
this.inBounds(tilePoint) ? {tilePoint, mapPoint: tilePoint, pixelPoint} :
{tilePoint, mapPoint: null, pixelPoint};
}
boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) {
const upperLeftTile = this._pixelToTile(upperLeftPoint);
const lowerRightTile = this._pixelToTile(lowerRightPoint);
const upperRightTile = this._pixelToTile(upperRightPoint);
const upperLeftTile = this.pixelToTile(upperLeftPoint);
const lowerRightTile = this.pixelToTile(lowerRightPoint);
const upperRightTile = this.pixelToTile(upperRightPoint);
const columns = rangeInclusive(upperLeftTile.getX(), upperRightTile.getX());
const rows = rangeInclusive(lowerRightTile.getY(), upperLeftTile.getY());
@@ -142,7 +148,6 @@ export default class CartographerFlatXY extends Cartographer {
.flatten()
.map(makeAPointPair)
.map(this.enforceBoundries)
.compact()
.map(tilePointToSquare)
.value();
}

View File

@@ -6,7 +6,11 @@ import {rangeInclusive, sqrt3} from './utils.js';
import Hex from './hex.js';
import Point from './point.js';
const tilePointToHex = ({tilePoint, pixelPoint}) => ({tilePoint: new Hex(tilePoint), pixelPoint});
const tilePointToHex = ({tilePoint, mapPoint, pixelPoint}) => ({
tilePoint: tilePoint instanceof Hex ? tilePoint : new Hex(tilePoint),
mapPoint: mapPoint instanceof Hex ? mapPoint : new Hex(mapPoint),
pixelPoint,
});
const zeroZeroZero = new Hex({x: 0, y: 0, z: 0});
@@ -31,7 +35,7 @@ export default class CartographerFlatXYZ extends Cartographer {
'calculateVerticalScale',
'tileToPixel',
'_pixelToTile',
'pixelToTile',
'teleport',
'inBounds',
@@ -118,13 +122,13 @@ export default class CartographerFlatXYZ extends Cartographer {
tileToPixel (hex) {
hex = hex instanceof Hex ? hex : new Hex(...arguments);
const pixelX = this.scale * 3/2 * hex.getQ();
const pixelY = this.scale * sqrt3 * (hex.getR() + (hex.getQ() / 2));
const pixelX = this.scale * 3/2 * hex.getQ() + this.originX;
const pixelY = this.scale * sqrt3 * (hex.getR() + (hex.getQ() / 2)) + this.originY;
return new Point(pixelX + this.originX, pixelY + this.originY);
return new Point(pixelX, pixelY);
}
_pixelToTile (point) {
pixelToTile (point) {
point = point instanceof Point ? point : new Point(...arguments);
const pixelX = point.getX() - this.originX;
@@ -137,6 +141,8 @@ export default class CartographerFlatXYZ extends Cartographer {
}
teleport (hex) {
if (!this.wrap) return hex;
hex = hex instanceof Hex ? hex : new Hex(hex);
if (this.radius) {
@@ -207,16 +213,16 @@ export default class CartographerFlatXYZ extends Cartographer {
}
enforceBoundries ({tilePoint, pixelPoint}) {
return this.wrap ? ({tilePoint: this.teleport(tilePoint), pixelPoint}) :
this.inBounds(tilePoint) ? ({tilePoint, pixelPoint}) :
null;
return this.wrap ? {tilePoint, mapPoint: this.teleport(tilePoint), pixelPoint} :
this.inBounds(tilePoint) ? {tilePoint, mapPoint: tilePoint, pixelPoint} :
{tilePoint, mapPoint: null, pixelPoint};
}
boundingBox (upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) {
const upperLeftTile = this._pixelToTile(upperLeftPoint);
const lowerLeftTile = this._pixelToTile(lowerLeftPoint);
const lowerRightTile = this._pixelToTile(lowerRightPoint);
const upperRightTile = this._pixelToTile(upperRightPoint);
const upperLeftTile = this.pixelToTile(upperLeftPoint);
const lowerLeftTile = this.pixelToTile(lowerLeftPoint);
const lowerRightTile = this.pixelToTile(lowerRightPoint);
const upperRightTile = this.pixelToTile(upperRightPoint);
const columns = rangeInclusive(upperLeftTile.getQ() - 1, upperRightTile.getQ() + 1);
@@ -235,7 +241,6 @@ export default class CartographerFlatXYZ extends Cartographer {
.map(makeAPoint)
.map(makeAPointPair)
.map(this.enforceBoundries)
.compact()
.map(tilePointToHex)
.value();
};

View File

@@ -6,7 +6,11 @@ import {rangeInclusive, invSqrt2, sqrt2} from './utils.js';
import Square from './square.js';
import Point from './point.js';
const tilePointToSquare = ({tilePoint, pixelPoint}) => ({tilePoint: new Square(tilePoint), pixelPoint});
const tilePointToSquare = ({tilePoint, mapPoint, pixelPoint}) => ({
tilePoint: tilePoint instanceof Square ? tilePoint : new Square(tilePoint),
mapPoint: mapPoint instanceof Square ? mapPoint : new Square(mapPoint),
pixelPoint,
});
export default class CartographerPointyXY extends Cartographer {
constructor(settings) {
@@ -29,7 +33,7 @@ export default class CartographerPointyXY extends Cartographer {
'calculateVerticalScale',
'tileToPixel',
'_pixelToTile',
'pixelToTile',
'teleport',
'inBounds',
@@ -85,13 +89,13 @@ export default class CartographerPointyXY extends Cartographer {
const y = square.getY();
// (above/below axis) * (distance from axis) / (size)
let pixelX = (x < y ? -1 : 1) * (Math.abs(y - x) / sqrt2) * this.minWidth();
let pixelY = (-x < y ? 1 : -1) * (Math.abs(x + y) / sqrt2) * this.minWidth();
const pixelX = (x < y ? -1 : 1) * (Math.abs(y - x) / sqrt2) * this.minWidth() + this.originX;
const pixelY = this.originY - (-x < y ? 1 : -1) * (Math.abs(x + y) / sqrt2) * this.minWidth();
return new Point(pixelX + this.originX, this.originY - pixelY);
return new Point(pixelX, pixelY);
}
_pixelToTile (point) {
pixelToTile (point) {
point = point instanceof Point ? point : new Point(...arguments);
const pixelX = point.getX() - this.originX;
@@ -105,6 +109,8 @@ export default class CartographerPointyXY extends Cartographer {
}
teleport ({x, y}) {
if (!this.wrap) return new Point(x, y);
x = x % this.width;
y = y % this.height;
@@ -126,16 +132,16 @@ export default class CartographerPointyXY extends Cartographer {
}
enforceBoundries ({tilePoint, pixelPoint}) {
return this.wrap ? ({tilePoint: this.teleport(tilePoint), pixelPoint}) :
this.inBounds(tilePoint) ? ({tilePoint, pixelPoint}) :
null;
return this.wrap ? {tilePoint, mapPoint: this.teleport(tilePoint), pixelPoint} :
this.inBounds(tilePoint) ? {tilePoint, mapPoint: tilePoint, pixelPoint} :
{tilePoint, mapPoint: null, pixelPoint};
}
boundingBox(upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) {
const upperLeftTile = this._pixelToTile(upperLeftPoint);
const lowerRightTile = this._pixelToTile(lowerRightPoint);
const upperRightTile = this._pixelToTile(upperRightPoint);
const lowerLeftTile = this._pixelToTile(lowerLeftPoint);
const upperLeftTile = this.pixelToTile(upperLeftPoint);
const lowerRightTile = this.pixelToTile(lowerRightPoint);
const upperRightTile = this.pixelToTile(upperRightPoint);
const lowerLeftTile = this.pixelToTile(lowerLeftPoint);
const columns = rangeInclusive(lowerLeftTile.getX(), upperRightTile.getX());
@@ -167,7 +173,6 @@ export default class CartographerPointyXY extends Cartographer {
.map(makeAPoint)
.map(makeAPointPair)
.map(this.enforceBoundries)
.compact()
.map(tilePointToSquare)
.value();
};

View File

@@ -6,7 +6,11 @@ import {rangeInclusive, sqrt3} from './utils.js';
import Hex from './hex.js';
import Point from './point.js';
const tilePointToHex = ({tilePoint, pixelPoint}) => ({tilePoint: new Hex(tilePoint), pixelPoint});
const tilePointToHex = ({tilePoint, mapPoint, pixelPoint}) => ({
tilePoint: tilePoint instanceof Hex ? tilePoint : new Hex(tilePoint),
mapPoint: mapPoint instanceof Hex ? mapPoint : new Hex(mapPoint),
pixelPoint,
});
const zeroZeroZero = new Hex({x: 0, y: 0, z: 0});
@@ -31,7 +35,7 @@ export default class CartographerPointyXYZ extends Cartographer {
'calculateVerticalScale',
'tileToPixel',
'_pixelToTile',
'pixelToTile',
'teleport',
'inBounds',
@@ -124,7 +128,7 @@ export default class CartographerPointyXYZ extends Cartographer {
return new Point(pixelX + this.originX, pixelY + this.originY);
}
_pixelToTile (point) {
pixelToTile (point) {
point = point instanceof Point ? point : new Point(...arguments);
const pixelX = point.getX() - this.originX;
@@ -137,6 +141,8 @@ export default class CartographerPointyXYZ extends Cartographer {
}
teleport (hex) {
if (!this.wrap) return hex;
hex = hex instanceof Hex ? hex : new Hex(hex);
if (this.radius) {
@@ -209,16 +215,16 @@ export default class CartographerPointyXYZ extends Cartographer {
}
enforceBoundries ({tilePoint, pixelPoint}) {
return this.wrap ? ({tilePoint: this.teleport(tilePoint), pixelPoint}) :
this.inBounds(tilePoint) ? ({tilePoint, pixelPoint}) :
null;
return this.wrap ? {tilePoint, mapPoint: this.teleport(tilePoint), pixelPoint} :
this.inBounds(tilePoint) ? {tilePoint, mapPoint: tilePoint, pixelPoint} :
{tilePoint, mapPoint: null, pixelPoint};
}
boundingBox (upperLeftPoint, upperRightPoint, lowerLeftPoint, lowerRightPoint) {
const upperLeftTile = this._pixelToTile(upperLeftPoint);
const lowerLeftTile = this._pixelToTile(lowerLeftPoint);
const lowerRightTile = this._pixelToTile(lowerRightPoint);
const upperRightTile = this._pixelToTile(upperRightPoint);
const upperLeftTile = this.pixelToTile(upperLeftPoint);
const lowerLeftTile = this.pixelToTile(lowerLeftPoint);
const lowerRightTile = this.pixelToTile(lowerRightPoint);
const upperRightTile = this.pixelToTile(upperRightPoint);
const rows = rangeInclusive(upperLeftTile.getR() -1 , lowerLeftTile.getR() + 1);
@@ -237,7 +243,6 @@ export default class CartographerPointyXYZ extends Cartographer {
.map(makeAPoint)
.map(makeAPointPair)
.map(this.enforceBoundries)
.compact()
.map(tilePointToHex)
.value();
};

View File

@@ -10,6 +10,8 @@ const DEFAULTS = {
tile: Tessellate.TILE_STYLES.HEX,
};
const keyTemplate = ({x, y, z}) => `${ x },${ z != null ? z : y }`;
const pressRipple = function() {
const sinStart = 2 * Math.PI;
const halfPi = Math.PI / 2;
@@ -125,16 +127,14 @@ class Demo {
}
tap(tap) {
const {x, y, z} = tap.tile.getPoint();
const key = `${ x },${ z != null ? z : y }`;
const key = keyTemplate(tap.mapTile);
const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9;
if (this.map[key]) {
this.map[key].pips = Tessellate.utils.random(1, pipMax);
console.log(`{${ x }, ${ y }${ z != null ? `, ${ z }` : ''}}`);
console.log(tap.mapTile.getPoint());
}
else {
console.log('ERROR - no tile', key);
@@ -165,19 +165,18 @@ class Demo {
});
if (tap.event.mobile) {
this.togglemine(tap.tile)
this.togglemine(tap.mapTile)
}
}
press(tap) {
if (!tap.event.mobile) {
this.togglemine(tap.tile)
this.togglemine(tap.mapTile)
}
}
togglemine(tile) {
const {x, y, z} = tile.getPoint();
const key = `${ x },${ z != null ? z : y }`;
const key = keyTemplate(tile);
if (this.mines[key]) {
delete this.mines[key];
@@ -227,16 +226,16 @@ class Demo {
}
drawTile(pointGroup, context, scale) {
const {x, y, z} = pointGroup.tilePoint;
const pixelX = pointGroup.pixelPoint.getX();
const pixelY = pointGroup.pixelPoint.getY();
this.counts[0] += 1;
const key = `${ x },${ z != null ? z : y }`;
const key = keyTemplate(pointGroup.mapPoint);
this.map[key] = this.map[key] || this.createTile({
x, y,
x: pointGroup.mapPoint.x,
y: pointGroup.mapPoint.y,
drawStyle: this.settings.style,
tileStyle: this.settings.tile,
orientation: this.settings.orientation,
@@ -249,7 +248,7 @@ class Demo {
Tessellate.TILES[tile.tileStyle][tile.drawStyle](context, scale, pixelX, pixelY, tile);
if (this.mined) {
if (this.mined || this.mines[key]) {
this.counts[2] += 1;
Tessellate.Shapes.mine(context, scale, pixelX, pixelY);
}
@@ -284,7 +283,9 @@ class Demo {
blue: 128,
});
pointGroups.forEach(pointGroup => this.drawTile(pointGroup, context, scale));
pointGroups
.filter(pointGroup => pointGroup.mapPoint)
.forEach(pointGroup => this.drawTile(pointGroup, context, scale));
this.ripples.forEach(({timestamp, cell}) => {
const pressFactor = Math.min((now - timestamp) / PRESS_RIPPLE, 1);
@@ -292,21 +293,21 @@ class Demo {
Object.assign(cell, {scale: pressRipple(pressFactor)});
Object.assign(cell.color, {alpha: pressFade(pressFactor)});
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
const pixelPoint = this.tessellate.tileToPixel(cell);
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
});
this.ripples = this.ripples.filter(ripple => (ripple.timestamp + PRESS_RIPPLE) > now);
this.taps.forEach(cell => {
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
const pixelPoint = this.tessellate.tileToPixel(cell);
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
});
Tessellate.funky.forEach(this.mines, cell => {
this.counts[2] += 1;
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.Shapes.mine(context, scale, pixelPoint.getX(), pixelPoint.getY());
});
// Tessellate.funky.forEach(this.mines, cell => {
// this.counts[2] += 1;
// const pixelPoint = this.tessellate.tileToPixel(cell);
// Tessellate.Shapes.mine(context, scale, pixelPoint.getX(), pixelPoint.getY());
// });
this.fps.frame(now, lastNow, this.counts);
}

View File

@@ -148,26 +148,28 @@ export class Tessellate {
}
tap (event) {
let point = new Point(event.offsetX, event.offsetY);
const point = new Point(event.offsetX, event.offsetY);
const tile = this.cartographer.pixelToTile(point);
const mapTile = this.cartographer.teleport(tile);
let tile = this.cartographer.pixelToTile(point);
let tap = {
this.settings.tap({
event,
mapTile,
point,
tile
};
this.settings.tap(tap);
tile,
});
}
doubletap (event) {
console.log('DOUBLETAP', event);
let point = new Point(event.offsetX, event.offsetY);
let tile = this.cartographer.pixelToTile(point);
const point = new Point(event.offsetX, event.offsetY);
const tile = this.cartographer.pixelToTile(point);
const mapTile = this.cartographer.teleport(tile);
let tap = {
event,
map,
mapTile,
point,
tile
};
@@ -176,29 +178,44 @@ export class Tessellate {
}
pressStart (event) {
let point = new Point(event.offsetX, event.offsetY);
let tile = this.cartographer.pixelToTile(point);
const point = new Point(event.offsetX, event.offsetY);
const tile = this.cartographer.pixelToTile(point);
const mapTile = this.cartographer.teleport(tile);
let tap = {
event,
mapTile,
point,
tile
};
this.settings.pressStart(tap);
console.log(tap);
}
pressStart (event) {
const point = new Point(event.offsetX, event.offsetY);
const tile = this.cartographer.pixelToTile(point);
const mapTile = this.cartographer.teleport(tile);
this.settings.pressStart({
event,
mapTile,
point,
tile,
});
}
press (event) {
let point = new Point(event.offsetX, event.offsetY);
let tile = this.cartographer.pixelToTile(point);
const point = new Point(event.offsetX, event.offsetY);
const tile = this.cartographer.pixelToTile(point);
const mapTile = this.cartographer.teleport(tile);
let tap = {
this.settings.press({
event,
mapTile,
point,
tile
};
this.settings.press(tap);
tile,
});
}
move (event) {
@@ -213,8 +230,8 @@ export class Tessellate {
return this.cartographer.pixelToTile(x, y);
}
tileToPixel (x, y, z) {
return this.cartographer.tileToPixel(x, y, z);
tileToPixel (tilePoint) {
return this.cartographer.tileToPixel(tilePoint);
}
getTilePoints ({upperLeftX, upperLeftY, lowerRightX, lowerRightY}) {