Merge branch 'playerscene'

This commit is contained in:
Mashy 2018-12-04 15:20:50 +10:00
commit f1d6c8d17d
12 changed files with 261 additions and 43 deletions

View File

@ -43,7 +43,8 @@ function registerEvents(registry, events) {
const activeSkill = registry.get('activeSkill');
const game = registry.get('game');
if (activeSkill) {
if (activeSkill.cryp.account !== cryp.account) {
const target = activeSkill.cryp.account === cryp.account;
if (!target) {
const ws = registry.get('ws');
if (game.phase === 'Skill') {
ws.sendGameSkill(game.id, activeSkill.cryp.id, cryp.account, activeSkill.skill.skill);

7
client/src/scenes/combat.cryps.js Normal file → Executable file
View File

@ -95,6 +95,7 @@ class HealthBar extends Phaser.GameObjects.Graphics {
}
drawHealthBar() {
this.clear();
const {
healthBarX, healthBarY, healthBarWidth, healthBarHeight,
} = healthBarDimensions(this.team, this.iter);
@ -121,7 +122,6 @@ class HealthBar extends Phaser.GameObjects.Graphics {
takeDamage(damage) {
const takeDamage = (damage > this.hp) ? this.hp : damage;
this.hp -= takeDamage;
this.clear();
this.drawHealthBar();
}
}
@ -175,7 +175,7 @@ class CombatCryps extends Phaser.GameObjects.Group {
update(game, createCryps) {
// Setting gamePhase will stop redraw unless phase changes again
this.removeSkills();
if (!createCryps) this.clearSkills();
// 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);
@ -201,7 +201,8 @@ class CombatCryps extends Phaser.GameObjects.Group {
return true;
}
removeSkills() {
clearSkills() {
// console.log(this.scene.gameStart);
this.children.entries.filter(obj => obj instanceof CrypSkill).forEach(obj => obj.destroy());
}
}

27
client/src/scenes/combat.js Normal file → Executable file
View File

@ -16,7 +16,7 @@ class Combat extends Phaser.Scene {
preload() {
// Textures already loaded can do proper check in future when theres more textures
if (!(this.textures.getTextureKeys().length > 0)) {
if (!(this.textures.getTextureKeys().length > 2)) {
this.textures.addBase64('alk', `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/alakazam-f.png')).toString('base64')}`);
this.textures.addBase64('magmar', `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/magmar.png')).toString('base64')}`);
this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png');
@ -43,6 +43,7 @@ class Combat extends Phaser.Scene {
}
});
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);
@ -56,23 +57,22 @@ class Combat extends Phaser.Scene {
}
return false;
}, 1000);
return true;
}
startGame(game) {
this.registry.set('gamePhase', game.phase);
this.renderedResolves = game.resolved.length; // In case you rejoin mid way
this.combatCryps = new CombatCryps(this);
this.combatCryps.update(game, true);
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.registry.set('gamePhase', false);
this.scene.stop();
this.scene.remove();
return true;
}
@ -84,10 +84,8 @@ class Combat extends Phaser.Scene {
updateData(parent, key, data) {
if (key === 'game') {
if (!data) return false;
if (!this.registry.get('gamePhase')) {
this.startGame(data);
return true;
}
const startGame = this.registry.get('gamePhase') === false;
if (startGame) { this.startGame(data); return true; }
this.redrawGame(data);
}
return true;
@ -101,18 +99,21 @@ class Combat extends Phaser.Scene {
const newResolutions = game.resolved.slice(this.renderedResolves);
renderResolutions(this, game, this.combatCryps, newResolutions);
this.renderedResolves = game.resolved.length;
this.combatCryps.removeSkills();
this.combatCryps.clearSkills();
return true;
}
// update log
// shallow copy because reverse mutates
const content = Array.from(game.log).reverse().join('\n');
// this.log.setText(Array.from(game.log).reverse());
console.log(this.log);
this.log.setText(content);
// 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, false);
// update log
// shallow copy because reverse mutates
this.log.setText(Array.from(game.log).reverse());
// Game over?
if (game.phase === 'Finish') {

View File

@ -76,8 +76,7 @@ function animatePhase(scene, group, game, resolution, cb) {
// all done
scene.time.delayedCall(MOVE_CREEP, () => {
animations.cleanup();
animations.destroy();
animations.destroy(true);
return cb();
});
});

22
client/src/scenes/cryp.list.js Normal file → Executable file
View File

@ -1,8 +1,9 @@
const Phaser = require('phaser');
const Combat = require('./combat');
const CrypRows = require('./cryp.row');
const CrypPage = require('./cryp.page');
const GameList = require('./game.list');
const StatSheet = require('./statsheet');
class CrypList extends Phaser.Scene {
constructor() {
@ -15,7 +16,7 @@ class CrypList extends Phaser.Scene {
return true;
}
updateData(parent, key) {
updateData(parent, key, data) {
const UPDATE_KEYS = ['gameList', 'cryps'];
if (UPDATE_KEYS.includes(key)) {
this.renderList();
@ -23,7 +24,9 @@ class CrypList extends Phaser.Scene {
}
if (key === 'game' && this.scene.isActive()) {
this.scene.switch('Combat');
this.scene.sleep();
this.scene.add('Combat', Combat);
this.scene.run('Combat', data);
}
return true;
@ -38,12 +41,6 @@ class CrypList extends Phaser.Scene {
this.CrypRows.destroy(true);
}
this.CrypRows = new CrypRows(this, cryps);
// selected cryp
if (this.CrypPage) {
const cryp = cryps.find(c => c.id === this.CrypPage.id);
this.displaySkills(cryp);
}
}
renderGameList() {
@ -61,10 +58,9 @@ class CrypList extends Phaser.Scene {
displaySkills(cryp) {
if (cryp) {
if (this.CrypPage) {
this.CrypPage.destroy(true);
}
this.CrypPage = new CrypPage(this, cryp);
this.scene.add('StatSheet', StatSheet);
this.scene.run('StatSheet', { cryp });
this.scene.sleep();
}
return true;
}

3
client/src/scenes/cryps.js Normal file → Executable file
View File

@ -2,8 +2,6 @@ const Phaser = require('phaser');
const CrypList = require('./cryp.list');
const Menu = require('./menu');
const Combat = require('./combat');
// const Passives = require('./passives');
function renderCryps() {
const config = {
@ -22,7 +20,6 @@ function renderCryps() {
scene: [
Menu,
CrypList,
Combat,
],
};

17
client/src/scenes/game.list.js Normal file → Executable file
View File

@ -22,28 +22,36 @@ class GameList extends Phaser.GameObjects.Group {
.setInteractive()
.setOrigin(0);
this.add(list.add.text(spawn.getCenter().x, spawn.getCenter().y, 'SPAWN', TEXT.HEADER));
this.add(list.add
.text(spawn.getCenter().x, spawn.getCenter().y, 'SPAWN', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const pvp = list.add
.rectangle(X + WIDTH, GAME_LIST.y(0), WIDTH, HEIGHT, 0x440000)
.setInteractive()
.setOrigin(0);
this.add(list.add.text(pvp.getCenter().x, pvp.getCenter().y, 'PVP', TEXT.HEADER));
this.add(list.add
.text(pvp.getCenter().x, pvp.getCenter().y, 'PVP', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const pve = list.add
.rectangle(X, GAME_LIST.y(1), WIDTH, HEIGHT, 0x004400)
.setInteractive()
.setOrigin(0);
this.add(list.add.text(pve.getCenter().x, pve.getCenter().y, 'PVE', TEXT.HEADER));
this.add(list.add
.text(pve.getCenter().x, pve.getCenter().y, 'PVE', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const refresh = list.add
.rectangle(X + WIDTH, GAME_LIST.y(1), WIDTH, HEIGHT, 0x000044)
.setInteractive()
.setOrigin(0);
this.add(list.add.text(refresh.getCenter().x, refresh.getCenter().y, 'REFRESH', TEXT.HEADER));
this.add(list.add
.text(refresh.getCenter().x, refresh.getCenter().y, 'REFRESH', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const gameRow = (game, i) => {
@ -79,6 +87,7 @@ class GameList extends Phaser.GameObjects.Group {
pve.on('pointerdown', () => {
const team = cryps.filter(c => c.active).map(c => c.id);
if (team.length === 0) return false;
return ws.sendGamePve(team);
});

View File

@ -9,7 +9,7 @@ class Menu extends Phaser.Scene {
create() {
this.add.text(0, 0, 'cryps.gg', TEXT.HEADER);
this.scene.sleep('Passives');
// this.scene.sleep('Passives');
this.input.keyboard.on('keydown_F', () => {
this.scene.wake('Passives');
}, 0, this);

14
client/src/scenes/passives.js Normal file → Executable file
View File

@ -3,13 +3,16 @@ const PassiveNode = require('./passive.node');
const passiveDataNode = require('./passive.data.node');
const passiveDataEdge = require('./passive.data.edge');
const { POSITIONS: { COMBAT } } = require('./constants');
// Passive tree generator - proof of concept visuals need work
// Mouse click hold to move, Q + E to zoom in and out
// Press 'A' to reset allocated passive nodes
class PhaserPassives extends Phaser.Scene {
constructor() {
super({ key: 'Passives', active: true });
super({ key: 'Passives' });
// this.input = props.input;
}
preload() {
@ -20,6 +23,10 @@ class PhaserPassives extends Phaser.Scene {
this.graphics = this.add.graphics();
this.passiveNodeData = passiveDataNode;
this.passiveEdgeData = passiveDataEdge;
this.cameras.main.setViewport(COMBAT.width() * 0.2, COMBAT.y(),
COMBAT.width() * 0.8, COMBAT.height());
this.cameras.main.scrollX = 1000;
this.cameras.main.scrollY = 500;
this.addPassiveNodes();
this.addCameraControl();
this.addEvents();
@ -105,13 +112,14 @@ class PhaserPassives extends Phaser.Scene {
displayPassiveText(node, pointer) {
if (this.nodeText) this.nodeText.destroy();
this.nodeText = this.add.text(node.x, node.y, node.text, {
fontSize: '20px',
fontSize: '16px',
fontFamily: 'Arial',
color: '#ffffff',
backgroundColor: '#222222',
}).setPadding(32);
this.nodeText.setAlpha(0.8);
this.nodeText.setOrigin(pointer.x >= 600 ? 1 : 0, pointer.y >= 450 ? 1 : 0);
this.nodeText.setOrigin(pointer.x >= COMBAT.width() * 0.6 ? 1 : 0,
pointer.y >= COMBAT.height() * 0.5 ? 1 : 0);
this.nodeText.setWordWrapWidth(450);
this.nodeText.setScale(1 / this.cameras.main.zoom);
}

120
client/src/scenes/statsheet.js Executable file
View File

@ -0,0 +1,120 @@
const Phaser = require('phaser');
const Passives = require('./passives');
const Stats = require('./statsheet.stats');
const { SkillsKnown, SkillsLearn } = require('./statsheet.skills');
const { TEXT, POSITIONS: { STATS } } = require('./constants');
const menuOrig = STATS.height() * 0.5;
const menuHeight = STATS.height() * 0.1;
const menuPad = STATS.height() * 0.01;
const menuWidth = STATS.width() * 0.25;
class StatSheet extends Phaser.Scene {
constructor() {
super({ key: 'StatSheet' });
}
create(props) {
const { cryp } = props;
this.cryp = cryp;
this.stats = new Stats(this, cryp);
this.addControls(cryp);
this.registry.events.on('changedata', this.updateData, this);
}
updateData(parent, key, data) {
if (key === 'cryps') {
const cryp = data.find(c => c.id === this.cryp.id);
if (this.skillsKnown) this.skillsKnown.destroy(true);
if (this.skillsLearn) this.skillsLearn.destroy(true);
this.stats.destroy(true);
this.stats = new Stats(this, cryp);
this.addSkills(cryp);
}
}
addControls(cryp) {
const menu = this.add
.rectangle(0, menuOrig, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
// Registry events won't get auto cleaned
this.registry.events.off('changedata', this.updateData);
this.scene.run('CrypList');
this.scene.remove('Passives');
this.scene.remove();
});
this.add.text(menu.getCenter().x, menu.getCenter().y, 'Main Menu', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const passives = this.add
.rectangle(0, menuOrig + menuHeight + menuPad, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
if (this.passives) return false;
this.removeSkills();
this.addPassives(cryp);
this.passives = true;
return true;
});
this.add.text(passives.getCenter().x, passives.getCenter().y, 'View Passives', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const skills = this.add
.rectangle(0, menuOrig + (menuHeight + menuPad) * 2, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
if (this.skills) return false;
this.removePassives();
this.addSkills(cryp);
this.skills = true;
return true;
});
this.add.text(skills.getCenter().x, skills.getCenter().y, 'View Skills', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const clear = this.add
.rectangle(0, menuOrig + (menuHeight + menuPad) * 3, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
this.removePassives();
this.removeSkills();
return true;
});
this.add.text(clear.getCenter().x, clear.getCenter().y, 'View Cryp', TEXT.HEADER)
.setOrigin(0.5, 0.5);
}
addSkills(cryp) {
this.skillsKnown = new SkillsKnown(this, cryp);
this.skillsLearn = new SkillsLearn(this, cryp);
}
addPassives(cryp) {
this.scene.add('Passives', Passives);
this.scene.run('Passives', cryp);
}
removePassives() {
if (!this.passives) return false;
this.scene.remove('Passives');
this.passives = false;
return true;
}
removeSkills() {
if (!this.skills) return false;
this.skillsKnown.destroy(true);
this.skillsLearn.destroy(true);
this.skills = false;
return true;
}
}
module.exports = StatSheet;

View File

@ -0,0 +1,64 @@
const Phaser = require('phaser');
const { TEXT, SKILLS, POSITIONS: { STATS } } = require('./constants');
class SkillsKnown extends Phaser.GameObjects.Group {
constructor(scene, cryp) {
super(scene);
this.id = cryp.id;
this.scene = scene;
this.ws = scene.registry.get('ws');
const TEXT_MARGIN = STATS.textMargin();
const X_ORIG = STATS.knownX();
const Y_ORIG = STATS.y();
const knownSkill = (skill, i) => {
const SKILL_X = X_ORIG;
const SKILL_Y = (i * TEXT_MARGIN) + Y_ORIG + TEXT_MARGIN;
const text = scene.add.text(SKILL_X, SKILL_Y, skill.skill, TEXT.NORMAL)
.setInteractive();
text.on('pointerdown', () => {
this.ws.sendCrypForget(cryp.id, skill.skill);
});
this.add(text);
};
this.add(scene.add.text(X_ORIG, Y_ORIG, 'Skills', TEXT.HEADER));
cryp.skills.forEach(knownSkill);
}
}
class SkillsLearn extends Phaser.GameObjects.Group {
constructor(scene, cryp) {
super(scene);
this.id = cryp.id;
this.scene = scene;
this.ws = scene.registry.get('ws');
const TEXT_MARGIN = STATS.textMargin();
const X_ORIG = STATS.learnableX();
const Y_ORIG = STATS.y();
const learnable = (skill, i) => {
const SKILL_X = X_ORIG;
const SKILL_Y = Y_ORIG + (i * TEXT_MARGIN) + TEXT_MARGIN;
const text = scene.add.text(SKILL_X, SKILL_Y, skill, TEXT.NORMAL)
.setInteractive();
text.on('pointerdown', () => {
this.ws.sendCrypLearn(cryp.id, skill);
});
this.add(text);
text.cryp = cryp;
};
this.add(scene.add.text(X_ORIG, Y_ORIG, 'Learnable', TEXT.HEADER));
SKILLS.LEARNABLE.forEach(learnable);
}
}
module.exports = { SkillsKnown, SkillsLearn };

View File

@ -0,0 +1,22 @@
const Phaser = require('phaser');
const { TEXT, POSITIONS: { STATS } } = require('./constants');
const TEXT_MARGIN = STATS.textMargin();
class Stats extends Phaser.GameObjects.Group {
constructor(scene, cryp) {
super(scene);
const crypStat = (stat, i) => {
const STAT_X = 0;
const STAT_Y = (i * TEXT_MARGIN) + STATS.y() + TEXT_MARGIN;
this.add(scene.add.text(STAT_X, STAT_Y, `${stat.stat}: ${stat.base}`, TEXT.NORMAL));
};
const CRYP_STATS = [cryp.stamina, cryp.phys_dmg, cryp.spell_dmg];
this.add(scene.add.text(0, STATS.y(), cryp.name, TEXT.HEADER));
CRYP_STATS.forEach(crypStat);
}
}
module.exports = Stats;