const Phaser = require('phaser'); const Node = require('./zone.node'); const ZoneControls = require('./zone.controls'); const { POSITIONS: { MENU_MAIN }, TEXT } = 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 class Zones extends Phaser.Scene { constructor() { super({ key: 'Zones' }); } preload() { this.load.image('eye', 'https://labs.phaser.io/assets/particles/green-orb.png'); } create(zone) { if (!zone) return false; if (!this.scene.get('ZoneControls')) this.scene.manager.add('ZoneControls', ZoneControls, true, zone.id); this.graphics = this.add.graphics(); this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT); this.addNodes(zone.graph.nodes); this.drawEdges(zone.graph.edges); this.addCameraControl(); this.addEvents(zone.id); return this; } addNodes(nodeData) { this.nodes = []; nodeData.forEach((n, i) => { this.nodes[i] = this.add.existing( new Node(this, n.x * 50 + 200, n.y * 50 + 200, i, n.success, n.tag) ).setInteractive(); }); } addCameraControl() { this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl({ camera: this.cameras.main, zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q), zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), acceleration: 0.005, drag: 0.0005, maxSpeed: 0.001, }); } addEvents(zoneId) { this.input.on('pointerover', (pointer, gameObjects) => { if (gameObjects[0] instanceof Node) { this.displayNodeText(gameObjects[0], pointer); } }); this.input.on('pointerout', (pointer, gameObjects) => { if (gameObjects[0] instanceof Node) { this.nodeText.destroy(); } }); this.input.on('pointerup', (pointer, gameObjects) => { if (Math.abs(pointer.upX - pointer.downX) < 5 && Math.abs(pointer.upY - pointer.downY) < 5) { // Check cursor hasn't significantly moved during point allocation // If panning and mouse release is on node it won't allocate if (gameObjects[0] instanceof Node) { const team = this.registry.get('cryps').filter(c => c.active).map(c => c.id); if (gameObjects[0].success) return false; this.registry.get('ws').sendZoneJoin(zoneId, gameObjects[0].id, team); } } return true; }); this.input.on('pointermove', (pointer) => { const zoomFactor = 2 / this.cameras.main.zoom; if (this.registry.get('pan')) { const points = pointer.getInterpolatedPosition(2); this.cameras.main.scrollX -= zoomFactor * (points[1].x - points[0].x); this.cameras.main.scrollY -= zoomFactor * (points[1].y - points[0].y); } }, this); } drawEdges(edgeData) { this.graphics.clear(); edgeData.forEach((e) => { const nodeA = this.nodes[e[0]]; const nodeB = this.nodes[e[1]]; if (nodeA.success && nodeB.success) { this.graphics.lineStyle(10, 0xfff00f, 0.2); } else { this.graphics.lineStyle(2, 0xffffff, 0.2); } this.graphics.lineBetween(nodeA.x, nodeA.y, nodeB.x, nodeB.y); return true; }); } displayNodeText(node, pointer) { if (this.nodeText) this.nodeText.destroy(); this.nodeText = this.add.text(node.x, node.y, node.text, TEXT.HOVER).setPadding(32); this.nodeText.setAlpha(0.8); 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); } camPan(bool) { this.pan = bool; } update(delta) { this.controls.update(delta); } cleanUp() { if (this.scene.get('ZoneControls')) this.scene.get('ZoneControls').cleanUp(); this.scene.remove(); } } module.exports = Zones;