+ var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });
+ var walls;
+ var gems;
+ var shrinklevel = 0;
+
+ const WAIT_KEY = 200;
+ const WAIT_GEM = 2000;
+ const WALL_THICKNESS = 32;
+ const MAX_GEMS = 16;
+
+ var newWorldStartX;
+ var newWorldEndX;
+ var newWorldStartY;
+ var newWorldEndY;
+
+ window.addEventListener("keydown", function(e) {
+ // Prevent default browser action for arrows and spacebar
+ if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
+ e.preventDefault();
+ }
+ }, false);
+
+ class Entity extends Phaser.Sprite {
+ constructor(x, y, sprite) {
+ super(game, x, y, sprite);
+ this.anchor.setTo(.5,.5);
+ }
+
+ enablePhysics() {
+ game.physics.arcade.enable(this);
+ this.body.bounce.y = 0.2;
+ this.body.bounce.x = 0.2;
+ this.body.collideWorldBounds = true;
+ }
+ }
+
+ class Player extends Entity {
+ constructor(x, y, sprite) {
+ super(x, y, sprite);
+ this.lastmovetime = 0;
+ }
+ }
+
+ class Gem extends Entity {
+ constructor(x, y) {
+ super(x, y, 'gem');
+ this.lastInteraction = 0;
+ this.isActivated = false;
+ }
+
+ activate() {
+ this.isActivated = true;
+ this.loadTexture('gem_active');
+ }
+
+ deactivate() {
+ this.isActivated = false;
+ this.loadTexture('gem');
+ }
+ }
+
+ function sign(n) {
+ if (n >= 0) { return 1 } else { return -1 };
+ }
+
+ function preload () {
+
+ game.load.image('wall', 'wall.png');
+ game.load.image('player', 'player.png');
+ game.load.image('gem', 'gem.png');
+ game.load.image('gem_active', 'gem_active.png');
+
+ }
+
+ function create () {
+
+ game.world.setBounds(0, 0, 800, 600);
+ game.stage.backgroundColor = 'black';
+ game.physics.startSystem(Phaser.Physics.ARCADE);
+
+ walls = game.add.group();
+ walls.classType = Phaser.TileSprite;
+ walls.enableBody = true;
+
+ walls.add(game.add.tileSprite(0, 0, game.world.width, WALL_THICKNESS, 'wall'));
+ walls.add(game.add.tileSprite(0, game.world.height - WALL_THICKNESS, game.world.width, WALL_THICKNESS, 'wall'));
+ walls.add(game.add.tileSprite(0, 0, WALL_THICKNESS, game.world.height, 'wall'));
+ walls.add(game.add.tileSprite(game.world.width - WALL_THICKNESS, 0, WALL_THICKNESS, game.world.height, 'wall'));
+ walls.children.forEach(function(wall) { wall.body.immovable = true; });
+
+ gems = game.add.group();
+ for (var i = 0; i <= MAX_GEMS; i++)
+ gems.add(new Gem((Math.random() * (game.world.width - (WALL_THICKNESS * 4))) + (WALL_THICKNESS * 2), (Math.random() * (game.world.height - (WALL_THICKNESS * 4))) + (WALL_THICKNESS * 2)));
+ gems.children.forEach(function(gem) { gem.enablePhysics(); });
+
+ player = new Player(64, game.world.height - 200, 'player');
+ player.enablePhysics();
+ game.add.existing(player);
+ game.camera.follow(player);
+ cursors = game.input.keyboard.createCursorKeys();
+
+ keyboard_handler = keyPress_default;
+
+ newWorldStartX = WALL_THICKNESS;
+ newWorldEndX = game.world.width - WALL_THICKNESS;
+ newWorldStartY = WALL_THICKNESS;
+ newWorldEndY = game.world.height - WALL_THICKNESS;
+
+ helptext = game.add.text(10, 10, "Move with arrows, activate dimension crystals to shrink the world.", { align: 'left', fill: '#000000', fontSize: 14 });
+ helptext.font = "Ubuntu Mono";
+
+ }
+
+ function update () {
+
+ game.physics.arcade.collide(player, walls);
+ game.physics.arcade.overlap(player, gems, gem_overlap, gem_isInteractable);
+
+ var isAllActive = true;
+ gems.children.forEach(function(gem) { if (!gem.isActivated) { isAllActive = false; }});
+ if (isAllActive) {
+ world_shrink();
+ };
+
+ if ((game.time.now - player.lastmovetime) > WAIT_KEY) player.body.velocity.x = player.body.velocity.y = 0;
+ if (keyboard_handler) keyboard_handler();
+
+ }
+
+ function keyPress_default() {
+
+ if (cursors.left.isDown)
+ {
+ player.body.velocity.x = -150;
+ player.angle = -90;
+ player.lastmovetime = game.time.now;
+ }
+ else if (cursors.right.isDown)
+ {
+ player.body.velocity.x = 150;
+ player.angle = 90;
+ player.lastmovetime = game.time.now;
+ }
+ if (cursors.up.isDown)
+ {
+ player.body.velocity.y = -150;
+ player.angle = 0;
+ player.lastmovetime = game.time.now;
+ }
+ else if (cursors.down.isDown)
+ {
+ player.body.velocity.y = 150;
+ player.angle = 180;
+ player.lastmovetime = game.time.now;
+ }
+
+ }
+
+ function gem_isInteractable(player, gem) {
+ return (game.time.now - gem.lastInteraction) > WAIT_GEM;
+ }
+
+ function gem_overlap(player, gem) {
+
+ gem.lastInteraction = game.time.now;
+ gem.activate();
+
+ }
+
+ function world_shrink() {
+
+ if (player.x < (newWorldStartX + (newWorldEndX - newWorldStartX) / 2))
+ newWorldEndX -= (newWorldEndX - newWorldStartX) / 2;
+ else
+ newWorldStartX += (newWorldEndX - newWorldStartX) / 2;
+ if (player.y < (newWorldStartY + (newWorldEndY - newWorldStartY) / 2))
+ newWorldEndY -= (newWorldEndY - newWorldStartY) / 2;
+ else
+ newWorldStartY += (newWorldEndY - newWorldStartY) / 2;
+
+ // Draw a wall around the new world bounds.
+ walls.add(game.add.tileSprite(newWorldStartX - WALL_THICKNESS, newWorldStartY - WALL_THICKNESS, newWorldEndX - newWorldStartX + WALL_THICKNESS * 2, WALL_THICKNESS, 'wall'));
+ walls.add(game.add.tileSprite(newWorldStartX - WALL_THICKNESS, newWorldEndY, newWorldEndX - newWorldStartX + WALL_THICKNESS * 2, WALL_THICKNESS, 'wall'));
+ walls.add(game.add.tileSprite(newWorldStartX - WALL_THICKNESS, newWorldStartY - WALL_THICKNESS, WALL_THICKNESS, newWorldEndY - newWorldStartY + WALL_THICKNESS * 2, 'wall'));
+ walls.add(game.add.tileSprite(newWorldEndX, newWorldStartY - WALL_THICKNESS, WALL_THICKNESS, newWorldEndY - newWorldStartY + WALL_THICKNESS * 2, 'wall'));
+ walls.children.forEach(function(wall) { wall.body.immovable = true; });
+
+ function relocateGem(gem) {
+ if (gem.x < newWorldStartX) gem.x = newWorldStartX + (newWorldStartX - gem.x);
+ else if (gem.x > newWorldEndX) gem.x = newWorldEndX + (newWorldEndX - gem.x); // Adding negative value is like substraction.
+ if (gem.y < newWorldStartY) gem.y = newWorldStartY + (newWorldStartY - gem.y);
+ else if (gem.y > newWorldEndY) gem.y = newWorldEndY + (newWorldEndY - gem.y); // Same.
+ gem.deactivate();
+ }
+ gems.children.forEach(relocateGem);
+
+ }