Higher FPS! (#19)

This commit is contained in:
gavin
2018-10-05 20:22:11 -04:00
committed by Gitea
parent 0e2b7ea69d
commit 52017e8e30
7 changed files with 160 additions and 49 deletions

View File

@@ -1,6 +1,6 @@
import Cartographer from './cartographer.js';
import {rangeInclusive, sqrt2} from './utils.js';
import {rangeInclusive, invSqrt2} from './utils.js';
import Square from './square.js';
import Point from './point.js';
@@ -40,11 +40,11 @@ export default class CartographerFlatXY extends Cartographer {
}
maxWidth() {
return this.minWidth() * sqrt2;
return this.scale * 2;
}
minWidth() {
return this.scale * 2;
return this.maxWidth() * invSqrt2;
}
horizontalOverhang() {

View File

@@ -1,6 +1,6 @@
import Cartographer from './cartographer.js';
import {rangeInclusive, sqrt2} from './utils.js';
import {rangeInclusive, invSqrt2, sqrt2} from './utils.js';
import Square from './square.js';
import Point from './point.js';
@@ -40,11 +40,11 @@ export default class CartographerPointyXY extends Cartographer {
}
maxWidth() {
return this.minWidth() * sqrt2;
return this.scale * 2;
}
minWidth() {
return this.scale * 2;
return this.maxWidth() * invSqrt2;
}
horizontalOverhang() {

View File

@@ -1,5 +1,5 @@
import {FLAT, POINTY} from './consts.js';
import {getColor, range, toFixed} from './utils.js';
import {getColor, range, toFixed, quickCanvas} from './utils.js';
export default class DrawHexagon {
constructor(settings) {
@@ -50,6 +50,34 @@ export default class DrawHexagon {
context.stroke();
}
// fill(context, scale, x, y, cell) {
// if (cell.cacheScale !== scale) {
// cell.cacheScale = scale;
// scale = scale * cell.scale;
//
// cell.cacheHalfWidth = scale;
// cell.cacheHalfHeight = scale;
//
// cell.cacheHex = quickCanvas((context, height, width) => {
// const hexCornerX = cell.orientation === POINTY ? this.pointyTopCornerX : this.flatTopCornerX;
// const hexCornerY = cell.orientation === POINTY ? this.pointyTopCornerY : this.flatTopCornerY;
//
// context.beginPath();
// context.moveTo(scale + scale * hexCornerX[0], scale + scale * hexCornerY[0]);
// context.lineTo(scale + scale * hexCornerX[1], scale + scale * hexCornerY[1]);
// context.lineTo(scale + scale * hexCornerX[2], scale + scale * hexCornerY[2]);
// context.lineTo(scale + scale * hexCornerX[3], scale + scale * hexCornerY[3]);
// context.lineTo(scale + scale * hexCornerX[4], scale + scale * hexCornerY[4]);
// context.lineTo(scale + scale * hexCornerX[5], scale + scale * hexCornerY[5]);
//
// context.fillStyle = getColor(cell.color);
// context.fill();
// }, scale * 2);
// }
//
// context.drawImage(cell.cacheHex, x - cell.cacheHalfWidth, y - cell.cacheHalfHeight);
// }
fill(context, scale, x, y, cell) {
scale = scale * cell.scale;
let hexCornerX = cell.orientation === POINTY ? this.pointyTopCornerX : this.flatTopCornerX;

View File

@@ -1,4 +1,4 @@
import {getColor, range, sqrt2, toFixed} from './utils.js';
import {getColor, quickCanvas, range, invSqrt2, toFixed} from './utils.js';
import {HEX, SQUARE, FLAT, POINTY} from './consts.js';
const DEFAULTS = {
@@ -52,7 +52,7 @@ const DEFAULTS = {
green: 0,
},
},
distance: 0.4,
distance: 0.6,
},
sides: 6,
@@ -61,8 +61,8 @@ const DEFAULTS = {
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];
const pipX = [0, invSqrt2, invSqrt2, -invSqrt2, -invSqrt2, invSqrt2, -invSqrt2, 0, 0];
const pipY = [0, invSqrt2, -invSqrt2, -invSqrt2, invSqrt2, 0, 0, -invSqrt2, invSqrt2];
const getVertex = n => [pipX[n], pipY[n]];
@@ -81,8 +81,8 @@ function generateFlatSquarePips () {
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];
const pipX = [0, 1, 0, -1, 0, 0.5, -0.5, 0.5, -0.5];
const pipY = [0, 0, -1, 0, 1, -0.5, 0.5, 0.5, -0.5];
const getVertex = n => [pipX[n], pipY[n]];
@@ -144,6 +144,9 @@ export default class DrawShapes {
this.slicesX = range(slices).map(slice => toFixed(Math.cos(((slice / slices) * sides) * (2 * Math.PI) / sides)));
this.slicesY = range(slices).map(slice => toFixed(Math.sin(((slice / slices) * sides) * (2 * Math.PI) / sides)));
this.pipCache = {};
this.mineCache = {};
this.pipVertices = {
[HEX]: {
[FLAT]: generateFlatHexPips(this.slicesX, this.slicesY),
@@ -174,41 +177,75 @@ export default class DrawShapes {
context.arc(x, y, pipRadius, 0, Math.PI*2, true);
}
pips (context, scale, x, y, cell, pip = this.settings.pip) {
setPipCache (pips, scale) {
const pipDistance = scale * this.settings.pip.distance; //* cell.scale;
const pipBodyRadius = scale * this.settings.pip.body.scale;
const pipBorderRadius = scale * this.settings.pip.border.scale;
this.pipCache.scale = scale;
this.pipCache.height = (Math.ceil(pipBorderRadius) + 1) * 2;
this.pipCache.width = this.pipCache.height;
const pipCenter = this.pipCache.height / 2;
this.pipCache.pip = quickCanvas((context, height, width) => {
context.beginPath();
context.arc(pipCenter, pipCenter, pipBorderRadius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = getColor(this.settings.pip.border.color);
context.fill();
context.beginPath();
context.arc(pipCenter, pipCenter, pipBodyRadius, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = getColor(this.settings.pip.body.color);
context.fill();
}, this.pipCache.height, this.pipCache.width);
const pipsCenter = scale - pipCenter;
this.pipCache.pips = pips.map(vertices => {
return quickCanvas(context => {
vertices.forEach(([pipX, pipY]) => context.drawImage(this.pipCache.pip, pipsCenter + (pipDistance * pipX), pipsCenter + (pipDistance * pipY)));
}, scale * 2);
});
}
pips (context, scale, x, y, cell) {
const {tileStyle, orientation, pips} = cell;
if (this.pipVertices[tileStyle]
&& this.pipVertices[tileStyle][orientation]
&& this.pipVertices[tileStyle][orientation][pips]) {
const pipBodyRadius = scale * pip.body.scale;
const pipBorderRadius = scale * pip.border.scale;
const pipDistance = scale * pip.distance;
context.beginPath();
if (scale !== this.pipCache.scale) {
this.setPipCache(this.pipVertices[tileStyle][orientation], scale);
}
this.pipVertices[tileStyle][orientation][pips]
.forEach(([pipX, pipY]) => this.pip(context, scale, x,y, pipX, pipY, pipBorderRadius, pipDistance));
const scaleWidth = (scale * 2) * cell.scale;
const scaleHeight = (scale * 2) * cell.scale;
context.closePath();
context.fillStyle = getColor(pip.border.color);
context.fill();
context.beginPath();
this.pipVertices[tileStyle][orientation][pips]
.forEach(([pipX, pipY]) => this.pip(context, scale, x,y, pipX, pipY, pipBodyRadius, pipDistance));
context.closePath();
context.fillStyle = getColor(pip.body.color);
context.fill();
context.drawImage(this.pipCache.pips[pips], x - (scaleWidth / 2), y - (scaleHeight / 2), scaleWidth, scaleHeight);
}
}
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);
if (scale !== this.mineCache.scale) {
this.setMineCache(scale);
}
context.drawImage(this.mineCache.mine, x - scale, y - scale, scale * 2, scale * 2);
}
setMineCache (scale) {
this.mineCache.scale = scale;
this.mineCache.mine = quickCanvas(context => {
this._mine(context, scale, scale, scale, this.settings.mine.border);
this._horns(context, scale, scale, scale, this.settings.mine.border.horns, this.settings.mine.border.color);
this._mine(context, scale, scale, scale, this.settings.mine.body);
this._horns(context, scale, scale, scale, this.settings.mine.body.horns, this.settings.mine.body.color);
}, scale * 2);
}
_mine (context, scale, x, y, mine) {

View File

@@ -1,14 +1,14 @@
import {getColor, sqrt2} from './utils.js';
import {getColor, invSqrt2, sqrt2} from './utils.js';
import {FLAT, POINTY} from './consts.js';
export default class DrawSquare {
constructor(settings) {
this.settings = Object.assign({}, settings);
this.squareX = [1, 1, -1, -1];
this.squareY = [1, -1, -1, 1];
this.diamondX = [sqrt2, 0, -sqrt2, 0, sqrt2 / 2, -sqrt2 / 2];
this.diamondY = [0, -sqrt2, 0, sqrt2, -sqrt2 / 2, sqrt2 / 2];
this.squareX = [invSqrt2, invSqrt2, -invSqrt2, -invSqrt2];
this.squareY = [invSqrt2, -invSqrt2, -invSqrt2, invSqrt2];
this.diamondX = [1, 0, -1, 0, 0.5, -0.5];
this.diamondY = [0, -1, 0, 1, -0.5, 0.5];
}
fill(context, scale, x, y, cell) {

View File

@@ -27,7 +27,7 @@ class Demo {
constructor() {
[
'setOriginTile',
'setFadeToGray',
'setupKeydown',
'tap',
'pressStart',
'press',
@@ -50,7 +50,7 @@ class Demo {
});
this.setOriginTile();
this.setFadeToGray();
this.setupKeydown();
this.tessellate = new Tessellate(Object.assign({
element: '#container',
@@ -99,10 +99,27 @@ class Demo {
});
}
setFadeToGray () {
setupKeydown () {
this.pipDefault = null;
window.addEventListener('keydown', event => {
if (!event.repeat && event.key === 'Enter') {
this.gray = this.gray ? null : Date.now();
if (!event.repeat) {
if (event.key === 'Enter') {
this.gray = this.gray ? null : Date.now();
}
if (event.key === `~`) {
this.mined = true;
}
if (event.key === '`') {
this.pipDefault = '*';
}
const num = parseInt(event.key);
if (num >= 0 && num <= 9) {
this.pipDefault = num;
}
}
});
}
@@ -221,9 +238,25 @@ class Demo {
Tessellate.TILES[tile.tileStyle][tile.drawStyle](context, scale, pixelPoint.getX(), pixelPoint.getY(), tile);
if (tile.pips) {
this.counts[1] += tile.pips;
Tessellate.Shapes.pips(context, scale, pixelPoint.getX(), pixelPoint.getY(), tile);
if (this.mined) {
this.counts[2] += 1;
Tessellate.Shapes.mine(context, scale, pixelPoint.getX(), pixelPoint.getY());
}
else {
if (!tile.pips && this.pipDefault !== null) {
if (this.pipDefault === '*') {
const pipMax = this.settings.tile === Tessellate.TILE_STYLES.HEX ? 7 : 9;
tile.pips = Tessellate.utils.random(1, pipMax);
}
else {
tile = Tessellate.utils.extend(tile, {pips: this.pipDefault});
}
}
if (tile.pips) {
this.counts[1] += tile.pips;
Tessellate.Shapes.pips(context, scale, pixelPoint.getX(), pixelPoint.getY(), tile);
}
}
}

View File

@@ -9,6 +9,9 @@ export const sqrt2 = Math.sqrt(2);
// (2*S gives long width)
export const sqrt3 = Math.sqrt(3);
// leg factor of isoscelese right triangle with unit hypotenuse
export const invSqrt2 = 1 / sqrt2
export function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
@@ -141,3 +144,13 @@ export function extend (obj, ...sources) {
return extended;
}
export function quickCanvas (draw, height, width = height) {
const canvas = document.createElement('canvas');
canvas.height = height;
canvas.width = width;
draw(canvas.getContext('2d'), canvas.height, canvas.width);
return canvas;
}