new year, new menu

This commit is contained in:
Mashy 2019-01-01 16:15:43 +10:00
parent 2492e76ca1
commit d31c8775d6
17 changed files with 558 additions and 515 deletions

View File

@ -134,7 +134,7 @@ const CustomPipeline = new Phaser.Class({
Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline.call(this, {
game,
renderer: game.renderer,
fragShader: STARS,
fragShader: PLASMA,
});
},
});

View File

@ -1,5 +1,4 @@
const Phaser = require('phaser');
const fs = require('fs');
const { throttle } = require('lodash');
const CombatLog = require('./combat.log');
@ -9,7 +8,6 @@ const CombatHitBox = require('./combat.hitbox');
const renderResolutions = require('./combat.render.resolutions');
const aztecAtlas = require('../../assets/aztec.atlas.json');
class Combat extends Phaser.Scene {
constructor() {
@ -17,20 +15,12 @@ class Combat extends Phaser.Scene {
}
preload() {
// Textures already loaded can do proper check in future when theres more textures
if (!(this.textures.getTextureKeys().length > 2)) {
const aztecImg = new Image();
aztecImg.src = `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/aztec.clean.png')).toString('base64')}`;
aztecImg.onload = () => {
this.textures.addAtlas('aztec', aztecImg, aztecAtlas);
};
this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png');
this.load.image('blue', 'https://labs.phaser.io/assets/particles/blue.png');
this.load.image('green', 'https://labs.phaser.io/assets/particles/green.png');
this.load.image('red', 'https://labs.phaser.io/assets/particles/red.png');
this.load.image('white', 'https://labs.phaser.io/assets/particles/white.png');
this.load.image('yellow', 'https://labs.phaser.io/assets/particles/yellow.png');
}
this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png');
this.load.image('blue', 'https://labs.phaser.io/assets/particles/blue.png');
this.load.image('green', 'https://labs.phaser.io/assets/particles/green.png');
this.load.image('red', 'https://labs.phaser.io/assets/particles/red.png');
this.load.image('white', 'https://labs.phaser.io/assets/particles/white.png');
this.load.image('yellow', 'https://labs.phaser.io/assets/particles/yellow.png');
}
create() {

View File

@ -4,36 +4,40 @@
const CANVAS_WIDTH = 1600;
const CANVAS_HEIGHT = 1000;
const menuWidth = () => CANVAS_WIDTH;
const menuHeight = () => 25;
const headerWidth = () => CANVAS_WIDTH;
const headerHeight = () => Math.floor(CANVAS_HEIGHT * 0.05);
const menuCrypListWidth = () => Math.floor(CANVAS_WIDTH * 0.3);
const menuCrypListHeight = () => Math.floor(CANVAS_HEIGHT * 0.5);
const menuCrypListX = () => 0;
const menuCrypListY = () => headerHeight();
const itemListWidth = () => Math.floor(CANVAS_WIDTH * 0.5);
const itemListHeight = () => Math.floor(CANVAS_HEIGHT * 0.5);
const itemListX = () => 0;
const itemListY = () => Math.floor(CANVAS_HEIGHT * 0.5);
const menuNavigationWidth = () => Math.floor(CANVAS_WIDTH * 0.5);
const menuNavigationHeight = () => Math.floor(CANVAS_HEIGHT * 0.3);
const menuNavigationX = () => Math.floor(CANVAS_WIDTH * 0.5);
const menuNavigationY = () => Math.floor(CANVAS_HEIGHT * 0.7);
const menuMainWidth = () => Math.floor(CANVAS_WIDTH * 0.7);
const menuMainHeight = () => Math.floor(CANVAS_HEIGHT * 0.5);
const menuMainX = () => Math.floor(CANVAS_WIDTH * 0.3);
const menuMainY = () => headerHeight();
const combatWidth = () => CANVAS_WIDTH;
const combatHeight = () => CANVAS_HEIGHT - menuHeight();
const combatY = () => menuHeight();
const combatHeight = () => CANVAS_HEIGHT - headerHeight();
const combatY = () => headerHeight();
const combatX = () => 0;
const crypListWidth = () => Math.floor(CANVAS_WIDTH * 0.2);
const crypListHeight = () => CANVAS_HEIGHT - menuHeight();
const cryplistRowHeight = cryps => crypListHeight() / cryps.length;
const crypListY = () => menuHeight();
const crypListX = () => 0;
const gameListWidth = () => Math.floor(CANVAS_WIDTH * 0.2);
const gameListHeight = () => Math.floor(CANVAS_HEIGHT / 10);
const gameListX = () => crypListWidth() + itemListWidth();
const gameListY = i => menuHeight() + (gameListHeight() * i);
const gameListRowY = i => menuHeight() + (gameListHeight() * (i + 2));
const itemListWidth = () => Math.floor(CANVAS_WIDTH * 0.2);
const itemListHeight = () => Math.floor(CANVAS_HEIGHT / 10);
const itemListX = () => crypListWidth() * 1.5;
const itemListY = i => menuHeight() + (itemListHeight() * i);
const itemListRowY = i => menuHeight() + ((itemListHeight() * 1.5) * i);
const statsWidth = () => Math.floor(CANVAS_WIDTH - crypListWidth() - gameListWidth());
const statsHeight = () => CANVAS_HEIGHT - menuHeight();
const statsY = () => menuHeight();
const statsX = () => crypListWidth() + gameListWidth();
const statsWidth = () => Math.floor(CANVAS_WIDTH - menuCrypListWidth());
const statsHeight = () => CANVAS_HEIGHT - headerHeight();
const statsY = () => headerHeight();
const statsX = () => menuCrypListWidth();
const statsKnownX = () => Math.floor(statsX() + statsWidth() / 4);
const statsLearnableX = () => Math.floor(statsX() + statsWidth() / 2);
const statsTextMargin = () => 24;
@ -41,7 +45,7 @@ const statsLearnableMargin = () => 12;
const logWidth = () => combatWidth();
const logHeight = () => combatHeight() * 0.3;
const logY = () => menuHeight() + (combatHeight() * 0.7);
const logY = () => headerHeight() + (combatHeight() * 0.7);
const logX = () => combatWidth() * 0.6;
@ -53,18 +57,38 @@ module.exports = {
},
POSITIONS: {
MENU: {
width: menuWidth,
height: menuHeight,
HEADER: {
width: headerWidth,
height: headerHeight,
},
CRYP_LIST: {
x: crypListX,
y: crypListY,
width: crypListWidth,
height: crypListHeight,
rowHeight: cryplistRowHeight,
rowWidth: crypListWidth,
x: menuCrypListX,
y: menuCrypListY,
width: menuCrypListWidth,
height: menuCrypListHeight,
},
MENU_MAIN: {
x: menuMainX,
y: menuMainY,
width: menuMainWidth,
height: menuMainHeight,
},
NAVIGATION: {
x: menuNavigationX,
y: menuNavigationY,
width: menuNavigationWidth,
height: menuNavigationHeight,
},
ITEM_LIST: {
x: itemListX,
y: itemListY,
width: itemListWidth,
height: itemListHeight,
},
STATS: {
@ -91,22 +115,6 @@ module.exports = {
height: logHeight,
},
},
GAME_LIST: {
x: gameListX,
y: gameListY,
width: gameListWidth,
height: gameListHeight,
rowY: gameListRowY,
},
ITEM_LIST: {
x: itemListX,
y: itemListY,
width: itemListWidth,
height: itemListHeight,
rowY: itemListRowY,
},
},
COLOURS: {

View File

@ -5,6 +5,9 @@ const Menu = require('./menu');
const Combat = require('./combat');
const Zones = require('./zones');
const Background = require('./background');
const GameList = require('./game.list');
const StatSheet = require('./statsheet');
function renderCryps() {
const config = {
@ -24,11 +27,32 @@ function renderCryps() {
scene: [
Background,
Header,
], };
],
};
const game = new Phaser.Game(config);
function newMainScene(key, scene, data) {
let addScene = true;
const ACTIVE_MAIN_SCENES = ['GameList', 'Zones', 'StatSheet'];
ACTIVE_MAIN_SCENES.forEach((sKey) => {
if (game.scene.keys[sKey]) {
if (key === sKey) {
game.scene.keys[sKey].scene.restart(data);
addScene = false;
} else {
game.scene.keys[sKey].cleanUp();
}
}
});
if (addScene) game.scene.add(key, scene, true, data);
return true;
}
function changeData(parent, key, data) {
// Don't load other scenes if you're not logged in
if (!game.registry.get('account')) return false;
if (key === 'menu') {
if (data) return game.scene.add('Menu', Menu, true);
}
@ -39,7 +63,15 @@ function renderCryps() {
}
if (key === 'zone') {
return game.scene.add('Zones', Zones, true, data);
newMainScene('Zones', Zones, data);
}
if (key === 'gameList') {
newMainScene('GameList', GameList, data);
}
if (key === 'crypStats') {
newMainScene('StatSheet', StatSheet, data);
}
return true;

View File

@ -0,0 +1,53 @@
const Phaser = require('phaser');
const { TEXT, POSITIONS: { MENU_MAIN } } = require('./constants');
const X = MENU_MAIN.x();
const Y = MENU_MAIN.y();
const WIDTH = MENU_MAIN.width();
const HEIGHT = MENU_MAIN.height();
const ROW_SIZE = 50;
const LOBBY_WIDTH = WIDTH / 2;
class GameList extends Phaser.Scene {
constructor() {
super({ key: 'GameList' });
}
create(gameList) {
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
const ws = this.registry.get('ws');
this.add.text(WIDTH / 3, 0, 'PVP open games', TEXT.HEADER);
const gameRow = (game, i) => {
const GAME_X = WIDTH / 6;
const GAME_Y = 1.3 * ROW_SIZE * (i + 1);
const gameBox = this.add
.rectangle(GAME_X, GAME_Y, LOBBY_WIDTH, ROW_SIZE, 0x222222)
.setInteractive()
.setOrigin(0);
const TITLE = `${game.teams[0].cryps.map(c => c.name).join(', ')} - ${game.team_size}v${game.team_size}`;
this.add
.text(gameBox.getCenter().x, gameBox.getCenter().y, TITLE, TEXT.NORMAL)
.setOrigin(0.5, 0.5);
gameBox.on('pointerdown', () => {
const cryps = this.registry.get('cryps');
const team = cryps.filter(c => c.active).map(c => c.id);
ws.sendGameJoin(game.id, team);
});
};
gameList.forEach(gameRow);
return true;
}
cleanUp() {
this.scene.remove();
}
}
module.exports = GameList;

View File

@ -1,12 +1,24 @@
const Phaser = require('phaser');
const { TEXT } = require('./constants');
const fs = require('fs');
const aztecAtlas = require('../../assets/aztec.atlas.json');
class Header extends Phaser.Scene {
constructor() {
super({ key: 'Header', active: true });
}
preload() {
const aztecImg = new Image();
aztecImg.src = `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/aztec.clean.png')).toString('base64')}`;
aztecImg.onload = () => {
this.textures.addAtlas('aztec', aztecImg, aztecAtlas);
};
}
create() {
this.add.text(0, 0, 'cryps.gg', TEXT.HEADER);
}

View File

@ -6,6 +6,13 @@ const {
POSITIONS: { ITEM_LIST },
} = require('./constants');
const X = ITEM_LIST.x();
const Y = ITEM_LIST.y();
const WIDTH = ITEM_LIST.width();
const HEIGHT = ITEM_LIST.height();
const ITEM_WIDTH = WIDTH * 0.3;
const ITEM_HEIGHT = HEIGHT * 0.1;
const itemCheckHitbox = (scenePlugin, pointer) => {
const { list } = scenePlugin.get('MenuCrypList').children;
const hitboxes = list.filter(c => c.cryp);
@ -35,11 +42,8 @@ class Item extends Phaser.GameObjects.Container {
this.origX = x;
this.origY = y;
const WIDTH = ITEM_LIST.width();
const HEIGHT = ITEM_LIST.height();
this.box = scene.add
.rectangle(0, 0, WIDTH, HEIGHT, 0x111111);
.rectangle(0, 0, ITEM_WIDTH, ITEM_HEIGHT, 0x111111);
this.text = scene.add
.text(0, 0, item.action, TEXT.HEADER)
@ -48,7 +52,7 @@ class Item extends Phaser.GameObjects.Container {
this.add(this.box);
this.add(this.text);
this.setSize(WIDTH, HEIGHT);
this.setSize(ITEM_WIDTH, ITEM_HEIGHT);
this.setInteractive();
}
@ -94,14 +98,16 @@ class ItemList extends Phaser.Scene {
const itemList = this.registry.get('itemList');
const ws = this.registry.get('ws');
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
this.registry.events.on('changedata', this.updateData, this);
this.registry.events.on('setdata', this.updateData, this);
if (!itemList) return false;
itemList.forEach((item, i) => {
const ITEM_X = ITEM_LIST.x();
const ITEM_Y = ITEM_LIST.rowY(i);
const ITEM_X = ITEM_WIDTH;
const ITEM_Y = ITEM_HEIGHT * 1.2 * (i + 1);
const itemBox = new Item(this, item, ITEM_X, ITEM_Y);
this.input.setDraggable(itemBox);

View File

@ -1,6 +1,9 @@
const Phaser = require('phaser');
const { TEXT, COLOURS, POSITIONS: { CRYP_LIST, MENU } } = require('./constants');
const { TEXT, COLOURS, POSITIONS: { CRYP_LIST } } = require('./constants');
const ROW_HEIGHT = CRYP_LIST.height() * 0.2;
const ROW_WIDTH = CRYP_LIST.width();
const TEXT_MARGIN = 24;
@ -8,8 +11,6 @@ const KEY_MAP = [
'keydown_ONE',
'keydown_TWO',
'keydown_THREE',
'keydown_FOUR',
'keydown_FIVE',
];
class MenuCrypList extends Phaser.Scene {
@ -18,9 +19,11 @@ class MenuCrypList extends Phaser.Scene {
}
create() {
this.cameras.main.setViewport(CRYP_LIST.x(), CRYP_LIST.y(), CRYP_LIST.width(), CRYP_LIST.height());
this.registry.events.on('changedata', this.updateData, this);
this.registry.events.on('setdata', this.updateData, this);
this.addCrypRows(this.registry.get('cryps'));
this.addControls();
}
updateData(parent, key, data) {
@ -34,34 +37,20 @@ class MenuCrypList extends Phaser.Scene {
if (!cryps) return true;
if (this.crypRows) this.crypRows.destroy(true);
this.crypRows = this.add.group();
const ROW_HEIGHT = CRYP_LIST.rowHeight(cryps);
const ROW_WIDTH = CRYP_LIST.rowWidth();
// We only display 3 cryps others can be viewed in cryp list (soon TM)
for (let i = 0; i < 3; i += 1) {
const cryp = cryps[i];
const ROW_X = 0;
const ROW_Y = (i * ROW_HEIGHT);
cryps.forEach((cryp, i) => {
const ROW_X = CRYP_LIST.x();
const ROW_Y = (i * CRYP_LIST.rowHeight(cryps)) + MENU.height();
const BOX_WIDTH = Math.floor(ROW_WIDTH / 5);
const ACTIVE_FILL = cryp.active
? 1
: 0;
: 0.2;
const FILL = Object.values(COLOURS)[i];
const row = this.add.rectangle(ROW_X, ROW_Y, ROW_WIDTH, ROW_HEIGHT, FILL, ACTIVE_FILL)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
this.scene.get('Menu').displaySkills(cryp);
});
row.itemSelect = () => {
row.setFillStyle(COLOURS.SELECT);
};
row.itemDeselect = () => {
row.setFillStyle(FILL, ACTIVE_FILL);
};
// Selection of cryps
const selectFn = () => {
this.game.events.emit('CRYP_ACTIVE', cryp);
};
@ -70,41 +59,81 @@ class MenuCrypList extends Phaser.Scene {
this.input.keyboard.on(KEY_MAP[i], selectFn, this);
}
row.cryp = cryp;
this.crypRows.add(row);
const crypStat = (stat, j) => {
const STAT_X = ROW_X;
const STAT_Y = (j * TEXT_MARGIN) + ROW_Y + TEXT_MARGIN;
this.crypRows.add(this.add.text(STAT_X, STAT_Y, `${stat.stat}: ${stat.base}`, TEXT.NORMAL));
};
const CRYP_STATS = [cryp.stamina, cryp.phys_dmg, cryp.spell_dmg];
CRYP_STATS.forEach(crypStat);
const crypSkill = (skill, j) => {
const SKILL_X = ROW_X;
const SKILL_Y = ((j + 3) * TEXT_MARGIN) + ROW_Y + TEXT_MARGIN;
this.crypRows.add(this.add.text(SKILL_X, SKILL_Y, `${skill.skill}`, TEXT.NORMAL));
};
cryp.skills.forEach(crypSkill);
const selectBtn = this.add
.rectangle(0, ROW_Y + (ROW_HEIGHT * 0.9), ROW_WIDTH, ROW_HEIGHT / 10, FILL, 0.5)
const crypSelect = this.add
.rectangle(ROW_X, ROW_Y, BOX_WIDTH, ROW_HEIGHT, FILL, 1)
.setInteractive()
.setOrigin(0)
.on('pointerdown', selectFn);
this.crypRows.add(crypSelect);
this.crypRows.add(this.add
.text(crypSelect.getCenter().x, crypSelect.y + TEXT_MARGIN, i + 1, TEXT.HEADER)
.setOrigin(0.5, 0.5));
// Cryp avatar and interaction box
const crypInteract = this.add
.rectangle(ROW_X + BOX_WIDTH, ROW_Y, BOX_WIDTH * 2, ROW_HEIGHT, FILL, ACTIVE_FILL)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
this.registry.set('crypStats', cryp);
});
crypInteract.itemSelect = () => {
crypInteract.setFillStyle(COLOURS.SELECT);
};
crypInteract.itemDeselect = () => {
crypInteract.setFillStyle(FILL, ACTIVE_FILL);
};
crypInteract.cryp = cryp;
this.crypRows.add(this.add.image(
crypInteract.getCenter().x,
crypInteract.getCenter().y,
'aztec',
`sprite${Math.floor(Math.random() * 19) + 1}`
));
this.crypRows.add(crypInteract);
// Cryp information box (names + skills)
const crypInfo = this.add
.rectangle(ROW_X + BOX_WIDTH * 3, ROW_Y, BOX_WIDTH * 2, ROW_HEIGHT, FILL, ACTIVE_FILL)
.setOrigin(0);
selectBtn.on('pointerdown', selectFn);
this.crypRows.add(this.add.text(ROW_WIDTH - 20, ROW_Y, i + 1, TEXT.HEADER));
this.crypRows.add(this.add.text(ROW_X, ROW_Y + (TEXT_MARGIN * 0), cryp.name, TEXT.HEADER));
});
this.crypRows.add(crypInfo);
this.crypRows.add(this.add
.text(crypInfo.getCenter().x, crypInfo.y + TEXT_MARGIN, cryp.name, TEXT.HEADER)
.setOrigin(0.5, 0.5));
this.crypRows.add(this.add
.text(crypInfo.getCenter().x, crypInfo.y + TEXT_MARGIN * 2, `Level: ${cryp.lvl}`, TEXT.NORMAL)
.setOrigin(0.5, 0.5));
}
return true;
}
addControls() {
// Add Spawn Cryp Option
const spawn = this.add
.rectangle(ROW_WIDTH * 0.05, ROW_HEIGHT * 3.5, ROW_WIDTH * 0.4, ROW_HEIGHT, 0x888888)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
this.game.events.emit('CRYP_SPAWN');
});
this.add
.text(spawn.getCenter().x, spawn.getCenter().y, 'Spawn Cryp', TEXT.HEADER)
.setOrigin(0.5, 0.5);
// Dialog to view all cryps
const crypList = this.add
.rectangle(ROW_WIDTH * 0.55, ROW_HEIGHT * 3.5, ROW_WIDTH * 0.4, ROW_HEIGHT, 0xff9215)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
// this.game.events.emit('CRYP_LIST');
// Placeholder will give a full list of all cryps in the center
});
this.add
.text(crypList.getCenter().x, crypList.getCenter().y, 'Cryp List (soon)', TEXT.NORMAL)
.setOrigin(0.5, 0.5);
}
cleanUp() {
KEY_MAP.forEach(k => this.input.keyboard.removeListener(k));
this.registry.events.off('changedata', this.updateData, this);

View File

@ -1,145 +0,0 @@
const Phaser = require('phaser');
const {
TEXT,
POSITIONS: { GAME_LIST },
} = require('./constants');
class MenuGameList extends Phaser.Scene {
constructor() {
super({ key: 'MenuGameList' });
}
create() {
this.registry.events.on('changedata', this.updateData, this);
this.registry.events.on('setdata', this.updateData, this);
this.addGameList(this.registry.get('gameList'));
}
updateData(parent, key, data) {
if (key === 'gameList') {
console.log('got game list');
this.addGameList(data);
}
}
addGameList(gameList) {
if (!gameList) return true;
if (this.gameList) this.gameList.destroy(true);
this.gameList = this.add.group();
const ws = this.registry.get('ws');
const cryps = this.registry.get('cryps');
const { events } = this.game;
const X = GAME_LIST.x();
const WIDTH = Math.floor(GAME_LIST.width() / 2);
const HEIGHT = GAME_LIST.height();
const TEXT_MARGIN = 24;
const spawn = this.add
.rectangle(X, GAME_LIST.y(0), WIDTH, HEIGHT, 0x888888)
.setInteractive()
.setOrigin(0);
this.gameList.add(this.add
.text(spawn.getCenter().x, spawn.getCenter().y, 'spawn\ncryp', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const pvp = this.add
.rectangle(X + WIDTH, GAME_LIST.y(0), WIDTH, HEIGHT, 0x440000)
.setInteractive()
.setOrigin(0);
this.gameList.add(this.add
.text(pvp.getCenter().x, pvp.getCenter().y, 'new PVP\ngame', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const pve = this.add
.rectangle(X, GAME_LIST.y(1), WIDTH, HEIGHT, 0x004400)
.setInteractive()
.setOrigin(0);
this.gameList.add(this.add
.text(pve.getCenter().x, pve.getCenter().y, 'new PVE\ngame', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const zones = this.add
.rectangle(X + WIDTH * 2, GAME_LIST.y(0), WIDTH, HEIGHT, 0x222222)
.setInteractive()
.setOrigin(0);
this.gameList.add(this.add
.text(zones.getCenter().x, zones.getCenter().y, 'Zones\n', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const refresh = this.add
.rectangle(X + WIDTH, GAME_LIST.y(1), WIDTH, HEIGHT, 0x000044)
.setInteractive()
.setOrigin(0);
this.gameList.add(this.add
.text(refresh.getCenter().x, refresh.getCenter().y, 'refresh\ngame list', TEXT.HEADER)
.setOrigin(0.5, 0.5));
const gameRow = (game, i) => {
const GAME_X = GAME_LIST.x();
const GAME_Y = GAME_LIST.rowY(i);
const gameBox = this.add
.rectangle(GAME_X, GAME_Y, WIDTH * 2, HEIGHT, 0x111111)
.setInteractive()
.setOrigin(0);
const TITLE = game.teams[0].cryps.map(c => c.name).join(', ');
this.gameList.add(this.add.text(GAME_X, GAME_Y, TITLE, TEXT.NORMAL));
this.gameList.add(this.add.text(GAME_X, GAME_Y + TEXT_MARGIN, `${game.team_size}v${game.team_size}`, TEXT.NORMAL));
gameBox.on('pointerdown', () => {
const team = cryps.filter(c => c.active).map(c => c.id);
ws.sendGameJoin(game.id, team);
});
};
gameList.forEach(gameRow);
spawn.on('pointerdown', () => {
events.emit('CRYP_SPAWN');
});
pvp.on('pointerdown', () => {
const team = cryps.filter(c => c.active).map(c => c.id);
return ws.sendGamePvp(team);
});
pve.on('pointerdown', () => {
const team = cryps.filter(c => c.active).map(c => c.id);
if (team.length === 0) return false;
return ws.sendGamePve(team, 'Normal');
});
zones.on('pointerdown', () => {
if (this.scene.get('Zones')) return false;
return ws.sendAccountZone();
});
refresh.on('pointerdown', () => {
return ws.sendGameJoinableList();
});
return true;
}
cleanUp() {
this.registry.events.off('changedata', this.updateData, this);
this.registry.events.off('setdata', this.updateData, this);
this.scene.remove();
}
}
module.exports = MenuGameList;

View File

@ -1,10 +1,8 @@
const Phaser = require('phaser');
const MenuCrypList = require('./menu.cryps.list');
const MenuGameList = require('./menu.game.list');
const MenuNavigation = require('./menu.navigation');
const ItemList = require('./item.list');
const StatSheet = require('./statsheet');
class Menu extends Phaser.Scene {
constructor() {
@ -16,7 +14,7 @@ class Menu extends Phaser.Scene {
this.registry.events.on('setdata', this.updateData, this);
this.scene.manager.add('MenuCrypList', MenuCrypList, true);
this.scene.manager.add('MenuGameList', MenuGameList, true);
this.scene.manager.add('MenuNavigation', MenuNavigation, true);
this.scene.manager.add('ItemList', ItemList, true);
return true;
@ -25,26 +23,16 @@ class Menu extends Phaser.Scene {
updateData(parent, key, data) {
if (key === 'game') {
if (data) return this.cleanUp();
return this.scene.restart();
}
return true;
}
// Scene switch to statsheet called by MenuCrypRows scene
displaySkills(cryp) {
if (cryp) {
this.scene.manager.add('StatSheet', StatSheet, true, cryp);
this.cleanUp();
}
return true;
}
cleanUp() {
this.registry.events.off('changedata', this.updateData, this);
this.registry.events.off('setdata', this.updateData, this);
const ACTIVE_SCENES = ['MenuCrypList', 'MenuGameList', 'ItemList', 'Zones'];
const ACTIVE_SCENES = ['MenuCrypList', 'MenuNavigation', 'GameList', 'StatSheet', 'ItemList', 'Zones'];
ACTIVE_SCENES.forEach((sKey) => {
if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp();
});

View File

@ -0,0 +1,146 @@
const Phaser = require('phaser');
const { TEXT, POSITIONS: { NAVIGATION } } = require('./constants');
const X = NAVIGATION.x();
const Y = NAVIGATION.y();
const WIDTH = NAVIGATION.width();
const HEIGHT = NAVIGATION.height();
const BTN_WIDTH = Math.floor(WIDTH / 4);
const BTN_HEIGHT = Math.floor(HEIGHT / 2);
class MenuNavigation extends Phaser.Scene {
constructor() {
super({ key: 'MenuNavigation' });
}
create() {
const ws = this.registry.get('ws');
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
const play = this.add
.rectangle(BTN_WIDTH * 3, BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, 0x222222)
.setInteractive()
.setOrigin(0);
const playText = this.add
.text(play.getCenter().x, play.getCenter().y, 'Play Cryps', TEXT.HEADER)
.setOrigin(0.5, 0.5);
play.on('pointerdown', () => {
this.selectMode(ws);
play.destroy();
playText.destroy();
});
}
selectMode(ws) {
this.buttons = this.add.group();
const pvp = this.add
.rectangle(BTN_WIDTH * 2, 0, BTN_WIDTH, BTN_HEIGHT, 0x440000)
.setInteractive()
.setOrigin(0);
const pvpText = this.add
.text(pvp.getCenter().x, pvp.getCenter().y, 'Play PVP', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const pve = this.add
.rectangle(BTN_WIDTH * 2, BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, 0x004400)
.setInteractive()
.setOrigin(0);
const pveText = this.add
.text(pve.getCenter().x, pve.getCenter().y, 'Play PVE', TEXT.HEADER)
.setOrigin(0.5, 0.5);
pve.on('pointerdown', () => {
this.addPveModes(ws);
pve.destroy();
pveText.destroy();
pvp.destroy();
pvpText.destroy();
});
pvp.on('pointerdown', () => {
this.addPvpModes(ws);
pve.destroy();
pveText.destroy();
pvp.destroy();
pvpText.destroy();
});
const cancel = this.add
.rectangle(BTN_WIDTH * 3, 0, BTN_WIDTH, BTN_HEIGHT, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => this.scene.restart());
this.add
.text(cancel.getCenter().x, cancel.getCenter().y, 'Cancel', TEXT.HEADER)
.setOrigin(0.5, 0.5);
}
addPvpModes(ws) {
const hostPvp = this.add
.rectangle(0, 0, BTN_WIDTH, BTN_HEIGHT, 0x440000)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
const team = this.registry.get('cryps').filter(c => c.active).map(c => c.id);
if (team.length === 0) return false;
ws.sendGamePvp(team);
return this.scene.restart();
});
this.add
.text(hostPvp.getCenter().x, hostPvp.getCenter().y, 'Host PVP game', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const refresh = this.add
.rectangle(BTN_WIDTH, 0, BTN_WIDTH, BTN_HEIGHT, 0x000044)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
ws.sendGameJoinableList();
return this.scene.restart();
});
this.add
.text(refresh.getCenter().x, refresh.getCenter().y, 'PVP games list', TEXT.HEADER)
.setOrigin(0.5, 0.5);
}
addPveModes(ws) {
const quickPve = this.add
.rectangle(0, BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, 0x004400)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
const team = this.registry.get('cryps').filter(c => c.active).map(c => c.id);
if (team.length === 0) return false;
ws.sendGamePve(team, 'Normal');
return this.scene.restart();
});
this.add
.text(quickPve.getCenter().x, quickPve.getCenter().y, 'Quick battle', TEXT.HEADER)
.setOrigin(0.5, 0.5);
const zones = this.add
.rectangle(BTN_WIDTH, BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', () => {
if (this.scene.get('Zones')) return false;
ws.sendAccountZone();
return this.scene.restart();
});
this.add
.text(zones.getCenter().x, zones.getCenter().y, 'Zone Mode', TEXT.HEADER)
.setOrigin(0.5, 0.5);
}
cleanUp() {
this.scene.remove();
}
}
module.exports = MenuNavigation;

View File

@ -1,16 +0,0 @@
const { TEXT, POSITIONS: { STATS } } = require('./constants');
const menuHeight = STATS.height() * 0.1;
const menuWidth = STATS.width() * 0.25;
function addButton(scene, x, y, cback, name) {
const button = scene.add
.rectangle(x, y, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', cback);
scene.add.text(button.getCenter().x, button.getCenter().y, name, TEXT.HEADER)
.setOrigin(0.5, 0.5);
}
module.exports = addButton;

View File

@ -1,15 +1,31 @@
const Phaser = require('phaser');
const { POSITIONS: { MENU_MAIN }, TEXT, SKILLS } = require('./constants');
const { POSITIONS: { STATS } } = require('./constants');
const X = MENU_MAIN.x();
const Y = MENU_MAIN.y();
const WIDTH = MENU_MAIN.width();
const HEIGHT = MENU_MAIN.height();
const TEXT_MARGIN = 24;
const LEARN_MAGIN = 12;
const Passives = require('./passives');
const Stats = require('./statsheet.stats');
const Skills = require('./statsheet.skills');
const addButton = require('./statsheet.button');
const menuX = WIDTH / 10;
const menuY = HEIGHT * 0.8;
const menuWidth = WIDTH / 10;
const menuHeight = HEIGHT * 0.3;
const menuOrig = STATS.height() * 0.5;
const menuHeight = STATS.height() * 0.1;
const menuPad = STATS.height() * 0.01;
const X_LEARN = WIDTH * 2 / 4;
const Y_SKILLS = HEIGHT * 0.5;
function addButton(scene, x, y, cback, name) {
const button = scene.add
.rectangle(x, y, menuWidth, menuHeight, 0x222222)
.setInteractive()
.setOrigin(0)
.on('pointerdown', cback);
scene.add.text(button.getCenter().x, button.getCenter().y, name, TEXT.HEADER)
.setOrigin(0.5, 1);
}
class StatSheet extends Phaser.Scene {
constructor() {
@ -17,80 +33,126 @@ class StatSheet extends Phaser.Scene {
}
create(cryp) {
this.cryp = cryp;
this.stats = new Stats(this, cryp);
this.addControls(cryp);
this.addSkills(cryp);
this.skills = true;
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
this.registry.events.on('changedata', this.updateData, this);
this.registry.events.on('setdata', this.updateData, this);
this.cryp = cryp;
this.forget = false;
const crypStat = (stat, i) => {
const STAT_X = WIDTH / 10;
const STAT_Y = (i + 1) * TEXT_MARGIN;
this.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.text(WIDTH / 10, 0, cryp.name, TEXT.HEADER);
CRYP_STATS.forEach(crypStat);
this.addKnownSkills(cryp);
this.addControls();
}
updateData(parent, key, data) {
if (key === 'menu') {
if (data) return this.cleanUp();
if (key === 'cryps') {
const cryp = data.find(c => c.id === this.cryp.id);
this.cryp = cryp;
this.addKnownSkills(cryp);
}
return true;
}
addControls() {
const infoCback = () => {
this.forget = false;
this.addKnownSkills(this.cryp);
if (this.learnSkills) this.learnSkills.destroy(true);
};
const forgetCback = () => {
this.forget = true;
this.addKnownSkills(this.cryp);
};
const learnCback = () => {
this.forget = false;
this.addKnownSkills(this.cryp);
this.addLearnableSkills(this.cryp);
};
addButton(this, menuX, menuY, infoCback, 'Skill\nInfo');
addButton(this, menuX + menuWidth * 1.1, menuY, forgetCback, 'Forget\nSkills');
addButton(this, menuX + menuWidth * 2.2, menuY, learnCback, 'Learn\nSkills');
}
addControls(cryp) {
const menuCback = () => {
this.registry.set('menu', true);
addKnownSkills(cryp) {
if (this.knownSkills) this.knownSkills.destroy(true);
this.knownSkills = this.add.group();
this.add.text(menuX, Y_SKILLS, 'Skills', TEXT.HEADER);
const knownSkill = (skill, i) => {
const SKILL_X = menuX;
const SKILL_Y = (i * TEXT_MARGIN) + Y_SKILLS + TEXT_MARGIN;
const color = this.forget ? '#ff0000' : '#ffffff';
const style = { fontFamily: 'monospace', fontSize: 16, color };
this.knownSkills.add(this.add.text(menuX, SKILL_Y, skill.skill, style)
.setInteractive()
.on('pointerdown', () => {
if (this.forget) {
this.registry.get('ws').sendCrypForget(cryp.id, skill.skill);
}
})
.on('pointerover', (pointer) => {
if (!this.forget) {
const { description } = SKILLS.LEARNABLE.find(s => s.name === skill.skill);
this.displaySkillText(SKILL_X, SKILL_Y, description, pointer);
}
})
.on('pointerout', () => {
if (this.skillText) this.skillText.destroy();
}));
};
const passiveCback = () => {
if (this.passives) return false;
this.removeSkills();
this.addPassives(cryp);
this.passives = true;
return true;
};
const skillCback = () => {
if (this.skills) return false;
this.removePassives();
this.addSkills(cryp);
this.skills = true;
return true;
};
const clearCback = () => {
this.removePassives();
this.removeSkills();
return true;
cryp.skills.forEach(knownSkill);
}
addLearnableSkills(cryp) {
if (this.learnSkills) this.learnSkills.destroy(true);
this.learnSkills = this.add.group();
const learnable = (skill, i) => {
const SKILL_X = i <= 10 ? X_LEARN : X_LEARN + WIDTH / 5;
const SKILL_Y = i <= 10 ? (i + 1) * TEXT_MARGIN : (i - 10) * TEXT_MARGIN;
this.learnSkills.add(this.add.text(SKILL_X, SKILL_Y, skill.name, TEXT.NORMAL)
.setInteractive()
.on('pointerdown', () => {
this.registry.get('ws').sendCrypLearn(cryp.id, skill.name);
})
.on('pointerover', (pointer) => {
if (!this.forget) {
this.displaySkillText(SKILL_X, SKILL_Y, skill.description, pointer);
}
})
.on('pointerout', () => {
if (this.skillText) this.skillText.destroy();
}));
};
addButton(this, 0, menuOrig, menuCback, 'Main Menu');
addButton(this, 0, menuOrig + (menuHeight + menuPad), passiveCback, 'View Passives');
addButton(this, 0, menuOrig + (menuHeight + menuPad) * 2, skillCback, 'View Skills');
addButton(this, 0, menuOrig + (menuHeight + menuPad) * 3, clearCback, 'View Cryp');
this.learnSkills.add(this.add.text(X_LEARN, 0, 'Learnable', TEXT.HEADER));
SKILLS.LEARNABLE.forEach(learnable);
}
addSkills(cryp) {
this.scene.manager.add('Skills', Skills, true, cryp);
displaySkillText(x, y, description, pointer) {
if (this.skillText) this.skillText.destroy();
this.skillText = this.add.text(x, y, description, {
fontSize: '16px',
fontFamily: 'Arial',
color: '#ffffff',
backgroundColor: '#222222',
}).setPadding(32);
this.skillText.setAlpha(0.8);
this.skillText.setOrigin(pointer.x >= WIDTH * 0.65 ? 1 : 0,
pointer.y >= HEIGHT * 0.25 ? 1 : 0);
this.skillText.setWordWrapWidth(450);
}
addPassives(cryp) {
this.scene.manager.add('Passives', Skills, true, cryp);
}
removePassives() {
if (!this.passives) return false;
this.scene.get('Passives').cleanUp();
this.passives = false;
return true;
}
removeSkills() {
if (!this.skills) return false;
this.scene.get('Skills').cleanUp();
this.skills = false;
return true;
}
cleanUp() {
this.registry.events.off('changedata', this.updateData, this);
this.registry.events.off('setdata', this.updateData, this);
this.removePassives();
this.removeSkills();
this.scene.remove();
}
}

View File

@ -1,105 +0,0 @@
const Phaser = require('phaser');
const { TEXT, SKILLS, POSITIONS: { STATS } } = require('./constants');
const addButton = require('./statsheet.button');
const TEXT_MARGIN = STATS.textMargin();
const X_ORIG_KNOWN = STATS.knownX();
const X_ORIG_LEARN = STATS.learnableX();
const Y_ORIG = STATS.y();
const menuOrigX = STATS.width() * 0.6;
const menuOrigY = STATS.height() * 0.3;
const menuHeight = STATS.height() * 0.1;
const menuPad = STATS.height() * 0.01;
const menuWidth = STATS.width() * 0.25;
class Skills extends Phaser.Scene {
constructor() {
super({ key: 'Skills' });
}
create(cryp) {
this.cryp = cryp;
this.forget = false;
// Destroy the old registry event if it exists
this.registry.events.on('changedata', this.updateData, this);
this.add.text(X_ORIG_KNOWN, Y_ORIG, 'Skills', TEXT.HEADER);
this.addKnownSkills(cryp);
this.addControls();
}
addControls() {
const infoCback = () => {
this.forget = false;
this.addKnownSkills(this.cryp);
if (this.learnSkills) this.learnSkills.destroy(true);
};
const forgetCback = () => {
this.forget = true;
this.addKnownSkills(this.cryp);
};
const learnCback = () => {
this.forget = false;
this.addKnownSkills(this.cryp);
this.addLearnableSkills(this.cryp);
};
addButton(this, menuOrigX, menuOrigY, infoCback, 'Skill Info');
addButton(this, menuOrigX, menuOrigY + (menuHeight + menuPad), forgetCback, 'Forget Skills');
addButton(this, menuOrigX, menuOrigY + (menuHeight + menuPad) * 2, learnCback, 'Learn Skills');
}
addKnownSkills(cryp) {
if (this.knownSkills) this.knownSkills.destroy(true);
this.knownSkills = this.add.group();
const knownSkill = (skill, i) => {
const SKILL_X = X_ORIG_KNOWN;
const SKILL_Y = (i * TEXT_MARGIN) + Y_ORIG + TEXT_MARGIN;
const color = this.forget ? '#ff0000' : '#ffffff';
const style = { fontFamily: 'monospace', fontSize: 16, color };
this.knownSkills.add(this.add.text(SKILL_X, SKILL_Y, skill.skill, style)
.setInteractive()
.on('pointerdown', () => {
if (this.forget) {
this.registry.get('ws').sendCrypForget(cryp.id, skill.skill);
}
}));
};
cryp.skills.forEach(knownSkill);
}
addLearnableSkills(cryp) {
if (this.learnSkills) this.learnSkills.destroy(true);
this.learnSkills = this.add.group();
const learnable = (skill, i) => {
const SKILL_X = X_ORIG_LEARN;
const SKILL_Y = Y_ORIG + (i * STATS.learnableMargin() * 3) + TEXT_MARGIN;
this.learnSkills.add(this.add.text(SKILL_X, SKILL_Y, [skill.name, skill.description], TEXT.LEARNABLE)
.setInteractive()
.on('pointerdown', () => {
this.registry.get('ws').sendCrypLearn(cryp.id, skill.name);
}));
};
this.learnSkills.add(this.add.text(X_ORIG_LEARN, Y_ORIG, 'Learnable', TEXT.HEADER));
SKILLS.LEARNABLE.forEach(learnable);
}
updateData(parent, key, data) {
if (key === 'cryps') {
const cryp = data.find(c => c.id === this.cryp.id);
this.cryp = cryp;
this.addKnownSkills(cryp);
}
}
cleanUp() {
this.registry.events.off('changedata', this.updateData, this);
this.scene.remove();
}
}
module.exports = Skills;

View File

@ -1,22 +0,0 @@
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;

View File

@ -1,9 +1,11 @@
const Phaser = require('phaser');
const {
TEXT,
POSITIONS: { GAME_LIST },
} = require('./constants');
const { TEXT, POSITIONS: { MENU_MAIN } } = require('./constants');
const X = MENU_MAIN.x();
const Y = MENU_MAIN.y();
const WIDTH = MENU_MAIN.width();
const HEIGHT = MENU_MAIN.height();
class ZoneControls extends Phaser.Scene {
constructor() {
@ -11,11 +13,10 @@ class ZoneControls extends Phaser.Scene {
}
create(zoneId) {
const WIDTH = Math.floor(GAME_LIST.width() / 2);
const HEIGHT = GAME_LIST.height();
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
const menu = this.add
.rectangle(1000, 900, WIDTH, HEIGHT, 0x888888)
.rectangle(Math.floor(WIDTH * 0.7), Math.floor(HEIGHT * 0.8), Math.floor(WIDTH * 0.2), Math.floor(HEIGHT * 0.2), 0x888888)
.setInteractive()
.setOrigin(0);
@ -24,9 +25,8 @@ class ZoneControls extends Phaser.Scene {
.setOrigin(0.5, 0.5);
menu.on('pointerdown', () => {
this.scene.get('Zones').cleanUp();
this.registry.get('ws').sendZoneClose(zoneId);
this.cleanUp();
this.scene.get('Zones').cleanUp();
});

View File

@ -1,7 +1,13 @@
const Phaser = require('phaser');
const Node = require('./zone.node');
const ZoneControls = require('./zone.controls');
const { POSITIONS: { COMBAT } } = require('./constants');
const { POSITIONS: { MENU_MAIN } } = require('./constants');
const X = MENU_MAIN.x();
const Y = MENU_MAIN.y();
const WIDTH = MENU_MAIN.width();
const HEIGHT = MENU_MAIN.height();
// Mouse click hold to move, Q + E to zoom in and out
// Press 'A' to reset allocated passive nodes
@ -19,8 +25,7 @@ class Zones extends Phaser.Scene {
if (!zone) return false;
this.scene.manager.add('ZoneControls', ZoneControls, true, zone.id);
this.graphics = this.add.graphics();
this.cameras.main.setViewport(COMBAT.width() * 0.2, COMBAT.y(),
COMBAT.width() * 0.8, COMBAT.height());
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
this.addNodes(zone.graph.nodes);
this.drawEdges(zone.graph.edges);
this.addCameraControl();
@ -32,7 +37,7 @@ class Zones extends Phaser.Scene {
this.nodes = [];
nodeData.forEach((n, i) => {
this.nodes[i] = this.add.existing(
new Node(this, 500, 850 + i * -100, i, n.success, n.tag)
new Node(this, 250 + i * 100, 250, i, n.success, n.tag)
).setInteractive();
});
}
@ -108,8 +113,8 @@ class Zones extends Phaser.Scene {
backgroundColor: '#222222',
}).setPadding(32);
this.nodeText.setAlpha(0.8);
this.nodeText.setOrigin(pointer.x >= COMBAT.width() * 0.6 ? 1 : 0,
pointer.y >= COMBAT.height() * 0.5 ? 1 : 0);
this.nodeText.setOrigin(pointer.x >= WIDTH * 0.65 ? 1 : 0,
pointer.y >= HEIGHT * 0.25 ? 1 : 0);
this.nodeText.setWordWrapWidth(450);
this.nodeText.setScale(1 / this.cameras.main.zoom);
}