diff --git a/client/src/events.js b/client/src/events.js old mode 100644 new mode 100755 index 9029738a..333b8391 --- a/client/src/events.js +++ b/client/src/events.js @@ -47,6 +47,7 @@ function registerEvents(registry, events) { // const friendlyTarget = activeSkill.cryp.account === cryp.account; // if (!friendlyTarget) { if (game.phase === 'Skill') { + console.log(cryp.account); ws.sendGameSkill(game.id, activeSkill.cryp.id, cryp.account, activeSkill.skill.skill); } else if (game.phase === 'Target') { ws.sendGameTarget(game.id, cryp.id, activeSkill.skill.id); diff --git a/client/src/scenes/combat.cryps.js b/client/src/scenes/combat.cryps.js index 26452ae4..e16d6e5c 100755 --- a/client/src/scenes/combat.cryps.js +++ b/client/src/scenes/combat.cryps.js @@ -29,13 +29,6 @@ const crypAvatarText = (team, iter) => { return { nameTextX, nameTextY, healthTextX, healthTextY }; }; -const skillTextPosition = (crypIter, skillIter) => { - const { TEXT_MARGIN } = calcMargin(); - const skillTextX = 0.15 * COMBAT.width() * crypIter; - const skillTextY = COMBAT.y() + COMBAT.height() * 0.7 + TEXT_MARGIN * skillIter; - return [skillTextX, skillTextY]; -}; - const crypPosition = (team, iter) => { const { CRYP_MARGIN, TEAM_MARGIN, Y_PADDING } = calcMargin(); const crypAvatarX = COMBAT.width() / 8 + TEAM_MARGIN * team; @@ -48,7 +41,9 @@ class CrypImage extends Phaser.GameObjects.Image { // Avatar will be a property of cryp const { crypAvatarX, crypAvatarY } = crypPosition(team, iter); super(scene, crypAvatarX, crypAvatarY, avatar); - this.scene = scene; this.cryp = cryp; this.iter = iter; + this.scene = scene; + this.cryp = cryp; + this.iter = iter; this.healthbar = healthbar; } @@ -65,27 +60,6 @@ class CrypImage extends Phaser.GameObjects.Image { } } -class CrypSkill extends Phaser.GameObjects.Text { - constructor(scene, x, y, skill, cryp) { - // Avatar will be a property of cryp - if (skill) { - const CD_TEXT = skill.cd ? `(${skill.cd}T)` : ''; - const SKILL_TEXT = `${skill.skill} ${CD_TEXT}`; - super(scene, x, y, SKILL_TEXT, TEXT.NORMAL); - this.cryp = cryp; - this.skill = skill; - this.scene = scene; - this.setInteractive(); - } else { - super(scene, x, y, cryp.name, TEXT.HEADER); - } - } - - clickHandler() { - this.scene.game.events.emit('SET_ACTIVE_SKILL', this); - } -} - class HealthBar extends Phaser.GameObjects.Graphics { constructor(scene, cryp, team, iter, crypHpText) { super(scene); @@ -143,69 +117,58 @@ function renderCryp(scene, group, cryp, game, team, iter) { return crypSpawn; } -function renderSkills(scene, group, cryp, game, iter) { - const skillList = []; - // If the cryps have been spawned already put the skills in a corresponding pos - const namePos = skillTextPosition(iter, 0); - const addSkill = (skill, i) => { - // Draw skill group name as part of the "skill class" so we can destroy it later - if (i === 0) group.add(scene.add.existing(new CrypSkill(scene, namePos[0], namePos[1], false, cryp))); - const skillTextPos = skillTextPosition(iter, i + 2); - const skillObj = new CrypSkill(scene, skillTextPos[0], skillTextPos[1], skill, cryp); - group.add(scene.add.existing(skillObj)); - skillList.push(skillObj); - }; - if (game.phase === 'Skill' && cryp.account === scene.account.id) { - if (cryp.hp.base === 0) return true; - cryp.skills.forEach(addSkill); - } else if (game.phase === 'Target' && cryp.account !== scene.account.id) { - const blockSkill = game.stack.find(skill => skill.source_cryp_id === cryp.id); - // cryp not casting this turn - if (!blockSkill) return false; - addSkill(blockSkill, 0); - } - return skillList; -} +const CRYP_KEY_MAP = ['keydown_ONE', 'keydown_TWO', 'keydown_THREE']; -class CombatCryps extends Phaser.GameObjects.Group { - constructor(scene) { - super(scene); - this.scene = scene; +class CombatCryps extends Phaser.Scene { + constructor() { + super({ key: 'CombatCryps' }); } - update(game) { - // Setting gamePhase will stop redraw unless phase changes again - this.clearSkills(); + create(game) { + this.input.on('pointerup', (pointer, obj) => { + if (obj[0] instanceof CrypImage) { + obj[0].clickHandler(); + } + }); + this.cryps = this.add.group(); + this.account = this.registry.get('account'); + this.drawCryps(game); + this.registry.events.on('changedata', this.updateData, this); + } - // Destroy skills currently shown as the game state has changed - const account = this.scene.registry.get('account'); - const allyTeam = game.teams.find(t => t.id === account.id); - // in future there will be more than one - const [enemyTeam] = game.teams.filter(t => t.id !== account.id); + updateData(parent, key, data) { + if (key === 'game') { + if (!data) return false; + const isAnimating = this.registry.get('gameAnimating'); + if (isAnimating) return false; + this.drawCryps(data); + } + return true; + } + + drawCryps(game) { const renderTeam = (cryp, iter, team) => { const crypObj = - this.children.entries + this.cryps.children.entries .filter(obj => obj instanceof CrypImage) .find(c => c.cryp.id === cryp.id) - || renderCryp(this.scene, this, cryp, game, team, iter); - // Update to health bars wont be needed when dmg taken is done properly - crypObj.healthbar.hp = cryp.hp.base; - crypObj.healthbar.drawHealthBar(); - crypObj.skills = renderSkills(this.scene, this, cryp, game, crypObj.iter); - const addKeys = (game.phase === 'Skill' && !team) || (game.phase === 'Target' && team); - if (addKeys) this.scene.crypKeyHandler(crypObj, crypObj.iter); + || renderCryp(this, this.cryps, cryp, game, team, iter); }; - allyTeam.cryps.forEach((cryp, i) => renderTeam(cryp, i, 0)); + const allyTeam = game.teams.find(t => t.id === this.account.id); + // in future there will be more than one + const [enemyTeam] = game.teams.filter(t => t.id !== this.account.id); + + allyTeam.cryps.forEach((cryp, i) => renderTeam(cryp, i, 0)); if (!enemyTeam) return false; enemyTeam.cryps.forEach((cryp, i) => renderTeam(cryp, i, 1)); return true; } - clearSkills() { - // console.log(this.scene.gameStart); - this.children.entries.filter(obj => obj instanceof CrypSkill).forEach(obj => obj.destroy()); + cleanUp() { + this.registry.events.off('changedata', this.updateData); + this.scene.remove(); } } -module.exports = { CombatCryps, CrypImage, CrypSkill }; +module.exports = CombatCryps; diff --git a/client/src/scenes/combat.js b/client/src/scenes/combat.js index bd6bb86b..fc384c82 100755 --- a/client/src/scenes/combat.js +++ b/client/src/scenes/combat.js @@ -2,12 +2,11 @@ const Phaser = require('phaser'); const fs = require('fs'); const { throttle } = require('lodash'); -const { POSITIONS: { COMBAT }, TEXT } = require('./constants'); -const { CombatCryps, CrypImage, CrypSkill } = require('./combat.cryps'); +const CombatLog = require('./combat.log'); +const CombatCryps = require('./combat.cryps'); +const CombatSkills = require('./combat.skills'); const renderResolutions = require('./combat.render.resolutions'); -const CRYP_KEY_MAP = ['keydown_ONE', 'keydown_TWO', 'keydown_THREE']; -const SKILL_KEY_MAP = ['keydown_Q', 'keydown_W', 'keydown_E', 'keydown_R']; class Combat extends Phaser.Scene { constructor() { @@ -29,26 +28,14 @@ class Combat extends Phaser.Scene { } create() { + this.registry.events.off('changedata', this.updateData); this.registry.events.on('changedata', this.updateData, this); this.input.keyboard.on('keydown_S', () => { this.endGame(); }, 0, this); - - this.input.on('pointerup', (pointer, obj) => { - if (obj[0] instanceof CrypImage || obj[0] instanceof CrypSkill) { - obj[0].clickHandler(); - } else if (this.registry.get('activeSkill')) { - this.registry.get('activeSkill').clearTint(); - this.registry.set('activeSkill', null); - } - }); - this.registry.set('gamePhase', false); this.registry.set('gameAnimating', false); this.account = this.registry.get('account'); - this.log = this.add.text(COMBAT.LOG.x(), COMBAT.LOG.y(), '', TEXT.NORMAL); - this.log.setWordWrapWidth(COMBAT.LOG.width()); - this.fetchGame = throttle(() => { const game = this.registry.get('game'); if (game) { @@ -61,17 +48,20 @@ class Combat extends Phaser.Scene { } startGame(game) { + this.scene.manager.add('CombatCryps', CombatCryps, true, game); + this.scene.manager.add('CombatLog', CombatLog, true, game); + this.scene.manager.add('CombatSkills', CombatSkills, true, game); this.renderedResolves = game.resolved.length; // In case you rejoin mid way - this.combatCryps = new CombatCryps(this); - this.combatCryps.update(game); this.registry.set('gamePhase', game.phase); return true; } endGame() { this.scene.switch('CrypList'); // Switch back to cryp list - this.registry.events.off('changedata', this.updateData); this.registry.set('game', null); + this.scene.get('CombatLog').cleanUp(); + this.scene.get('CombatCryps').cleanUp(); + this.scene.get('CombatSkills').cleanUp(); this.scene.remove(); return true; } @@ -86,12 +76,18 @@ class Combat extends Phaser.Scene { if (!data) return false; const startGame = this.registry.get('gamePhase') === false; if (startGame) { this.startGame(data); return true; } - this.redrawGame(data); + this.checkAnimation(data); + // Game over? + if (data.phase === 'Finish') { + this.time.delayedCall(5000, () => { + this.endGame(); + }); + } } return true; } - redrawGame(game) { + checkAnimation(game) { // do we need to render resolution animations? const isAnimating = this.registry.get('gameAnimating'); if (isAnimating) return false; @@ -102,41 +98,6 @@ class Combat extends Phaser.Scene { this.combatCryps.clearSkills(); return true; } - // update log - // shallow copy because reverse mutates - this.log.setText(Array.from(game.log).reverse()); - // has the phase changed? - const phaseChange = (this.registry.get('gamePhase') === game.phase); - if (phaseChange) return false; - this.registry.set('gamePhase', game.phase); - this.combatCryps.update(game); - - - // Game over? - if (game.phase === 'Finish') { - this.time.delayedCall(5000, () => { - this.endGame(); - }); - } - - return true; - } - - crypKeyHandler(cryp, iter) { - if (CRYP_KEY_MAP[iter]) { - this.input.keyboard.removeListener(CRYP_KEY_MAP[iter]); - if (cryp.skills.length > 0) { // check there are cryp skills - this.input.keyboard.on(CRYP_KEY_MAP[iter], () => { - SKILL_KEY_MAP.forEach(k => this.input.keyboard.removeListener(k)); - cryp.skills.forEach((skill, i) => { - this.input.keyboard.on(SKILL_KEY_MAP[i], () => { - this.game.events.emit('SET_ACTIVE_SKILL', skill); - skill.setActive(); - }, this); - }); - }, this); - } - } return true; } } diff --git a/client/src/scenes/combat.log.js b/client/src/scenes/combat.log.js new file mode 100755 index 00000000..0ce11b31 --- /dev/null +++ b/client/src/scenes/combat.log.js @@ -0,0 +1,32 @@ +const Phaser = require('phaser'); +const { POSITIONS: { COMBAT }, TEXT } = require('./constants'); + +class CombatLog extends Phaser.Scene { + constructor() { + super({ key: 'CombatLog' }); + } + + create(game) { + this.registry.events.on('changedata', this.updateData, this); + this.log = this.add.text(COMBAT.LOG.x(), COMBAT.LOG.y(), '', TEXT.NORMAL); + this.log.setWordWrapWidth(COMBAT.LOG.width()); + this.log.setText(Array.from(game.log).reverse()); + } + + updateData(parent, key, data) { + if (key === 'game') { + if (!data) return false; + // update log + // shallow copy because reverse mutates + this.log.setText(Array.from(data.log).reverse()); + } + return true; + } + + cleanUp() { + this.registry.events.off('changedata', this.updateData); + this.scene.remove(); + } +} + +module.exports = CombatLog; diff --git a/client/src/scenes/combat.render.resolutions.js b/client/src/scenes/combat.render.resolutions.js old mode 100644 new mode 100755 diff --git a/client/src/scenes/combat.skills.js b/client/src/scenes/combat.skills.js new file mode 100755 index 00000000..ce57cc03 --- /dev/null +++ b/client/src/scenes/combat.skills.js @@ -0,0 +1,142 @@ +const Phaser = require('phaser'); +const { TEXT, POSITIONS: { COMBAT } } = require('./constants'); + +const calcMargin = () => { + const CRYP_MARGIN = COMBAT.height() / 5; + const TEXT_MARGIN = COMBAT.height() / 35; + const TEAM_MARGIN = COMBAT.width() * 0.7; + const X_PADDING = COMBAT.width() / 10; + const Y_PADDING = COMBAT.height() / 7; + return { CRYP_MARGIN, TEXT_MARGIN, TEAM_MARGIN, X_PADDING, Y_PADDING }; +}; + +const skillTextPosition = (crypIter, skillIter) => { + const { TEXT_MARGIN } = calcMargin(); + const skillTextX = 0.15 * COMBAT.width() * crypIter; + const skillTextY = COMBAT.y() + COMBAT.height() * 0.7 + TEXT_MARGIN * skillIter; + return [skillTextX, skillTextY]; +}; + +class CrypSkill extends Phaser.GameObjects.Text { + constructor(scene, x, y, skill, cryp) { + // Avatar will be a property of cryp + if (skill) { + const CD_TEXT = skill.cd ? `(${skill.cd}T)` : ''; + const SKILL_TEXT = `${skill.skill} ${CD_TEXT}`; + super(scene, x, y, SKILL_TEXT, TEXT.NORMAL); + this.cryp = cryp; + this.skill = skill; + this.scene = scene; + this.setInteractive(); + } else { + super(scene, x, y, cryp.name, TEXT.HEADER); + } + } + + clickHandler() { + this.scene.game.events.emit('SET_ACTIVE_SKILL', this); + } +} + +class CombatSkills extends Phaser.Scene { + constructor() { + super({ key: 'CombatSkills' }); + } + + create(game) { + this.registry.events.on('changedata', this.updateData, this); + this.input.on('pointerup', (pointer, obj) => { + if (obj[0] instanceof CrypSkill) { + obj[0].clickHandler(); + } + }); + this.skills = this.add.group(); + this.account = this.registry.get('account'); + // this.drawSkills(game); + } + + updateData(parent, key, data) { + if (key === 'game') { + if (!data) return false; + const isAnimating = this.registry.get('gameAnimating'); + if (isAnimating) return false; + // this.drawSkills(data); + } + return true; + } + + drawSkills(game) { + // const addKeys = (game.phase === 'Skill' && !team) || (game.phase === 'Target' && team); + const renderSkills = (scene, cryp, iter) => { + const skillList = []; + // If the cryps have been spawned already put the skills in a corresponding pos + const namePos = skillTextPosition(iter, 0); + const addSkill = (skill, i) => { + // Draw skill group name as part of the "skill class" so we can destroy it later + if (i === 0) this.skills.add(this.add.existing(new CrypSkill(scene, namePos[0], namePos[1], false, cryp))); + const skillTextPos = skillTextPosition(iter, i + 2); + const skillObj = new CrypSkill(scene, skillTextPos[0], skillTextPos[1], skill, cryp); + group.add(scene.add.existing(skillObj)); + skillList.push(skillObj); + }; + if (game.phase === 'Skill' && cryp.account === scene.account.id) { + if (cryp.hp.base === 0) return true; + cryp.skills.forEach(addSkill); + } else if (game.phase === 'Target' && cryp.account !== scene.account.id) { + const blockSkill = game.stack.find(skill => skill.source_cryp_id === cryp.id); + // cryp not casting this turn + if (!blockSkill) return false; + addSkill(blockSkill, 0); + } + return true; + }; + + const allyTeam = game.teams.find(t => t.id === this.account.id); + // in future there will be more than one + const [enemyTeam] = game.teams.filter(t => t.id !== this.account.id); + + allyTeam.cryps.forEach((cryp, i) => renderSkills(cryp, i, 0)); + if (!enemyTeam) return false; + enemyTeam.cryps.forEach((cryp, i) => renderSkills(cryp, i, 1)); + + renderSkills(this, this.skills, cryp, game, crypObj.iter); + return true + } + + cleanUp() { + this.registry.events.off('changedata', this.updateData, this); + this.scene.remove(); + } +} + +module.exports = CombatSkills; + + +/* clearSkills() { + // console.log(this.scene.gameStart); + this.children.entries.filter(obj => obj instanceof CrypSkill).forEach(obj => obj.destroy()); + } +*/ +/* crypKeyHandler(cryp, iter) { + if (CRYP_KEY_MAP[iter]) { + this.input.keyboard.removeListener(CRYP_KEY_MAP[iter]); + if (cryp.skills.length > 0) { // check there are cryp skills + this.input.keyboard.on(CRYP_KEY_MAP[iter], () => { + SKILL_KEY_MAP.forEach(k => this.input.keyboard.removeListener(k)); + cryp.skills.forEach((skill, i) => { + this.input.keyboard.on(SKILL_KEY_MAP[i], () => { + this.game.events.emit('SET_ACTIVE_SKILL', skill); + skill.setActive(); + }, this); + }); + }, this); + } + } + return true; + }*/ + + /*// has the phase changed? + const phaseChange = (this.registry.get('gamePhase') === game.phase); + if (phaseChange) return false; + this.registry.set('gamePhase', game.phase); + this.combatCryps.update(game);*/