diff --git a/game/Camera.js b/game/Camera.js index 7f44ae6..17cd883 100644 --- a/game/Camera.js +++ b/game/Camera.js @@ -1,84 +1,129 @@ export default class Camera { - constructor(canvas) { - this.x = 0 - this.y = 0 + constructor(canvas) { + this.x = 0 + this.y = 0 - // TODO: when canvas resizes, this should - // syncronize with the cam - this.width = canvas.width - this.height = canvas.height + // TODO: when canvas resizes, this should + // syncronize with the cam + this.width = canvas.width + this.height = canvas.height - this.zoom = 1 - this.minZoom = .1 - this.maxZoom = 6 - this.zoomStep = .05 + this.zoom = 1 + this.minZoom = .1 + this.maxZoom = 6 + this.zoomStep = .05 + } + + rect() { + return { + x: -this.x, + y: -this.y, + w: this.width / this.zoom, + h: this.height / this.zoom, + } + } + + move(x, y) { + this.x += x / this.zoom + this.y += y / this.zoom + } + + setZoom(newzoom) { + const zoom = Math.min(Math.max(newzoom, this.minZoom), this.maxZoom) + if (zoom == this.zoom) { + return false } - rect() { - return { - x: -this.x, - y: -this.y, - w: this.width / this.zoom, - h: this.height / this.zoom, - } + // centered zoom + // TODO: mouse-centered-zoom + this.x -= Math.round(((this.width / this.zoom) - (this.width / zoom)) / 2) + this.y -= Math.round(((this.height / this.zoom) - (this.height / zoom)) / 2) + + this.zoom = zoom + return true + } + + zoomOut() { + return this.setZoom(this.zoom - this.zoomStep * this.zoom) + } + + zoomIn() { + return this.setZoom(this.zoom + this.zoomStep * this.zoom) + } + + /** + * Translate a coordinate in the viewport to a + * coordinate in the world, rounded + * @param {x, y} coord + */ + viewportToWorld(coord) { + const worldCoord = this.viewportToWorldRaw(coord) + return { + x: Math.round(worldCoord.x), + y: Math.round(worldCoord.y), } + } - move(x, y) { - this.x += x / this.zoom - this.y += y / this.zoom + /** + * Translate a coordinate in the viewport to a + * coordinate in the world, not rounded + * @param {x, y} coord + */ + viewportToWorldRaw(coord) { + return { + x: (coord.x / this.zoom) - this.x, + y: (coord.y / this.zoom) - this.y, } + } - setZoom(newzoom) { - const zoom = Math.min(Math.max(newzoom, this.minZoom), this.maxZoom) - if (zoom == this.zoom) { - return false - } - - // centered zoom - // TODO: mouse-centered-zoom - this.x -= Math.round(((this.width / this.zoom) - (this.width / zoom)) / 2) - this.y -= Math.round(((this.height / this.zoom) - (this.height / zoom)) / 2) - - this.zoom = zoom - return true + /** + * Translate a coordinate in the world to a + * coordinate in the viewport, rounded + * @param {x, y} coord + */ + worldToViewport(coord) { + const viewportCoord = this.worldToViewportRaw(coord) + return { + x: Math.round(viewportCoord.x), + y: Math.round(viewportCoord.y), } + } - zoomOut() { - return this.setZoom(this.zoom - this.zoomStep * this.zoom) + /** + * Translate a coordinate in the world to a + * coordinate in the viewport, not rounded + * @param {x, y} coord + */ + worldToViewportRaw(coord) { + return { + x: (coord.x + this.x) * this.zoom, + y: (coord.y + this.y) * this.zoom, } + } - zoomIn() { - return this.setZoom(this.zoom + this.zoomStep * this.zoom) + /** + * Translate a 2d dimension (width/height) in the world to + * one in the viewport, rounded + * @param {x, y} coord + */ + worldDimToViewport(dim) { + const viewportDim = this.worldDimToViewportRaw(dim) + return { + w: Math.round(viewportDim.w), + h: Math.round(viewportDim.h), } + } - /** - * Translate a coordinate in the viewport to a - * coordinate in the world - * @param {x, y} coord - */ - viewportToWorld(coord) { - return { - x: Math.round((coord.x / this.zoom) - this.x), - y: Math.round((coord.y / this.zoom) - this.y), - } - } - /** - * Translate a coordinate in the world to a - * coordinate in the viewport - * @param {x, y} coord - */ - worldToViewport(coord) { - return { - x: Math.round((coord.x + this.x) * this.zoom), - y: Math.round((coord.y + this.y) * this.zoom), - } - } - - worldDimToViewport(dim) { - return { - w: Math.round(dim.w * this.zoom), - h: Math.round(dim.h * this.zoom), - } + /** + * Translate a 2d dimension (width/height) in the world to + * one in the viewport, not rounded + * @param {x, y} coord + */ + worldDimToViewportRaw(dim) { + return { + w: dim.w * this.zoom, + h: dim.h * this.zoom, } + } } diff --git a/game/game.js b/game/game.js index 0fbf929..ad363d7 100644 --- a/game/game.js +++ b/game/game.js @@ -8,7 +8,6 @@ import Util from './../common/Util.js' import PuzzleGraphics from './PuzzleGraphics.js' import Game from './Game.js' import fireworksController from './Fireworks.js' -import { Rng } from '../common/Rng.js' import Protocol from '../common/Protocol.js' if (typeof GAME_ID === 'undefined') throw '[ GAME_ID not set ]' @@ -645,15 +644,15 @@ async function main() { // DRAW BOARD // --------------------------------------------------------------- - pos = viewport.worldToViewport({ + pos = viewport.worldToViewportRaw({ x: (Game.getTableWidth(gameId) - Game.getPuzzleWidth(gameId)) / 2, y: (Game.getTableHeight(gameId) - Game.getPuzzleHeight(gameId)) / 2 }) - dim = viewport.worldDimToViewport({ + dim = viewport.worldDimToViewportRaw({ w: Game.getPuzzleWidth(gameId), h: Game.getPuzzleHeight(gameId), }) - ctx.fillStyle = 'rgba(255, 255, 255, .5)' + ctx.fillStyle = 'rgba(255, 255, 255, .3)' ctx.fillRect(pos.x, pos.y, dim.w, dim.h) if (DEBUG) Debug.checkpoint('board done') // --------------------------------------------------------------- @@ -663,11 +662,11 @@ async function main() { // --------------------------------------------------------------- for (let tile of Game.getTilesSortedByZIndex(gameId)) { const bmp = bitmaps[tile.idx] - pos = viewport.worldToViewport({ + pos = viewport.worldToViewportRaw({ x: Game.getTileDrawOffset(gameId) + tile.pos.x, y: Game.getTileDrawOffset(gameId) + tile.pos.y, }) - dim = viewport.worldDimToViewport({ + dim = viewport.worldDimToViewportRaw({ w: Game.getTileDrawSize(gameId), h: Game.getTileDrawSize(gameId), }) @@ -685,7 +684,7 @@ async function main() { const ts = TIME() for (let player of Game.getActivePlayers(gameId, ts)) { const cursor = await getPlayerCursor(player) - const pos = viewport.worldToViewport(player) + const pos = viewport.worldToViewportRaw(player) ctx.drawImage(cursor, Math.round(pos.x - cursor.width/2), Math.round(pos.y - cursor.height/2)