From 95630bb96d6b9ac709b6f2e6800fcbe8d312ed6e Mon Sep 17 00:00:00 2001 From: Florrie Date: Thu, 23 Aug 2018 15:32:54 -0300 Subject: Prototype XYZ --- index.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 19 deletions(-) (limited to 'index.js') diff --git a/index.js b/index.js index 693b5e3..8375346 100644 --- a/index.js +++ b/index.js @@ -47,8 +47,11 @@ const isHealingAction = action => { class Sprite { constructor() { + // X is left/right, Z is forwards/backwards, Y is up/down. this.x = 0 this.y = 0 + this.z = 0 + this.canvas = document.createElement('canvas') this.canvas.width = 1 this.canvas.height = 1 @@ -919,33 +922,52 @@ class Battle { } } - ctx.save() // Begin camera-translated drawing - ctx.translate(Math.round(-camera.x), Math.round(-camera.y)) + // ctx.translate(Math.round(-camera.x), Math.round(-camera.y)) + const spriteData = [] for (const sprite of [this.backdrop, ...this.getAllBattleCharacters(), ...this.animationEntities]) { - const x = Math.round(sprite.x - sprite.canvas.width / 2) - const y = Math.round(sprite.y - sprite.canvas.height / 2) + // const x = Math.round(sprite.x - sprite.canvas.width / 2) + // const y = Math.round(sprite.y - sprite.canvas.height / 2) sprite.draw() - ctx.drawImage(sprite.canvas, x, y) + const cameraOffsetX = sprite.x - camera.x + const cameraOffsetY = sprite.y - camera.y + const cameraOffsetZ = sprite.z - camera.z + const scaleRatio = camera.getScaleRatio(cameraOffsetZ) + const drawX = scaleRatio * cameraOffsetX + const drawY = scaleRatio * cameraOffsetY + const canvasOffsetDrawX = drawX - sprite.canvas.width / 2 + const canvasOffsetDrawY = drawY - sprite.canvas.height / 2 + spriteData.push({drawX, drawY, canvasOffsetDrawX, canvasOffsetDrawY, scaleRatio, sprite}) + } + window.spriteData = spriteData + + for (const { canvasOffsetDrawX, canvasOffsetDrawY, sprite: { canvas } } of spriteData) { + ctx.drawImage(canvas, Math.round(canvasOffsetDrawX), Math.round(canvasOffsetDrawY)) + } + + for (const { drawX, canvasOffsetDrawY, sprite } of spriteData) { const overlayHPBar = overlayHPBars.find(o => o.battleCharacter === sprite) if (overlayHPBar) { - overlayHPBar.x = sprite.x - camera.x - overlayHPBar.y = y - camera.y + overlayHPBar.x = drawX + overlayHPBar.y = canvasOffsetDrawY } } - for (const battleCharacter of this.getAllBattleCharacters()) { - if (battleCharacter.isExecutingAction) { - const sprite = battleCharacter - const { label } = battleCharacter.actionBeingExecuted + for (const { sprite, drawX, offsetDrawY } of spriteData) { + if (!(sprite instanceof BattleCharacter)) { + continue + } + + if (sprite.isExecutingAction) { + const { label } = sprite.actionBeingExecuted ctx.font = '5px pixel-font' const width = ctx.measureText(label).width + 4 - const x = Math.round(sprite.x - width / 2) - const y = Math.round(sprite.y - sprite.canvas.height / 2) + const x = Math.round(drawX - width / 2) + const y = Math.round(offsetDrawY) let textFillStyle - if (battleCharacter.team === this.playerCharacter.team) { + if (sprite.team === this.playerCharacter.team) { ctx.fillStyle = 'rgba(45, 128, 255, 0.3)' ctx.strokeStyle = 'rgb(30, 85, 170)' } else { @@ -960,10 +982,9 @@ class Battle { ctx.fillText(label, x + 3, y + 7) } } - ctx.restore() // End camera-translated drawing + // ctx.restore() // End camera-translated drawing if (this.nearlyDeadAnim) { - // TODO: Gradient const height = Math.min(60, this.canvas.height / 4) const opacity = (1 - this.nearlyDeadAnim.time) * (0.35 + Math.sin(Date.now() / 300) / 5) const gradient = ctx.createLinearGradient(0, 0, 0, height) @@ -1029,10 +1050,12 @@ class Battle { } for (const { x, y, battleCharacter } of overlayHPBars) { + const { drawX: spriteX, canvasOffsetDrawY: spriteY } = spriteData.find(o => o.sprite === battleCharacter) + const hpBar = battleCharacter.hpBar hpBar.draw() - const drawX = Math.min(this.canvas.width - 10 - hpBar.canvas.width, Math.max(10 + hpBar.labelCanvas.width, Math.round(x - hpBar.canvas.width / 2))) - const drawY = Math.min(this.canvas.height - 20, Math.max(10, Math.round(y - hpBar.canvas.height))) + const drawX = Math.min(this.canvas.width - 10 - hpBar.canvas.width, Math.max(10 + hpBar.labelCanvas.width, Math.round(spriteX - hpBar.canvas.width / 2))) + const drawY = Math.min(this.canvas.height - 20, Math.max(10, Math.round(spriteY - hpBar.canvas.height))) ctx.drawImage(hpBar.canvas, drawX, drawY) ctx.drawImage(hpBar.labelCanvas, drawX - hpBar.labelCanvas.width - 2, drawY - 1) } @@ -1223,6 +1246,7 @@ class Camera extends Sprite { this.spriteToFollow = null this.width = 200 this.height = 200 + this.focalLength = 300 } update(dt) { @@ -1253,6 +1277,10 @@ class Camera extends Sprite { y: sprite.y - this.height / 2 } } + + getScaleRatio(z) { + return this.focalLength / (this.focalLength + z) + } } class BattleCamera extends Camera { @@ -1289,6 +1317,7 @@ class MagicProjectile { constructor(caster, target, action) { this.x = caster.x this.y = caster.y + this.z = caster.z this.target = target this.action = action @@ -1302,10 +1331,12 @@ class MagicProjectile { // TODO: Good animation, make distance affect acceleration, not velocity const xvel = 5 * (this.target.x - this.x) const yvel = 5 * (this.target.y - this.y) + const zvel = 5 * (this.target.z - this.z) this.x += dt * xvel this.y += dt * yvel + this.z += dt * zvel - if (Math.abs(this.target.x - this.x) <= 5 && Math.abs(this.target.y - this.y) <= 5) { + if (Math.abs(this.target.x - this.x) <= 5 && Math.abs(this.target.y - this.y) <= 5 && Math.abs(this.target.z - this.z) <= 5) { if (this.action.target === 'enemy') { if (this.action.damage) this.target.takeDamage(this.action.damage) if (this.action.stun) this.target.addStunTime(this.action.stun || 0) @@ -1319,6 +1350,7 @@ class MagicProjectile { this.target.xvel += 2 * xvel * this.target.knockbackMultiplier * actionKB this.target.yvel += 2 * yvel * this.target.knockbackMultiplier * actionKB + this.target.zvel += 2 * zvel * this.target.knockbackMultiplier * actionKB this.discarded = true } -- cgit 1.3.0-6-gf8a5