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 {
HEX, CIRCLE, SQUARE,
FLAT, POINTY,
@@ -15,10 +15,12 @@ const DEFAULTS = {
drawStyle: FILL,
width: 1,
color: {
red: 0,
green: 0,
blue: 0,
alpha: 0.5,
},
};
export default class Cell {
@@ -29,7 +31,7 @@ export default class Cell {
}
getColor() {
return `rgba(${this.red},${this.green},${this.blue},${this.alpha})`;
return getColor(this.color);
}
}

View File

@@ -1,16 +1,53 @@
import {range, sqrt2, toFixed} from './utils.js';
import {getColor, range, sqrt2, toFixed} from './utils.js';
import {HEX, SQUARE, FLAT, POINTY} from './consts.js';
const DEFAULTS = {
flagScale: 0.5,
pipScale: 0.15,
pipDistance: 0.4,
mine: {
border: {
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,
slices: 24,
};
function generateFlatSquarePips() {
function generateFlatSquarePips () {
const pips = [];
const pipX = [0, 1, 1, -1, -1, 1, -1, 0, 0];
const pipY = [0, 1, -1, -1, 1, 0, 0, -1, 1];
@@ -30,7 +67,7 @@ function generateFlatSquarePips() {
return pips;
}
function generatePointySquarePips() {
function generatePointySquarePips () {
const pips = [];
const pipX = [0, sqrt2, 0, -sqrt2, 0, sqrt2 / 2, -sqrt2 / 2, sqrt2 / 2, -sqrt2 / 2];
const pipY = [0, 0, -sqrt2, 0, sqrt2, -sqrt2 / 2, sqrt2 / 2, sqrt2 / 2, -sqrt2 / 2];
@@ -50,7 +87,7 @@ function generatePointySquarePips() {
return pips;
}
function generateFlatHexPips(slicesX, slicesY) {
function generateFlatHexPips (slicesX, slicesY) {
const pips = []
slicesX = [0].concat(slicesX);
slicesY = [0].concat(slicesY);
@@ -68,7 +105,7 @@ function generateFlatHexPips(slicesX, slicesY) {
return pips;
}
function generatePointyHexPips(slicesX, slicesY) {
function generatePointyHexPips (slicesX, slicesY) {
const pips = []
slicesX = [0].concat(slicesX);
slicesY = [0].concat(slicesY);
@@ -87,7 +124,7 @@ function generatePointyHexPips(slicesX, slicesY) {
}
export default class DrawShapes {
constructor(settings) {
constructor (settings) {
this.settings = Object.assign({}, DEFAULTS, settings);
const sides = this.settings.sides;
@@ -105,9 +142,11 @@ export default class DrawShapes {
[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) {
const x = cellX + (pipDistance * vertexX);
const y = cellY + (pipDistance * vertexY);
@@ -115,14 +154,14 @@ export default class DrawShapes {
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;
if (this.pipVertices[tileStyle]
&& this.pipVertices[tileStyle][orientation]
&& this.pipVertices[tileStyle][orientation][pips]) {
const pipRadius = scale * this.settings.pipScale;
const pipDistance = scale * this.settings.pipDistance;
const pipRadius = scale * pip.scale;
const pipDistance = scale * pip.distance;
context.beginPath();
@@ -130,23 +169,44 @@ export default class DrawShapes {
.forEach(([pipX, pipY]) => this.pip(context, scale, x,y, pipX, pipY, pipRadius, pipDistance));
context.closePath();
context.fillStyle = 'rgb(0,0,0)';
context.fillStyle = getColor(pip.color);
context.fill();
}
}
flag (context, scale, x, y) {
context.beginPath();
mine (context, scale, x, y, mine = this.settings.mine) {
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.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.fillStyle = 'rgb(255,0,0)';
context.fillStyle = getColor(mine.color);
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 valley = scale * 0.333;

View File

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

View File

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