├── .gitignore ├── README.md ├── assets ├── fonts │ ├── press-start-instructions.fnt │ ├── press-start-instructions.png │ ├── press-start-rollback.fnt │ ├── press-start-rollback.png │ ├── press-start-super.fnt │ ├── press-start-super.png │ ├── press-start-title.fnt │ ├── press-start-title.png │ ├── press-start-ultra.fnt │ └── press-start-ultra.png ├── images │ ├── background-2.png │ ├── background.png │ ├── blocks-alt.png │ ├── blocks.png │ ├── blocks.xcf │ ├── blocks1.png │ ├── blocks2.png │ ├── favicon.png │ ├── floor.png │ ├── github_logo.png │ ├── octocat-spinner-128.gif │ ├── octocat.png │ ├── octocoder.xcf │ ├── particle.png │ ├── poster.png │ ├── poster.xcf │ ├── progressbar.png │ ├── speaker.png │ └── title.png └── sounds │ ├── block.wav │ ├── bug.wav │ ├── dead.wav │ ├── fork.wav │ ├── korobeiniki-fast.mp3 │ ├── korobeiniki-normal.mp3 │ ├── regular.wav │ ├── rollback.wav │ ├── super.wav │ └── ultra.wav ├── elements ├── application.js ├── block.js ├── floor.js ├── hud.js ├── instructions.js ├── language.js ├── octocat.js └── text.js ├── game.js ├── index.html ├── lib └── phaser.js ├── octocoder-deploy.png ├── octocoder-ingame.png ├── octocoder-menu.png ├── octocoder-screenshot.png ├── octocoder-todo.pdf ├── octocoder-wip-1.png ├── octocoder-wip-2.png ├── octocoder-wip-3.png └── states ├── boot.js ├── instructions.js ├── load.js ├── menu.js └── play.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Octocoder 2 | ========= 3 | 4 | Octocoder is a tetris-like game where you have to collect code blocks and deploy them into 5 | applications. Combine the blocks to build popular applications and earn lots of points. 6 | It was born as a fork of [Octocat Jump](https://github.com/ogoshen/game-off-2012) 7 | and is my entry for the [Github Game Off 2015](https://github.com/blog/1972-the-game-has-changed). 8 | 9 | It works in Chrome, Firefox and Safari. It probably works in other browsers but I haven't tested. 10 | 11 | [Play it!](http://satanas.github.io/game-off-2015/) 12 | 13 | Rules 14 | ===== 15 | 1. Take the code blocks and combine them horizontally to create an application. 16 | 17 | 2. Missed blocks will become bugs 18 | 19 | 3. Unknown or buggy applications won't be deployed. 20 | 21 | 4. Each successful deploy will give you points and the blocks of that line will dissapear. 22 | 23 | 5. If Octocat touch the top of the screen, you lose. 24 | 25 | 6. If you create an app with more than 4 bugs (40%), you lose. 26 | 27 | Some combinations could be Python + HTML to create Django applications or Ruby + HTML to create Ruby on Rails apps. 28 | Try yourself other combinations to discover all the possibilities. 29 | 30 | Controls 31 | ======== 32 | 33 | * ← and → to move the player 34 | * ↓ to drop the block 35 | * P to pause the game 36 | * M to mute the music 37 | 38 | Thanks 39 | ====== 40 | 41 | I want to thank Thiago Costa for his help and his ideas for the mechanic of the game :) 42 | -------------------------------------------------------------------------------- /assets/fonts/press-start-instructions.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /assets/fonts/press-start-instructions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/fonts/press-start-instructions.png -------------------------------------------------------------------------------- /assets/fonts/press-start-rollback.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /assets/fonts/press-start-rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/fonts/press-start-rollback.png -------------------------------------------------------------------------------- /assets/fonts/press-start-super.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /assets/fonts/press-start-super.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/fonts/press-start-super.png -------------------------------------------------------------------------------- /assets/fonts/press-start-title.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /assets/fonts/press-start-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/fonts/press-start-title.png -------------------------------------------------------------------------------- /assets/fonts/press-start-ultra.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /assets/fonts/press-start-ultra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/fonts/press-start-ultra.png -------------------------------------------------------------------------------- /assets/images/background-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/background-2.png -------------------------------------------------------------------------------- /assets/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/background.png -------------------------------------------------------------------------------- /assets/images/blocks-alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/blocks-alt.png -------------------------------------------------------------------------------- /assets/images/blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/blocks.png -------------------------------------------------------------------------------- /assets/images/blocks.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/blocks.xcf -------------------------------------------------------------------------------- /assets/images/blocks1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/blocks1.png -------------------------------------------------------------------------------- /assets/images/blocks2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/blocks2.png -------------------------------------------------------------------------------- /assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/favicon.png -------------------------------------------------------------------------------- /assets/images/floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/floor.png -------------------------------------------------------------------------------- /assets/images/github_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/github_logo.png -------------------------------------------------------------------------------- /assets/images/octocat-spinner-128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/octocat-spinner-128.gif -------------------------------------------------------------------------------- /assets/images/octocat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/octocat.png -------------------------------------------------------------------------------- /assets/images/octocoder.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/octocoder.xcf -------------------------------------------------------------------------------- /assets/images/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/particle.png -------------------------------------------------------------------------------- /assets/images/poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/poster.png -------------------------------------------------------------------------------- /assets/images/poster.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/poster.xcf -------------------------------------------------------------------------------- /assets/images/progressbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/progressbar.png -------------------------------------------------------------------------------- /assets/images/speaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/speaker.png -------------------------------------------------------------------------------- /assets/images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/images/title.png -------------------------------------------------------------------------------- /assets/sounds/block.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/block.wav -------------------------------------------------------------------------------- /assets/sounds/bug.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/bug.wav -------------------------------------------------------------------------------- /assets/sounds/dead.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/dead.wav -------------------------------------------------------------------------------- /assets/sounds/fork.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/fork.wav -------------------------------------------------------------------------------- /assets/sounds/korobeiniki-fast.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/korobeiniki-fast.mp3 -------------------------------------------------------------------------------- /assets/sounds/korobeiniki-normal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/korobeiniki-normal.mp3 -------------------------------------------------------------------------------- /assets/sounds/regular.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/regular.wav -------------------------------------------------------------------------------- /assets/sounds/rollback.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/rollback.wav -------------------------------------------------------------------------------- /assets/sounds/super.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/super.wav -------------------------------------------------------------------------------- /assets/sounds/ultra.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/assets/sounds/ultra.wav -------------------------------------------------------------------------------- /elements/application.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Application = function() { 4 | this.bugs = 0; 5 | this.value = 0; 6 | this.bonus = 0; 7 | this.name = null; 8 | }; 9 | 10 | Application.prototype.constructor = Application; 11 | 12 | Application.prototype.build = function() { 13 | if (this.bugs >= game.global.bugsToRollback) { 14 | this.name = 'Too many bugs'; 15 | this.bonus = -1; 16 | } else if (this.value === 1) { 17 | this.name = 'Pure Ruby'; 18 | this.bonus = game.global.bonus.ultra; 19 | } else if (this.value === 2) { 20 | this.name = 'Pure Javascript'; 21 | this.bonus = game.global.bonus.ultra; 22 | } else if (this.value === 4) { 23 | this.name = 'Pure Java'; 24 | this.bonus = game.global.bonus.ultra; 25 | } else if (this.value === 8) { 26 | this.name = 'Pure Python'; 27 | this.bonus = game.global.bonus.ultra; 28 | } else if (this.value === 32) { 29 | this.name = 'Pure PHP'; 30 | this.bonus = game.global.bonus.ultra; 31 | } else if (this.value === 5) { 32 | this.name = 'JRuby'; 33 | this.bonus = game.global.bonus.ultra; 34 | } else if (this.value === 12) { 35 | this.name = 'Jython'; 36 | this.bonus = game.global.bonus.ultra; 37 | } else if (this.value === 21 || this.value === 23) { 38 | this.name = 'JRuby Web'; 39 | this.bonus = game.global.bonus.super; 40 | } else if (this.value === 30 || this.value === 28) { 41 | this.name = 'Jython Web'; 42 | this.bonus = game.global.bonus.super; 43 | } else if (this.value === 80 || this.value === 82 || this.value === 18) { 44 | this.name = 'Standard Web'; 45 | this.bonus = game.global.bonus.super; 46 | } else if (this.value === 48 || this.value === 34 || this.value === 50) { 47 | this.name = 'PHP Web'; 48 | this.bonus = game.global.bonus.super; 49 | } else if (this.value === 20 || this.value === 22 || this.value === 6) { 50 | this.name = 'JSP'; 51 | this.bonus = game.global.bonus.super; 52 | } else if (this.value === 17 || this.value === 19 || this.value === 3) { 53 | this.name = 'Ruby on Rails'; 54 | this.bonus = game.global.bonus.super; 55 | } else if (this.value === 24 || this.value === 26 || this.value === 10) { 56 | this.name = 'Django'; 57 | this.bonus = game.global.bonus.super; 58 | } else if (this.value === 18) { 59 | this.name = 'Express'; 60 | this.bonus = game.global.bonus.super; 61 | } else { 62 | this.name = 'Unknown app'; 63 | this.bonus = -1; 64 | } 65 | }; 66 | 67 | Application.prototype.addCode = function(block) { 68 | if (block.language.isRuby()) { 69 | this.addRuby(); 70 | } else if (block.language.isJavascript()) { 71 | this.addJavascript(); 72 | } else if (block.language.isJava()) { 73 | this.addJava(); 74 | } else if (block.language.isPython()) { 75 | this.addPython(); 76 | } else if (block.language.isHTML()) { 77 | this.addHTML(); 78 | } else if (block.language.isPHP()) { 79 | this.addPHP(); 80 | } else if (block.language.isBug()) { 81 | this.addBug(); 82 | } 83 | }; 84 | 85 | Application.prototype.addRuby = function() { 86 | this.value = this.value | 1; 87 | }; 88 | 89 | Application.prototype.addJavascript = function() { 90 | this.value = this.value | 2; 91 | }; 92 | 93 | Application.prototype.addJava = function() { 94 | this.value = this.value | 4; 95 | }; 96 | 97 | Application.prototype.addPython = function() { 98 | this.value = this.value | 8; 99 | }; 100 | 101 | Application.prototype.addHTML = function() { 102 | this.value = this.value | 16; 103 | }; 104 | 105 | Application.prototype.addPHP = function() { 106 | this.value = this.value | 32; 107 | }; 108 | 109 | Application.prototype.addBug = function() { 110 | this.bugs += 1; 111 | }; 112 | -------------------------------------------------------------------------------- /elements/block.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Block = function(delay) { 4 | var x = Math.floor(Math.random() * 10) * 40; 5 | 6 | this.falling = true; 7 | this.language = new Language(); 8 | this.moveDelay = delay; 9 | if (delay) { 10 | this.delay = delay; 11 | } else { 12 | this.delay = game.global.block.speed; 13 | } 14 | Phaser.Sprite.call(this, game, x, 0, 'blocks', this.language.index); 15 | 16 | game.physics.arcade.enable(this); 17 | groups.blocks.add(this); 18 | }; 19 | 20 | Block.prototype = Object.create(Phaser.Sprite.prototype); 21 | Block.prototype.constructor = Block; 22 | 23 | Block.prototype.update = function() { 24 | if (this.falling) { 25 | this.delay -= game.time.elapsedMS; 26 | if (this.delay <= 0) { 27 | this.y += 40; 28 | this.delay = this.moveDelay; 29 | } 30 | } 31 | 32 | if (!this.alive) { 33 | this.destroy(); 34 | } 35 | }; 36 | 37 | Block.prototype.settle = function(x, y) { 38 | this.x = x; 39 | this.falling = false; 40 | var tween = game.add.tween(this); 41 | tween.to({y: y}, 200, Phaser.Easing.Linear.None, true); 42 | }; 43 | 44 | Block.prototype.displace = function() { 45 | var tween = game.add.tween(this); 46 | tween.to({y: this.y + 40}, 250, Phaser.Easing.Linear.None, true); 47 | }; 48 | 49 | Block.prototype.addBug = function() { 50 | this.language.addBug(); 51 | this.frame = 6; 52 | }; 53 | 54 | Block.prototype.isBug = function() { 55 | return this.language.isBug(); 56 | }; 57 | -------------------------------------------------------------------------------- /elements/floor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Floor = function() { 4 | this.h = 40; 5 | this.lines = [ 6 | [null, null, null, null, null, null, null, null, null, null] 7 | ]; 8 | 9 | this.sprite = game.add.sprite(0, 580, 'floor'); 10 | game.physics.arcade.enable(this.sprite); 11 | this.sprite.body.immovable = true; 12 | 13 | this.bugSound = game.add.audio('bug'); 14 | this.blockSound = game.add.audio('block'); 15 | this.regularSound = game.add.audio('regular'); 16 | this.superSound = game.add.audio('super'); 17 | this.ultraSound = game.add.audio('ultra'); 18 | this.rollbackSound = game.add.audio('rollback'); 19 | 20 | groups.floor.add(this.sprite); 21 | }; 22 | 23 | Floor.prototype.constructor = Floor; 24 | 25 | Floor.prototype.getHeight = function() { 26 | var height = 640 - ((this.h * this.lines.length) + 20); 27 | if (height > 580) height = 580; 28 | return height; 29 | }; 30 | 31 | Floor.prototype.getLineHeight = function(line) { 32 | return 640 - (this.h * (line + 1)); 33 | }; 34 | 35 | Floor.prototype.addBlock = function(block, player) { 36 | var index = null, 37 | position = Math.floor(block.x / 40); 38 | 39 | for (var i = 0; i < this.lines.length; i++) { 40 | if (this.lines[i][position] === null) { 41 | index = i; 42 | break; 43 | } 44 | } 45 | 46 | if (index === null) { 47 | this.lines.push([null, null, null, null, null, null, null, null, null, null]); 48 | index = this.lines.length - 1; 49 | this.sprite.y = this.getHeight(); 50 | player.updateHeight(this); 51 | } 52 | 53 | block.settle(block.x, 640 - (40 * (index + 1))); 54 | if (block.isBug()) { 55 | this.bugSound.play(); 56 | } else { 57 | this.blockSound.play(); 58 | } 59 | this.lines[index][position] = block; 60 | return this.checkDeploy(index, player); 61 | }; 62 | 63 | Floor.prototype.checkDeploy = function(line, player) { 64 | var tryDeploy = true, 65 | deploy = null, 66 | self = this; 67 | 68 | for (var i = 0; i < 10; i++) { 69 | if (this.lines[line][i] === null) { 70 | tryDeploy = false; 71 | break; 72 | } 73 | } 74 | 75 | if (tryDeploy) { 76 | // perform deploy and score 77 | deploy = 0; 78 | var bugs = 0, 79 | score = 0, 80 | app = new Application(); 81 | 82 | for (var i = 0; i < 10; i++) { 83 | var block = this.lines[line][i]; 84 | score += block.language.points; 85 | app.addCode(block); 86 | } 87 | app.build(); 88 | score += app.bonus; 89 | 90 | var font = 'title', 91 | sizePoints = 32, 92 | sizeText = 20, 93 | sound = this.regularSound; 94 | if (app.bonus < 0) { 95 | font = 'rollback'; 96 | sizePoints = 28; 97 | score = 'No deploy'; 98 | sound = this.rollbackSound; 99 | } else { 100 | if (app.bonus === game.global.bonus.super) { 101 | font = 'super'; 102 | sound = this.superSound; 103 | sizePoints = 52; 104 | } else if (app.bonus === game.global.bonus.ultra) { 105 | font = 'ultra'; 106 | sound = this.ultraSound; 107 | sizePoints = 72; 108 | } 109 | 110 | game.global.score += score; 111 | deploy = score; 112 | 113 | // remove last line 114 | for (var i = 0; i < 10; i++) { 115 | var block = this.lines[line][i]; 116 | this.emitParticles(block.x, block.y); 117 | block.kill(); 118 | } 119 | 120 | // displace blocks 121 | for (var j = line; j < this.lines.length - 1; j++) { 122 | for (var i = 0; i < 10; i++) { 123 | this.lines[j][i] = this.lines[j + 1][i]; 124 | if (this.lines[j][i] !== null) { 125 | this.lines[j][i].displace(); 126 | } 127 | } 128 | } 129 | 130 | this.lines.pop(); 131 | this.sprite.y = this.getHeight(); 132 | player.updateHeight(this); 133 | } 134 | sound.play(); 135 | var appText = bitmapTextCentered(320, font, app.name, sizeText); 136 | var appTween = game.add.tween(appText); 137 | appTween.to({y: 230, alpha: 0}, 250, Phaser.Easing.Linear.None, true, 1500); 138 | 139 | var scoreText = bitmapTextCentered(250, font, String(score), sizePoints); 140 | var scoreTween = game.add.tween(scoreText); 141 | scoreTween.to({y: 160, alpha: 0}, 250, Phaser.Easing.Linear.None, true, 1500); 142 | } 143 | return deploy; 144 | }; 145 | 146 | Floor.prototype.emitParticles = function(x, y) { 147 | var emitter = game.add.emitter(x, y, 15); 148 | emitter.makeParticles('particle', 0, 25); 149 | emitter.minParticleSpeed.setTo(-100, -200); 150 | emitter.maxParticleSpeed.setTo(50, 100); 151 | //emitter.angularDrag = 10; 152 | emitter.start(true, 1000, null, 5); 153 | }; 154 | -------------------------------------------------------------------------------- /elements/hud.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var HUD = function(main) { 4 | this.main = main; 5 | this.speaker = game.add.sprite(340, 10, 'speaker', 0); 6 | this.score = game.add.bitmapText(15, 20, 'title', String(game.global.score), 32); 7 | }; 8 | 9 | HUD.prototype.constructor = HUD; 10 | 11 | HUD.prototype.update = function() { 12 | this.score.setText(String(game.global.score)); 13 | if (this.main.muted) { 14 | this.speaker.frame = 1; 15 | } else { 16 | this.speaker.frame = 0; 17 | } 18 | }; 19 | 20 | HUD.prototype.hide = function() { 21 | this.score.visible = false; 22 | this.speaker.visible = false; 23 | }; 24 | -------------------------------------------------------------------------------- /elements/instructions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Instructions = function() { 4 | this.step = 0; 5 | this.x1 = 130; 6 | this.x2 = 155; 7 | this.fontSize = 14; 8 | this.fontFamily = 'instructions'; 9 | this.enabled = true; 10 | this.rendered = false; 11 | }; 12 | 13 | Instructions.prototype.constructor = Instructions; 14 | 15 | Instructions.prototype.next = function(step) { 16 | if (!this.enabled) return; 17 | 18 | if (step) { 19 | this.step = step; 20 | } else { 21 | this.step += 1; 22 | } 23 | if (this.l1) this.l1.destroy(); 24 | if (this.l2) this.l2.destroy(); 25 | if (this.step < 10) { 26 | this.rendered = false; 27 | } else { 28 | this.poster.destroy(); 29 | this.enabled = false; 30 | } 31 | }; 32 | 33 | Instructions.prototype.setStep = function(step) { 34 | this.next(step); 35 | }; 36 | 37 | Instructions.prototype.createLabels = function(line1, line2) { 38 | this.l1 = bitmapTextCentered(this.x1, this.fontFamily, line1, this.fontSize); 39 | this.l2 = bitmapTextCentered(this.x2, this.fontFamily, line2, this.fontSize); 40 | //var tween = game.add.tween(this.l1); 41 | //tween.to({alpha: 100}, 1000, Phaser.Easing.Linear.None, true, 3000); 42 | //console.log('createLabels'); 43 | }; 44 | 45 | Instructions.prototype.update = function() { 46 | if (this.enabled && !this.rendered) { 47 | if (this.step === 0) { 48 | this.poster = game.add.image(0, 100, 'poster'); 49 | this.createLabels('Move with the arrows to', 'catch the block'); 50 | } else if (this.step === 1) { 51 | this.createLabels('Now press down to drop', 'the block into dev zone'); 52 | } else if (this.step === 2) { 53 | this.createLabels('Catch the new block and', 'drop it into the zone'); 54 | } else if (this.step === 3) { 55 | this.createLabels('Good! Horizontal lines', 'represent applications'); 56 | } else if (this.step === 4) { 57 | this.createLabels('Combine the blocks to', 'create popular apps'); 58 | } else if (this.step === 5) { 59 | this.createLabels('Popular apps will deploy,', 'giving you points'); 60 | } else if (this.step === 6) { 61 | this.createLabels('Unknown apps won\'t deploy,', 'making your code grow'); 62 | } else if (this.step === 7) { 63 | this.createLabels('If you reach the top of', 'the screen, you\'re fired'); 64 | } else if (this.step === 8) { 65 | this.createLabels('If you create buggy', 'apps, you\'re fired'); 66 | } else if (this.step === 9) { 67 | this.createLabels('That\'s all folks.', 'Good luck!'); 68 | } 69 | this.rendered = true; 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /elements/language.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Language = function() { 4 | this.index = Math.floor(Math.random() * 6); 5 | this.points = 10; 6 | this.name = ['rb', 'js', 'java', 'py', 'html', 'php'][this.index]; 7 | }; 8 | 9 | Language.prototype.constructor = Language; 10 | 11 | Language.prototype.isRuby = function() { 12 | return (this.index === 0) ? true : false; 13 | }; 14 | 15 | Language.prototype.isJavascript = function() { 16 | return (this.index === 1) ? true : false; 17 | }; 18 | 19 | Language.prototype.isJava = function() { 20 | return (this.index === 2) ? true : false; 21 | }; 22 | 23 | Language.prototype.isPython = function() { 24 | return (this.index === 3) ? true : false; 25 | }; 26 | 27 | Language.prototype.isHTML = function() { 28 | return (this.index === 4) ? true : false; 29 | }; 30 | 31 | Language.prototype.isPHP = function() { 32 | return (this.index === 5) ? true : false; 33 | }; 34 | 35 | Language.prototype.isBug = function() { 36 | return (this.index === 6) ? true : false; 37 | }; 38 | 39 | Language.prototype.addBug = function() { 40 | this.index = 6; 41 | this.points = -(this.points); 42 | this.name = 'bug'; 43 | }; 44 | -------------------------------------------------------------------------------- /elements/octocat.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Octocat = function(x, y, floor) { 4 | Phaser.Sprite.call(this, game, x + 20, y, 'octocat', 0); 5 | 6 | this.floor = floor; 7 | game.physics.arcade.enable(this); 8 | this.body.gravity.y = 1000; 9 | this.body.collideWorldBounds = true; 10 | this.body.setSize(40, 56, 20, 13); 11 | this.block = null; 12 | this.walking = false; 13 | this.walkingDelay = 0; 14 | this.newX = x; 15 | this.direction = null; 16 | this.maxSpeed = 1.2; 17 | this.minSpeed = 0.5; 18 | this.speed = 0.5; 19 | 20 | this.cursors = game.input.keyboard.createCursorKeys(); 21 | this.animations.add('main', [0, 1, 2, 3], 12, true); 22 | 23 | this.animations.play('main'); 24 | game.add.existing(this); 25 | }; 26 | 27 | Octocat.prototype = Object.create(Phaser.Sprite.prototype); 28 | Octocat.prototype.constructor = Octocat; 29 | 30 | Octocat.prototype.update = function() { 31 | game.physics.arcade.collide(this, groups.floor); 32 | 33 | if (this.walking && this.walkingDelay === 0) { 34 | var deltaX = game.time.elapsedMS * this.speed; 35 | if (this.direction === 'left') { 36 | this.walkLeft(deltaX); 37 | } else { 38 | this.walkRight(deltaX); 39 | } 40 | } else if (this.walking && this.walkingDelay > 0) { 41 | this.walkingDelay -= game.time.elapsedMS; 42 | if (this.walkingDelay <= 0) { 43 | this.walking = false; 44 | this.walkingDelay = 0; 45 | } 46 | } else { 47 | this.checkMovement(); 48 | } 49 | }; 50 | 51 | Octocat.prototype.checkMovement = function() { 52 | if (!this.alive) return; 53 | 54 | if (this.cursors.left.isDown) { 55 | if (this.body.x > 0) { 56 | this.newX = this.body.x - 40; 57 | this.direction = 'left'; 58 | } 59 | } else if (this.cursors.right.isDown) { 60 | if (this.body.x + 40 < 380) { 61 | this.newX = this.body.x + 40; 62 | this.direction = 'right'; 63 | } 64 | } 65 | 66 | this.walking = true; 67 | }; 68 | 69 | Octocat.prototype.walkLeft = function(deltaX) { 70 | this.body.x -= deltaX; 71 | if (this.block) this.block.x -= deltaX; 72 | if (this.body.x <= this.newX) { 73 | this.stopWalking(); 74 | } 75 | }; 76 | 77 | Octocat.prototype.walkRight = function(deltaX) { 78 | this.body.x += deltaX; 79 | if (this.block) this.block.x += deltaX; 80 | if (this.body.x >= this.newX) { 81 | this.stopWalking(); 82 | } 83 | }; 84 | 85 | Octocat.prototype.stopWalking = function() { 86 | this.body.x = this.newX; 87 | if (this.block) { 88 | this.block.x = this.newX; 89 | } 90 | this.walkingDelay = 20; 91 | }; 92 | 93 | Octocat.prototype.updateHeight = function(floor) { 94 | this.y = floor.getHeight() - 67; 95 | if (this.block) { 96 | this.block.y = this.y + 10; 97 | } 98 | }; 99 | 100 | Octocat.prototype.takeBlock = function(block) { 101 | this.block = block; 102 | this.block.falling = false; 103 | this.block.y = this.y + 12; 104 | this.block.x = this.body.x; 105 | }; 106 | 107 | Octocat.prototype.dropBlock = function() { 108 | if (this.walking) return null; 109 | 110 | var b = this.block; 111 | this.block = null; 112 | return b; 113 | }; 114 | 115 | Octocat.prototype.fire = function() { 116 | this.alive = false; 117 | this.animations.stop(); 118 | this.frame = 4; 119 | }; 120 | 121 | Octocat.prototype.incSpeed = function() { 122 | this.speed += 0.25; 123 | if (this.speed > this.maxSpeed) this.speed = this.maxSpeed; 124 | }; 125 | 126 | Octocat.prototype.decSpeed = function() { 127 | this.speed -= 0.25; 128 | if (this.speed < this.minSpeed) this.speed = this.minSpeed; 129 | }; 130 | -------------------------------------------------------------------------------- /elements/text.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function bitmapTextCentered(y, font, text, size) { 4 | var label = game.add.bitmapText(0, y, font, text, size); 5 | label.updateTransform(); 6 | label.x = (game.width - label.width) / 2; 7 | return label; 8 | } 9 | -------------------------------------------------------------------------------- /game.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var game = new Phaser.Game(400, 640, Phaser.AUTO, 'game'); 4 | game.global = { 5 | block: { 6 | spawn: 8000, 7 | speed: 600, 8 | minSpawn: 2000, 9 | minSpeed: 100, 10 | }, 11 | deploysToNextLevel: 2, 12 | movementsToNextLevel: 10, 13 | bugsToRollback: 4, 14 | score: 0, 15 | bonus: { 16 | ultra: 600, 17 | super: 300 18 | } 19 | } 20 | var debug = false; 21 | var groups = {}; 22 | 23 | game.state.add('boot', bootState); 24 | game.state.add('load', loadState); 25 | game.state.add('menu', menuState); 26 | game.state.add('play', playState); 27 | 28 | game.state.start('boot'); 29 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Octocoder 7 | 35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /octocoder-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-deploy.png -------------------------------------------------------------------------------- /octocoder-ingame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-ingame.png -------------------------------------------------------------------------------- /octocoder-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-menu.png -------------------------------------------------------------------------------- /octocoder-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-screenshot.png -------------------------------------------------------------------------------- /octocoder-todo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-todo.pdf -------------------------------------------------------------------------------- /octocoder-wip-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-wip-1.png -------------------------------------------------------------------------------- /octocoder-wip-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-wip-2.png -------------------------------------------------------------------------------- /octocoder-wip-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satanas/game-off-2015/517ba685c58479c562fbeda1eece6570fd1eb4e5/octocoder-wip-3.png -------------------------------------------------------------------------------- /states/boot.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var bootState = { 4 | preload: function() { 5 | game.load.image('progressbar', 'assets/images/progressbar.png'); 6 | game.load.bitmapFont('rollback', 'assets/fonts/press-start-rollback.png', 'assets/fonts/press-start-rollback.fnt'); 7 | }, 8 | 9 | create: function() { 10 | game.stage.backgroundColor = '#fff'; 11 | game.state.start('load'); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /states/instructions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var instructionsState = { 4 | create: function() { 5 | game.sound.stopAll(); 6 | game.add.image(0, 0, 'background'); 7 | var bg = this.game.add.graphics(0, 0); 8 | bg.beginFill(0x000000, 1); 9 | bg.drawRect(game.camera.x, game.camera.y, game.width, game.height); 10 | bg.alpha = 0.5; 11 | bg.endFill(); 12 | game.add.bitmapText(12, 60, 'instructions', 'Instructions', 20); 13 | game.add.bitmapText(15, 90, 'instructions', '1. Take the blocks of code that', 12); 14 | game.add.bitmapText(15, 105, 'instructions', ' fall from above', 12); 15 | game.add.bitmapText(15, 135, 'instructions', '2. Combine the blocks in lines', 12); 16 | game.add.bitmapText(15, 150, 'instructions', ' to create popular apps and', 12); 17 | game.add.bitmapText(15, 165, 'instructions', ' deploy them', 12); 18 | game.add.bitmapText(15, 195, 'instructions', '3. Missed blocks will become', 12); 19 | game.add.bitmapText(15, 210, 'instructions', ' bugs', 12); 20 | game.add.bitmapText(15, 240, 'instructions', '4. Unknown or buggy apps won\'t', 12); 21 | game.add.bitmapText(15, 255, 'instructions', ' be deployed', 12); 22 | game.add.bitmapText(15, 285, 'instructions', '5. If Octocat touch the top of', 12); 23 | game.add.bitmapText(15, 300, 'instructions', ' the screen, you\'re fired', 12); 24 | game.add.bitmapText(15, 330, 'instructions', '6. If an app has more than 4', 12); 25 | game.add.bitmapText(15, 345, 'instructions', ' bugs, you\'re fired', 12); 26 | game.add.bitmapText(12, 400, 'instructions', 'Controls', 20); 27 | game.add.bitmapText(15, 430, 'instructions', '* Arrows to move and drop', 12); 28 | game.add.bitmapText(15, 460, 'instructions', '* P to pause the game', 12); 29 | game.add.bitmapText(15, 490, 'instructions', '* M to mute the music', 12); 30 | bitmapTextCentered(game.height - 40, 'instructions', 'Press ENTER to continue', 12); 31 | 32 | var enterKey = game.input.keyboard.addKey(Phaser.Keyboard.ENTER); 33 | enterKey.onDown.addOnce(this.start, this); 34 | }, 35 | 36 | start: function() { 37 | game.state.start('play'); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /states/load.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var loadState = { 4 | preload: function() { 5 | bitmapTextCentered(240, 'rollback', 'Loading...', 20); 6 | 7 | var progressBar = game.add.sprite(100, 300, 'progressbar'); 8 | progressBar.anchor.setTo(0, 0.5); 9 | game.load.setPreloadSprite(progressBar); 10 | 11 | // Fonts 12 | game.load.bitmapFont('super', 'assets/fonts/press-start-super.png', 'assets/fonts/press-start-super.fnt'); 13 | game.load.bitmapFont('ultra', 'assets/fonts/press-start-ultra.png', 'assets/fonts/press-start-ultra.fnt'); 14 | game.load.bitmapFont('title', 'assets/fonts/press-start-title.png', 'assets/fonts/press-start-title.fnt'); 15 | game.load.bitmapFont('instructions', 'assets/fonts/press-start-instructions.png', 'assets/fonts/press-start-instructions.fnt'); 16 | 17 | // Sprites 18 | game.load.image('title', 'assets/images/title.png'); 19 | game.load.image('floor', 'assets/images/floor.png'); 20 | game.load.image('particle', 'assets/images/particle.png'); 21 | game.load.image('background', 'assets/images/background.png'); 22 | game.load.image('poster', 'assets/images/poster.png'); 23 | 24 | // Spritesheets 25 | game.load.spritesheet('octocat', 'assets/images/octocat.png', 80, 80); 26 | game.load.spritesheet('blocks', 'assets/images/blocks.png', 40, 40); 27 | game.load.spritesheet('speaker', 'assets/images/speaker.png', 48, 48); 28 | 29 | // Sounds 30 | game.load.audio('regular', 'assets/sounds/regular.wav'); 31 | game.load.audio('super', 'assets/sounds/super.wav'); 32 | game.load.audio('ultra', 'assets/sounds/ultra.wav'); 33 | game.load.audio('rollback', 'assets/sounds/rollback.wav'); 34 | game.load.audio('block', 'assets/sounds/block.wav'); 35 | game.load.audio('bug', 'assets/sounds/bug.wav'); 36 | game.load.audio('dead', 'assets/sounds/dead.wav'); 37 | 38 | // BGMs 39 | game.load.audio('normal-bgm', 'assets/sounds/korobeiniki-normal.mp3', 0.75, true); 40 | game.load.audio('fast-bgm', 'assets/sounds/korobeiniki-fast.mp3', 0.75, true); 41 | }, 42 | 43 | create: function() { 44 | game.state.start('menu'); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /states/menu.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var menuState = { 4 | create: function() { 5 | game.sound.stopAll(); 6 | game.add.image(0, 0, 'title'); 7 | bitmapTextCentered(game.height - 70, 'instructions', 'Press ENTER to start', 12); 8 | bitmapTextCentered(game.height - 20, 'instructions', 'Created by Wil Alvarez - @satanas82', 10); 9 | 10 | var enterKey = game.input.keyboard.addKey(Phaser.Keyboard.ENTER); 11 | enterKey.onDown.addOnce(this.start, this); 12 | }, 13 | 14 | start: function() { 15 | game.state.start('play'); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /states/play.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var playState = { 4 | create: function() { 5 | this.player = null; 6 | this.sceneDelay = 500; 7 | this.elapsed = game.global.block.spawn; 8 | this.blockSpawnTime = game.global.block.spawn; 9 | this.blockMoveTime = game.global.block.speed; 10 | this.level = 1; 11 | this.muted = false; 12 | this.paused = false; 13 | this.fastPaced = false; 14 | this.deploys = 0; 15 | this.movements = 0; 16 | this.pauseText = null; 17 | this.normalBgmSound = game.add.audio('normal-bgm'); 18 | this.fastBgmSound = game.add.audio('fast-bgm'); 19 | this.deadSound = game.add.audio('dead'); 20 | game.sound.stopAll(); 21 | 22 | game.add.image(0, 0, 'background'); 23 | game.global.time = 0; 24 | game.global.score = 0; 25 | 26 | groups.blocks = game.add.group(); 27 | groups.floor = game.add.group(); 28 | 29 | this.player = new Octocat(200, 515); 30 | this.floor = new Floor(); 31 | this.hud = new HUD(this); 32 | this.instructions = new Instructions(); 33 | 34 | this.currentHeight = this.floor.getHeight(); 35 | 36 | //Ingame shortcuts 37 | this.pauseKey = game.input.keyboard.addKey(Phaser.Keyboard.P); 38 | this.pauseKey.onUp.add(this.togglePause, this); 39 | 40 | this.muteKey = game.input.keyboard.addKey(Phaser.Keyboard.M); 41 | this.muteKey.onUp.add(this.muteGame, this); 42 | 43 | this.normalBgmSound.play('', 0, 0.75, true); 44 | }, 45 | 46 | update: function() { 47 | this.hud.update(); 48 | this.instructions.update(); 49 | this.elapsed += game.time.elapsedMS; 50 | 51 | if (this.player.alive && !this.paused) { 52 | if (this.elapsed >= this.blockSpawnTime) { 53 | this.elapsed = 0; 54 | var block = new Block(this.blockMoveTime); 55 | } 56 | 57 | var self = this; 58 | groups.blocks.forEach(function(block) { 59 | if (game.physics.arcade.intersects(self.player.body, block.body)) { 60 | if (block.falling && !self.player.walking) { 61 | // drop block if exist 62 | if (self.player.block) { 63 | self.dropBlock(self.player.dropBlock(), true); 64 | } 65 | self.player.takeBlock(block); 66 | if (self.movements === 0 && self.instructions.step === 0) { 67 | self.instructions.next(); 68 | } 69 | } 70 | } 71 | 72 | if (game.physics.arcade.intersects(groups.floor.children[0].body, block.body) && block.falling) { 73 | self.dropBlock(block, true); 74 | } 75 | }); 76 | 77 | if (this.player.cursors.down.isDown) { 78 | this.dropBlock(this.player.dropBlock()); 79 | } 80 | 81 | // check player's dead 82 | if (this.player.y <= 0) { 83 | this.finishGame('Deadline reached'); 84 | } 85 | } 86 | }, 87 | 88 | dropBlock: function(block, bug) { 89 | if (block !== null) { 90 | if (bug) { 91 | block.addBug(); 92 | } 93 | block.y = this.floor.sprite.y + 20; 94 | this.currentHeight = this.floor.getHeight(); 95 | var deployed = this.floor.addBlock(block, this.player); 96 | 97 | this.onDrop(); 98 | if (deployed !== null) { 99 | this.onDeploy(deployed); 100 | } 101 | } 102 | }, 103 | 104 | onDrop: function(block) { 105 | this.movements += 1; 106 | this.increaseDifficulty(); 107 | 108 | if (this.instructions.step >= 1) { 109 | this.instructions.next(); 110 | } 111 | }, 112 | 113 | onDeploy: function(value) { 114 | this.deploys += 1; 115 | if (value < 0) { 116 | this.finishGame('Too many bugs'); 117 | } 118 | if (this.level > 8 && !this.fastPaced) { 119 | this.normalBgmSound.fadeOut(500); 120 | this.fastBgmSound.play('', 0, 1.0, true); 121 | this.fastPaced = true; 122 | } 123 | }, 124 | 125 | increaseDifficulty: function() { 126 | if (this.movements >= game.global.movementsToNextLevel) { 127 | this.deploys = 0; 128 | this.movements = 0; 129 | this.level += 1; 130 | this.blockSpawnTime -= 500; 131 | this.blockMoveTime -= 50; 132 | this.player.incSpeed(); 133 | console.log('level', this.level); 134 | } 135 | 136 | var diff = this.floor.getHeight() - this.currentHeight; 137 | if (diff > 0) { 138 | this.player.decSpeed(); 139 | this.blockSpawnTime += 12.5 * diff; 140 | } else if (diff < 0) { 141 | this.player.incSpeed(); 142 | this.blockSpawnTime += 12.5 * diff; 143 | } 144 | 145 | // Do not exceed the limits 146 | if (this.blockSpawnTime < game.global.block.minSpawn) { 147 | this.blockSpawnTime = game.global.block.minSpawn; 148 | } 149 | if (this.blockMoveTime < game.global.block.minSpeed) { 150 | this.blockMoveTime = game.global.block.minSpeed; 151 | } 152 | }, 153 | 154 | pauseUpdate: function() { 155 | //if (this.paused) { 156 | //} 157 | }, 158 | 159 | togglePause: function() { 160 | this.paused = !this.paused; 161 | if (this.paused) { 162 | this.pauseText = bitmapTextCentered(270, 'title', 'Paused', 48); 163 | } else { 164 | this.pauseText.destroy(); 165 | this.pauseText = null; 166 | } 167 | game.paused = this.paused; 168 | }, 169 | 170 | restartGame: function() { 171 | game.state.start('play'); 172 | }, 173 | 174 | quitGame: function() { 175 | game.state.start('menu'); 176 | }, 177 | 178 | muteGame: function() { 179 | this.muted = !this.muted; 180 | 181 | if (this.muted) { 182 | this.normalBgmSound.stop(); 183 | this.fastBgmSound.stop(); 184 | } else { 185 | if (this.fastPaced){ 186 | this.fastBgmSound.play('', 0, 0.75, true); 187 | } else { 188 | this.normalBgmSound.play('', 0, 0.75, true); 189 | } 190 | } 191 | }, 192 | 193 | finishGame: function(subtitle) { 194 | groups.blocks.forEach(function(block) { 195 | block.falling = false; 196 | }); 197 | game.sound.stopAll(); 198 | this.hud.hide(); 199 | this.player.fire(); 200 | var bg = this.game.add.graphics(0, 0); 201 | bg.beginFill(0x000000, 1); 202 | bg.drawRect(game.camera.x, game.camera.y, game.width, game.height); 203 | bg.alpha = 0.3; 204 | bg.endFill(); 205 | 206 | bitmapTextCentered(200, 'rollback', "You're fired!", 29); 207 | bitmapTextCentered(250, 'rollback', subtitle, 20); 208 | bitmapTextCentered(320, 'instructions', "Your score: " + String(game.global.score), 18); 209 | bitmapTextCentered(390, 'instructions', "Enter to restart", 12); 210 | bitmapTextCentered(410, 'instructions', "Esc to exit", 12); 211 | 212 | var enterKey = game.input.keyboard.addKey(Phaser.Keyboard.ENTER); 213 | var escKey = game.input.keyboard.addKey(Phaser.Keyboard.ESC); 214 | enterKey.onDown.addOnce(this.restartGame, this); 215 | escKey.onDown.addOnce(this.quitGame, this); 216 | 217 | this.deadSound.play(); 218 | }, 219 | 220 | //render: function() { 221 | // game.debug.body(this.player); 222 | // //game.debug.bodyInfo(this.player, 10, 20); 223 | //} 224 | }; 225 | --------------------------------------------------------------------------------