Mine Upgrade (#15)

This commit is contained in:
gavin
2018-08-24 02:42:33 +00:00
committed by Gitea
parent 90cf1723a8
commit a2d7402cfa
5 changed files with 171 additions and 108 deletions

View File

@@ -1,4 +1,4 @@
import {random} from './utils.js'; import {getColor, random} from './utils.js';
import { import {
HEX, CIRCLE, SQUARE, HEX, CIRCLE, SQUARE,
FLAT, POINTY, FLAT, POINTY,
@@ -15,10 +15,12 @@ const DEFAULTS = {
drawStyle: FILL, drawStyle: FILL,
width: 1, width: 1,
color: {
red: 0, red: 0,
green: 0, green: 0,
blue: 0, blue: 0,
alpha: 0.5, alpha: 0.5,
},
}; };
export default class Cell { export default class Cell {
@@ -29,7 +31,7 @@ export default class Cell {
} }
getColor() { getColor() {
return `rgba(${this.red},${this.green},${this.blue},${this.alpha})`; return getColor(this.color);
} }
} }

View File

@@ -1,10 +1,47 @@
import {range, sqrt2, toFixed} from './utils.js'; import {getColor, range, sqrt2, toFixed} from './utils.js';
import {HEX, SQUARE, FLAT, POINTY} from './consts.js'; import {HEX, SQUARE, FLAT, POINTY} from './consts.js';
const DEFAULTS = { const DEFAULTS = {
flagScale: 0.5, mine: {
pipScale: 0.15, border: {
pipDistance: 0.4, scale: 0.38,
color: {
red: 255,
blue: 255,
green: 255,
},
horns: {
scale: 0.07,
distance: 0.36,
},
},
body: {
scale: 0.36,
color: {
red: 192,
blue: 32,
green: 32,
},
horns: {
scale: 0.05,
distance: 0.36,
},
}
},
pip: {
scale: 0.15,
distance: 0.4,
color: {
red: 0,
blue: 0,
green: 0,
},
},
sides: 6, sides: 6,
slices: 24, slices: 24,
@@ -105,6 +142,8 @@ export default class DrawShapes {
[POINTY]: generatePointySquarePips(), [POINTY]: generatePointySquarePips(),
} }
}; };
this.horns = this.pipVertices[HEX][FLAT][6].concat(this.pipVertices[HEX][POINTY][6]);
} }
pip (context, scale, cellX, cellY, vertexX, vertexY, pipRadius, pipDistance) { pip (context, scale, cellX, cellY, vertexX, vertexY, pipRadius, pipDistance) {
@@ -115,14 +154,14 @@ export default class DrawShapes {
context.arc(x, y, pipRadius, 0, Math.PI*2, true); context.arc(x, y, pipRadius, 0, Math.PI*2, true);
} }
pips(context, scale, x, y, cell) { pips (context, scale, x, y, cell, pip = this.settings.pip) {
const {tileStyle, orientation, pips} = cell; const {tileStyle, orientation, pips} = cell;
if (this.pipVertices[tileStyle] if (this.pipVertices[tileStyle]
&& this.pipVertices[tileStyle][orientation] && this.pipVertices[tileStyle][orientation]
&& this.pipVertices[tileStyle][orientation][pips]) { && this.pipVertices[tileStyle][orientation][pips]) {
const pipRadius = scale * this.settings.pipScale; const pipRadius = scale * pip.scale;
const pipDistance = scale * this.settings.pipDistance; const pipDistance = scale * pip.distance;
context.beginPath(); context.beginPath();
@@ -130,23 +169,44 @@ export default class DrawShapes {
.forEach(([pipX, pipY]) => this.pip(context, scale, x,y, pipX, pipY, pipRadius, pipDistance)); .forEach(([pipX, pipY]) => this.pip(context, scale, x,y, pipX, pipY, pipRadius, pipDistance));
context.closePath(); context.closePath();
context.fillStyle = 'rgb(0,0,0)'; context.fillStyle = getColor(pip.color);
context.fill(); context.fill();
} }
} }
flag (context, scale, x, y) { mine (context, scale, x, y, mine = this.settings.mine) {
context.beginPath(); this._mine(context, scale, x, y, mine.border);
this._horns(context, scale, x, y, mine.border.horns, mine.border.color);
this._mine(context, scale, x, y, mine.body);
this._horns(context, scale, x, y, mine.body.horns, mine.body.color);
}
_mine (context, scale, x, y, mine) {
context.beginPath();
context.moveTo(x, y); context.moveTo(x, y);
context.arc(x, y, scale * this.settings.flagScale, 0, Math.PI*2, true);
context.arc(x, y, scale * mine.scale, 0, Math.PI*2, true);
context.closePath(); context.closePath();
context.fillStyle = 'rgb(255,0,0)'; context.fillStyle = getColor(mine.color);
context.fill(); context.fill();
} }
mine(context, scale, x, y) { _horns (context, scale, x, y, horn, color) {
const hornRadius = scale * horn.scale;
const hornDistance = scale * horn.distance;
context.beginPath();
this.horns
.forEach(([hornX, hornY]) => this.pip(context, scale, x,y, hornX, hornY, hornRadius, hornDistance));
context.closePath();
context.fillStyle = getColor(color);
context.fill();
}
explosion (context, scale, x, y) {
var peak = scale * 0.667; var peak = scale * 0.667;
var valley = scale * 0.333; var valley = scale * 0.333;

View File

@@ -39,7 +39,7 @@ class Demo {
this.map = {}; this.map = {};
this.taps = []; this.taps = [];
this.flags = {}; this.mines = {};
this.ripples = []; this.ripples = [];
this.setOriginTile(); this.setOriginTile();
@@ -60,10 +60,13 @@ class Demo {
drawStyle: Tessellate.DRAW_STYLES.FILL, drawStyle: Tessellate.DRAW_STYLES.FILL,
tileStyle: this.settings.tile, tileStyle: this.settings.tile,
orientation: this.settings.orientation, orientation: this.settings.orientation,
color: {
red: 255, red: 255,
green: 255, green: 255,
blue: 0, blue: 0,
alpha: 1, alpha: 1,
}
}); });
Tessellate.utils.rangeInclusive(0, 5) Tessellate.utils.rangeInclusive(0, 5)
@@ -76,28 +79,29 @@ class Demo {
drawStyle: Tessellate.DRAW_STYLES.OUTLINE, drawStyle: Tessellate.DRAW_STYLES.OUTLINE,
tileStyle: this.settings.tile, tileStyle: this.settings.tile,
orientation: this.settings.orientation, orientation: this.settings.orientation,
color: {
red: 0, red: 0,
green: 0, green: 0,
blue: 0, blue: 0,
alpha: 1, alpha: 1,
},
})); }));
}); });
} }
tap(tap) { tap(tap) {
const {x, y, z} = tap.tile.getPoint(); const {x, y, z} = tap.tile.getPoint();
console.log(x, y, z);
const key = `${ x },${ z != null ? z : y }`; const key = `${ x },${ z != null ? z : y }`;
const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9; const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9;
this.map[key].pips = Tessellate.utils.random(1, pipMax); this.map[key].pips = Tessellate.utils.random(1, pipMax);
console.log(this.map[key].pips);
} }
pressStart(tap) { pressStart(tap) {
this.ripples.push({ this.ripples.push({
timestamp: tap.event.timeStamp, timestamp: tap.event.timeStampUTC,
cell: this.createTile({ cell: this.createTile({
x: tap.tile.x, x: tap.tile.x,
@@ -109,43 +113,47 @@ class Demo {
tileStyle: Tessellate.TILE_STYLES.CIRCLE, tileStyle: Tessellate.TILE_STYLES.CIRCLE,
orientation: Tessellate.ORIENTATION_STYLES.FLAT, orientation: Tessellate.ORIENTATION_STYLES.FLAT,
red: 255, color: {
green: 127, red: 128,
blue: 127, green: 128,
blue: 128,
alpha: 0.5, alpha: 0.5,
},
}) })
}); });
if (tap.event.mobile) { if (tap.event.mobile) {
this.toggleFlag(tap.tile) this.togglemine(tap.tile)
} }
} }
press(tap) { press(tap) {
if (!tap.event.mobile) { if (!tap.event.mobile) {
this.toggleFlag(tap.tile) this.togglemine(tap.tile)
} }
} }
toggleFlag(tile) { togglemine(tile) {
const {x, y, z} = tile.getPoint(); const {x, y, z} = tile.getPoint();
const key = `${ x },${ z != null ? z : y }`; const key = `${ x },${ z != null ? z : y }`;
if (this.flags[key]) { if (this.mines[key]) {
delete this.flags[key]; delete this.mines[key];
} }
else { else {
this.flags[key] = tile; this.mines[key] = tile;
} }
} }
createTile({x, y, createTile({x, y,
drawStyle, tileStyle, orientation, drawStyle, tileStyle, orientation,
scale = Tessellate.utils.random(7, 9) / 10, scale = Tessellate.utils.random(7, 9) / 10,
red = Tessellate.utils.random(255), color = {
green = Tessellate.utils.random(255), red: Tessellate.utils.random(255),
blue = Tessellate.utils.random(255), green: Tessellate.utils.random(255),
alpha = Tessellate.utils.random(25, 75) / 100, blue: Tessellate.utils.random(255),
alpha: Tessellate.utils.random(25, 75) / 100,
}
}) { }) {
return new Tessellate.Cell({ return new Tessellate.Cell({
@@ -157,10 +165,7 @@ class Demo {
tileStyle, tileStyle,
orientation, orientation,
red, color,
green,
blue,
alpha,
}); });
} }
@@ -186,13 +191,10 @@ class Demo {
const now = Date.now(); const now = Date.now();
this.ripples.forEach(({timestamp, cell}) => { this.ripples.forEach(({timestamp, cell}) => {
let pressFactor = (now - timestamp) / PRESS_RIPPLE; const pressFactor = Math.min((now - timestamp) / PRESS_RIPPLE, 1);
pressFactor = pressFactor > 1 ? 1 : pressFactor;
Object.assign(cell, { Object.assign(cell, {scale: pressRipple(pressFactor)});
scale: pressRipple(pressFactor), Object.assign(cell.color, {alpha: pressFade(pressFactor)});
alpha: pressFade(pressFactor),
});
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y); const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell); Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
@@ -204,15 +206,15 @@ class Demo {
Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell); Tessellate.TILES[cell.tileStyle][cell.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), cell);
}); });
Tessellate.funky.forEach(this.flags, cell => { Tessellate.funky.forEach(this.mines, cell => {
const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y); const pixelPoint = this.tessellate.tileToPixel(cell.x, cell.y);
Tessellate.Shapes.flag(context, scale, pixelPoint.getX(), pixelPoint.getY()); Tessellate.Shapes.mine(context, scale, pixelPoint.getX(), pixelPoint.getY());
}); });
if (!this.notFirstTime) { // if (!this.notFirstTime) {
this.notFirstTime = true; // this.notFirstTime = true;
console.log(tilePoints); // console.log(tilePoints);
} // }
} }
} }

View File

@@ -1,6 +1,7 @@
import {noop} from './utils.js'; import {noop} from './utils.js';
const MODULE = 'onTap';
const DEFAULTS = { const DEFAULTS = {
debug: false, debug: false,
@@ -23,19 +24,7 @@ const DEFAULTS = {
wheelFactor: -100, wheelFactor: -100,
}; };
export default class OnTap { const events = [
constructor(settings) {
this.settings = Object.assign({}, DEFAULTS, settings);
this.state = {
tapStartTime: null,
};
[
// TODO: don't set up listeners for these two
'tapStart',
'pressStart',
'contextmenu', 'contextmenu',
'mousedown', 'mousedown',
@@ -48,10 +37,33 @@ export default class OnTap {
'touchcancel', 'touchcancel',
'wheel', 'wheel',
].forEach(method => { ];
this[method] = this[method].bind(this);
this.settings.element.addEventListener(method, this[method]); const methods = [
}); 'eventHandler',
'tapStart',
'pressStart',
].concat(events);
export default class OnTap {
constructor(settings) {
this.settings = Object.assign({}, DEFAULTS, settings);
this.state = {
tapStartTime: null,
};
methods.forEach(method => this[method] = this[method].bind(this));
events.forEach(eventName => this.settings.element.addEventListener(eventName, event => this.eventHandler(event, eventName)));
}
eventHandler (event, eventName) {
event.timeStampUTC = Date.now();
if (this.settings.debug) console.debug(`[${ MODULE }][${ eventName }]`, event);
this[eventName](event);
} }
contextmenu(event) { contextmenu(event) {
@@ -59,11 +71,9 @@ export default class OnTap {
} }
tapStart(event) { tapStart(event) {
if (this.settings.debug) console.debug('onTap.tapStart', event);
if (!this.state.tapStartTime) { if (!this.state.tapStartTime) {
const {mobile} = event; const {mobile} = event;
this.state.tapStartTime = event.timeStamp; this.state.tapStartTime = event.timeStampUTC;
if (mobile || this.settings.desktopPress) { if (mobile || this.settings.desktopPress) {
clearTimeout(this.state.pressTO); clearTimeout(this.state.pressTO);
@@ -71,7 +81,7 @@ export default class OnTap {
this.state.pressTO = setTimeout(() => { this.state.pressTO = setTimeout(() => {
this.pressStart({ this.pressStart({
mobile, mobile,
timeStamp: Date.now(), timeStampUTC: Date.now(),
offsetX: this.state.lastX, offsetX: this.state.lastX,
offsetY: this.state.lastY, offsetY: this.state.lastY,
}); });
@@ -83,8 +93,6 @@ export default class OnTap {
} }
mousedown(event) { mousedown(event) {
if (this.settings.debug) console.debug('onTap.mousedown', event);
Object.assign(event, { Object.assign(event, {
mobile: false, mobile: false,
}); });
@@ -103,8 +111,6 @@ export default class OnTap {
touchstart(event) { touchstart(event) {
event.preventDefault(); event.preventDefault();
if (this.settings.debug) console.debug('onTap.touchstart', event);
Object.assign(event, { Object.assign(event, {
mobile: true, mobile: true,
}); });
@@ -125,17 +131,13 @@ export default class OnTap {
} }
pressStart(event) { pressStart(event) {
if (this.settings.debug) console.debug('onTap.pressStart', event);
this.settings.pressStart(event); this.settings.pressStart(event);
} }
mouseup(event) { mouseup(event) {
if (this.settings.debug) console.debug('onTap.mouseup', event);
Object.assign(event, { Object.assign(event, {
mobile: false, mobile: false,
duration: event.timeStamp - this.state.tapStartTime, duration: event.timeStampUTC - this.state.tapStartTime,
}); });
if (!this.state.moving) { if (!this.state.moving) {
@@ -161,11 +163,9 @@ export default class OnTap {
touchend(event) { touchend(event) {
event.preventDefault(); event.preventDefault();
if (this.settings.debug) console.debug('onTap.touchend', event);
Object.assign(event, { Object.assign(event, {
mobile: true, mobile: true,
duration: event.timeStamp - this.state.tapStartTime, duration: event.timeStampUTC - this.state.tapStartTime,
}); });
const touches = [...event.touches]; const touches = [...event.touches];
@@ -206,8 +206,6 @@ export default class OnTap {
} }
mousemove(event) { mousemove(event) {
if (this.settings.debug) console.debug('onTap.mousemove', event);
if (this.state.tapStartTime) { if (this.state.tapStartTime) {
if (!this.state.moving) { if (!this.state.moving) {
if ((Math.abs(event.offsetX - this.state.lastX) > this.settings.moveThreshold) if ((Math.abs(event.offsetX - this.state.lastX) > this.settings.moveThreshold)
@@ -235,8 +233,6 @@ export default class OnTap {
touchmove(event) { touchmove(event) {
event.preventDefault(); event.preventDefault();
if (this.settings.debug) console.debug('onTap.touchmove', event);
if (this.state.tapStartTime) { if (this.state.tapStartTime) {
const touches = [...event.touches]; const touches = [...event.touches];
@@ -281,8 +277,6 @@ export default class OnTap {
} }
wheel(event) { wheel(event) {
if (this.settings.debug) console.debug('onTap.wheel', event);
Object.assign(event, { Object.assign(event, {
scaleStep: 1 + (event.deltaY / this.settings.wheelFactor), scaleStep: 1 + (event.deltaY / this.settings.wheelFactor),
mobile: false, mobile: false,

View File

@@ -121,3 +121,8 @@ export function toFixed(number, precision = 3, fallback = NaN) {
return typeof number === 'number' && !isNaN(number) ? Number(number.toFixed(precision)) : fallback; return typeof number === 'number' && !isNaN(number) ? Number(number.toFixed(precision)) : fallback;
} }
export function getColor ({red, green, blue, alpha}) {
return alpha != null ? `rgba(${ red }, ${ green }, ${ blue }, ${ alpha })` :
`rgb(${ red }, ${ green }, ${ blue })`;
}