diff --git a/package-lock.json b/package-lock.json index c55ad70..5a2e773 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5994,6 +5994,11 @@ "integrity": "sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==", "dev": true }, + "lokijs": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.8.tgz", + "integrity": "sha512-D8E3TBrY35o1ELnonp2MF8b3wKu2tVNl2TqRjvS+95oPMMe7OoIAxNY1qr+5BEZwnWn2V4ErAjVt000DonM+FA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6855,6 +6860,11 @@ "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", "dev": true }, + "papaparse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.2.0.tgz", + "integrity": "sha512-ylq1wgUSnagU+MKQtNeVqrPhZuMYBvOSL00DHycFTCxownF95gpLAk1HiHdUW77N8yxRq1qHXLdlIPyBSG9NSA==" + }, "parallel-transform": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", @@ -7072,6 +7082,17 @@ "path": "^0.12.7" } }, + "phaser3-rex-plugins": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/phaser3-rex-plugins/-/phaser3-rex-plugins-1.1.18.tgz", + "integrity": "sha512-M6dSxy8l7KM1501SBi3McL4zOmDvn989npMYN/oRwfqOOrY1qj07z1hQy9johZGdlAepoYxdyAWxkcAyjgRM8A==", + "requires": { + "eventemitter3": "^3.1.2", + "lokijs": "^1.5.8", + "papaparse": "^5.2.0", + "webfontloader": "^1.6.28" + } + }, "phin": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", @@ -9318,6 +9339,11 @@ "minimalistic-assert": "^1.0.0" } }, + "webfontloader": { + "version": "1.6.28", + "resolved": "https://registry.npmjs.org/webfontloader/-/webfontloader-1.6.28.tgz", + "integrity": "sha1-23hhKSU8tujq5UwvsF+HCvZnW64=" + }, "webpack": { "version": "4.41.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", diff --git a/package.json b/package.json index 66ed01a..0a93160 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "webpack-merge": "^4.2.2" }, "dependencies": { - "phaser": "^3.20.1" + "phaser": "^3.20.1", + "phaser3-rex-plugins": "^1.1.18" } } diff --git a/src/Storage.js b/src/Storage.js new file mode 100644 index 0000000..193d90e --- /dev/null +++ b/src/Storage.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020. Antonio Martinez Casadesus and Pascal Syma. + * All rights reserved. + */ + +export default class Storage { + + static get() { + if (!window.localStorage.getItem(Storage.KEY)) + this.reset(); + + return JSON.parse(atob(window.localStorage.getItem(Storage.KEY))); + } + + static set(value) { + window.localStorage.setItem(Storage.KEY, btoa(JSON.stringify(value))); + } + + static clear() { + window.localStorage.removeItem(Storage.KEY); + } + + static reset() { + this.set({ + controls: { + jump: {name: "Jump", bind: Phaser.Input.Keyboard.KeyCodes.W}, + w_left: {name: "Walk left", bind: Phaser.Input.Keyboard.KeyCodes.A}, + w_right: {name: "Walk right", bind: Phaser.Input.Keyboard.KeyCodes.D}, + use_left: {name: "Use left item", bind: Phaser.Input.Keyboard.KeyCodes.Q}, + use_right: {name: "Use right item", bind: Phaser.Input.Keyboard.KeyCodes.E}, + attack: {name: "Attack", bind: Phaser.Input.Keyboard.KeyCodes.SPACE}, + block: {name: "Block", bind: Phaser.Input.Keyboard.KeyCodes.F}, + pickup: {name: "Pickup", bind: Phaser.Input.Keyboard.KeyCodes.S} + } + }) + } + +} + +Storage.KEY = "save"; \ No newline at end of file diff --git a/src/entities/Player.js b/src/entities/Player.js index 52940ca..13301f3 100644 --- a/src/entities/Player.js +++ b/src/entities/Player.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020. Pascal Syma + * Copyright (c) 2020. Antonio Martinez Casadesus and Pascal Syma. * All rights reserved. */ @@ -42,14 +42,14 @@ export default class Player extends Entity { } update(...args) { - if (this.scene.dieActive()) { - this.pause = true; - this.play('die', true) - .once('animationcomplete', () => { - this.setFrame(51); - this.scene.scene.pause(); - }) - } + // if (this.scene.dieActive()) { + // this.pause = true; + // this.play('die', true) + // .once('animationcomplete', () => { + // this.setFrame(51); + // this.scene.scene.pause(); + // }) + // } if (this.pause) return; @@ -59,8 +59,6 @@ export default class Player extends Entity { // Jumping, Dashing if (this.scene.upActive() && this.body.blocked.down) { this.body.velocity.y = -this.getData('speed') * 1.5; - } else if (this.scene.downActive() && !this.body.blocked.down) { - this.body.velocity.y = this.getData('speed'); } // Walking L R diff --git a/src/index.js b/src/index.js index d9fa02d..1d8232e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020. Pascal Syma + * Copyright (c) 2020. Antonio Martinez Casadesus and Pascal Syma. * All rights reserved. */ @@ -7,6 +7,8 @@ import Phaser from "phaser"; import Menu from "./scenes/Menu"; import Preload from "./scenes/Preload"; import Game from "./scenes/Game"; +import ControlsSettings from "./scenes/ControlsSettings"; +import RexUIPlugin from 'phaser3-rex-plugins/templates/ui/ui-plugin.js'; const ratio = 16 / 9; // any ratio you want, 16/9 landscape or 9/16 portrait const DEFAULT_HEIGHT = 1080 / 4; // any height you want @@ -21,11 +23,18 @@ const config = { height: DEFAULT_HEIGHT }, parent: "phaser-example", - scene: [Preload, Menu, Game], + scene: [Preload, Menu, ControlsSettings, Game], pixelArt: true, antialias: false, // pixelArt: true, - // roundPixels: true + // roundPixels: true, + plugins: { + scene: [{ + key: 'rexUI', + plugin: RexUIPlugin, + mapping: 'rexUI' + }] + } }; const game = new Phaser.Game(config); diff --git a/src/scenes/ControlsSettings.js b/src/scenes/ControlsSettings.js new file mode 100644 index 0000000..a51fe2b --- /dev/null +++ b/src/scenes/ControlsSettings.js @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020. Antonio Martinez Casadesus and Pascal Syma. + * All rights reserved. + */ + +import Storage from "../Storage"; + +export default class ControlsSettings extends Phaser.Scene { + + constructor() { + super({ + key: "ControlsSettings", + pixelArt: true + }); + } + + create() { + this.controls = Storage.get().controls; + + console.log(this.controls); + + let gridTable = this.rexUI.add.gridTable({ + x: this.cameras.main.centerX, + y: this.cameras.main.centerY, + height: this.cameras.main.height, + width: this.cameras.main.width, + + scrollMode: 0, + background: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, 0x7777ff), + + table: { + cellHeight: 80, + columns: 2, + mask: { + padding: 2, + }, + + reuseCellContainer: true + }, + + slider: { + track: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, 0x777777), + thumb: this.rexUI.add.roundRectangle(0, 0, 0, 0, 13, 0xcccccc) + }, + + header: this.rexUI.add.label({ + height: 40, + orientation: 0, + background: this.rexUI.add.roundRectangle(0, 0, 20, 20, 0, 0x777777), + text: this.add.text(0, 0, 'Controls') + }), + + space: { + left: 10, + right: 10, + top: 10, + bottom: 10, + + table: 10, + header: 10, + footer: 10, + }, + + createCellContainerCallback: (cell, cellContainer) => { + let width = cell.width, + height = cell.height, + item = cell.item, + index = cell.index; + + if (cellContainer === null) { + cellContainer = this.rexUI.add.label({ + width: width, + height: height, + + orientation: 0, + background: this.rexUI.add.roundRectangle(0, 0, 20, 20, 0).setStrokeStyle(2, 0x777777), + icon: undefined, + text: this.add.text(0, 0, ''), + space: { + icon: 10, + left: 15, + top: 0 + }, + }); + + } + + cellContainer.setMinSize(width, height); + cellContainer.getElement('text').setText(item[1].name + ": < " + this.getKeyById(item[1].bind) + " >"); + // cellContainer.getElement('icon').setFillStyle(0xffffff); + cellContainer.getElement('background').setStrokeStyle(2, 0x777777).setDepth(0); + + cellContainer.data = item; + + return cellContainer; + }, + + items: Object.entries(this.controls), + }).layout() + // .drawBounds(this.add.graphics(), 0xff0000) + ; + + gridTable + .on('cell.up', (cell, index, p) => { + if (this.listen) + return; + + this.listen = cell.data[0]; + + cell.getElement('background') + .setStrokeStyle(2, 0xff0000) + .setDepth(1); + + cell.getElement('text').setText(cell.data[1].name + ": < ??? >"); + }) + .on('cell.over', (cell, index, p) => { + cell.getElement('background') + .setStrokeStyle(2, 0xcccccc) + .setDepth(1); + }) + .on('cell.out', (cell, index, p) => { + cell.getElement('background') + .setStrokeStyle(2, 0x777777) + .setDepth(0); + }); + + + this.input.keyboard.on('keydown', e => { + if (this.listen === undefined) + return; + + this.controls[this.listen].bind = e.keyCode; + + let config = Storage.get(); + + config.controls = this.controls; + + Storage.set(config); + + this.controls = Storage.get().controls; + + gridTable + .setItems(Object.entries(this.controls)) + .scrollToBottom(); + + this.listen = undefined; + }); + + + } + + getKeyById(id) { + return Object.keys(Phaser.Input.Keyboard.KeyCodes).find(k => Phaser.Input.Keyboard.KeyCodes[k] === id); + } +} diff --git a/src/scenes/Game.js b/src/scenes/Game.js index d419147..a0f3198 100644 --- a/src/scenes/Game.js +++ b/src/scenes/Game.js @@ -1,11 +1,12 @@ /* - * Copyright (c) 2020. Pascal Syma + * Copyright (c) 2020. Antonio Martinez Casadesus and Pascal Syma. * All rights reserved. */ import Player from "../entities/Player"; import Bat from "../entities/Enemys/Bat"; import Item from "../entities/Item"; +import Storage from "../Storage"; export default class Game extends Phaser.Scene { @@ -153,12 +154,12 @@ export default class Game extends Phaser.Scene { let bat = new Bat(this, s); bat.fly(s.type === "" ? 90 : parseInt(s.type)); this.enemys.add(bat) - }) + }); map.objects[0].objects.filter(obj => obj.name === "item").forEach(s => { let item = new Item(this, s); this.items.add(item) - }) + }); this.worldLayer.setCollisionByProperty({collides: true}); @@ -167,7 +168,7 @@ export default class Game extends Phaser.Scene { bottom: false, right: false, left: false - }) + }); this.physics.world.bounds.width = this.backLayer.width; this.physics.world.bounds.height = this.backLayer.height; @@ -185,21 +186,18 @@ export default class Game extends Phaser.Scene { if (h.getData('active') && h.overlap !== undefined) { h.overlap(b); } - }) + }); - this.keyW = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W); - this.keyS = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S); - this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A); - this.keyD = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D); - this.keySpace = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); - this.keyUp = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP); - this.keyLeft = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT); - this.keyRight = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT); - this.keyDown = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN); + let controls = Storage.get().controls; + + this.keyW = this.input.keyboard.addKey(controls.jump.bind); + this.keyA = this.input.keyboard.addKey(controls.w_left.bind); + this.keyD = this.input.keyboard.addKey(controls.w_right.bind); + this.keySpace = this.input.keyboard.addKey(controls.attack.bind); // this.keyDie = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.C); - this.keyPickup = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.C); - this.keyAction1 = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q); - this.keyAction2 = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E); + this.keyPickup = this.input.keyboard.addKey(controls.pickup.bind); + this.keyAction1 = this.input.keyboard.addKey(controls.use_left.bind); + this.keyAction2 = this.input.keyboard.addKey(controls.use_right.bind); this.physics.add.overlap(this.player, this.items, (p, i) => { if (this.keyPickup.isDown && i.canPickup()) { @@ -217,28 +215,18 @@ export default class Game extends Phaser.Scene { } - dieActive() { - return false; - // return this.keyDie.isDown; - } - rightActive() { - return this.keyRight.isDown || this.keyD.isDown/* || (this.game.input.activePointer.isDown && + return /*this.keyRight.isDown || */this.keyD.isDown/* || (this.game.input.activePointer.isDown && this.game.input.activePointer.x > 2*this.game.config.width/3)*/; } leftActive() { - return this.keyLeft.isDown || this.keyA.isDown/* || (this.game.input.activePointer.isDown && + return /*this.keyLeft.isDown || */this.keyA.isDown/* || (this.game.input.activePointer.isDown && this.game.input.activePointer.x < this.game.config.width/3)*/; } - downActive() { - return this.keyDown.isDown || this.keyS.isDown/* || (this.game.input.activePointer.isDown && - this.game.input.activePointer.y > 2*this.game.config.height/3)*/; - } - upActive() { - return this.keyUp.isDown || this.keyW.isDown/* || (this.game.input.activePointer.isDown && + return /*this.keyUp.isDown || */this.keyW.isDown/* || (this.game.input.activePointer.isDown && this.game.input.activePointer.y < this.game.config.height/3)*/; } } \ No newline at end of file