diff --git a/game.js b/game.js index 553849b..7e03348 100644 --- a/game.js +++ b/game.js @@ -99,8 +99,17 @@ Sprite = function () { this.bridgesH = true; this.bridgesV = true; + // collidesWith determines the list of sprites that can interact with this sprite. + // Anything not in this list will just pass right through this sprite. this.collidesWith = []; + // getInterference returns a list of sprites that this sprite cannot spawn on top of. + // By default this is the same as collides with. The exception is that ships can + // collide with coins, but they can also spawn on top of coins. + this.getInterference = function () { + return this.collidesWith; + } + this.x = 0; this.y = 0; this.rot = 0; @@ -331,7 +340,9 @@ Sprite = function () { return trans; }; this.isClear = function () { - if (this.collidesWith.length == 0) return true; + interferesWith = this.getInterference(); + + if (interferesWith.length == 0) return true; var cn = this.currentNode; if (cn == null) { var gridx = Math.floor(this.x / GRID_SIZE); @@ -340,15 +351,15 @@ Sprite = function () { gridy = (gridy >= this.grid[0].length) ? 0 : gridy; cn = this.grid[gridx][gridy]; } - return (cn.isEmpty(this.collidesWith) && - cn.north.isEmpty(this.collidesWith) && - cn.south.isEmpty(this.collidesWith) && - cn.east.isEmpty(this.collidesWith) && - cn.west.isEmpty(this.collidesWith) && - cn.north.east.isEmpty(this.collidesWith) && - cn.north.west.isEmpty(this.collidesWith) && - cn.south.east.isEmpty(this.collidesWith) && - cn.south.west.isEmpty(this.collidesWith)); + return (cn.isEmpty(interferesWith) && + cn.north.isEmpty(interferesWith) && + cn.south.isEmpty(interferesWith) && + cn.east.isEmpty(interferesWith) && + cn.west.isEmpty(interferesWith) && + cn.north.east.isEmpty(interferesWith) && + cn.north.west.isEmpty(interferesWith) && + cn.south.east.isEmpty(interferesWith) && + cn.south.west.isEmpty(interferesWith)); }; this.wrapPostMove = function () { if (this.x > Game.canvasWidth) { @@ -381,7 +392,29 @@ Ship = function () { this.postMove = this.wrapPostMove; - this.collidesWith = ["asteroid", "bigalien", "alienbullet"]; + this.collidesWith = ["asteroid", "bigalien", "alienbullet", "coin"]; + this.getInterference = function () { + return ["asteroid", "bigalien", "alienbullet"]; + } + + this.shoot = function() { + for (var i = 0; i < this.bullets.length; i++) { + if (!this.bullets[i].visible) { + SFX.laser(); + var bullet = this.bullets[i]; + var rad = ((this.rot-90) * Math.PI)/180; + var vectorx = Math.cos(rad); + var vectory = Math.sin(rad); + // move to the nose of the ship + bullet.x = this.x + vectorx * 4; + bullet.y = this.y + vectory * 4; + bullet.vel.x = 6 * vectorx + this.vel.x; + bullet.vel.y = 6 * vectory + this.vel.y; + bullet.visible = true; + break; + } + } + } this.preMove = function (delta) { if (KEY_STATUS.left) { @@ -409,22 +442,7 @@ Ship = function () { if (KEY_STATUS.space) { if (this.delayBeforeBullet <= 0) { this.delayBeforeBullet = 10; - for (var i = 0; i < this.bullets.length; i++) { - if (!this.bullets[i].visible) { - SFX.laser(); - var bullet = this.bullets[i]; - var rad = ((this.rot-90) * Math.PI)/180; - var vectorx = Math.cos(rad); - var vectory = Math.sin(rad); - // move to the nose of the ship - bullet.x = this.x + vectorx * 4; - bullet.y = this.y + vectory * 4; - bullet.vel.x = 6 * vectorx + this.vel.x; - bullet.vel.y = 6 * vectory + this.vel.y; - bullet.visible = true; - break; - } - } + this.shoot(); } } @@ -436,13 +454,15 @@ Ship = function () { }; this.collision = function (other) { - SFX.explosion(); - Game.explosionAt(other.x, other.y); - Game.FSM.state = 'player_died'; - this.visible = false; - this.currentNode.leave(this); - this.currentNode = null; - Game.lives--; + if (other.name != 'coin') { + SFX.explosion(); + Game.explosionAt(other.x, other.y); + Game.FSM.state = 'player_died'; + this.visible = false; + this.currentNode.leave(this); + this.currentNode = null; + Game.lives--; + } }; }; @@ -654,23 +674,26 @@ Asteroid = function () { this.collidesWith = ["ship", "bullet", "bigalien", "alienbullet"]; + this.breakIntoFragments = function () { + for (var i = 0; i < 3; i++) { + var roid = $.extend(true, {}, this); + roid.vel.x = Math.random() * 6 - 3; + roid.vel.y = Math.random() * 6 - 3; + if (Math.random() > 0.5) { + roid.points.reverse(); + } + roid.vel.rot = Math.random() * 2 - 1; + roid.move(roid.scale * 3); // give them a little push + Game.sprites.push(roid); + } + } + this.collision = function (other) { SFX.explosion(); if (other.name == "bullet") Game.score += 120 / this.scale; this.scale /= 3; if (this.scale > 0.5) { - // break into fragments - for (var i = 0; i < 3; i++) { - var roid = $.extend(true, {}, this); - roid.vel.x = Math.random() * 6 - 3; - roid.vel.y = Math.random() * 6 - 3; - if (Math.random() > 0.5) { - roid.points.reverse(); - } - roid.vel.rot = Math.random() * 2 - 1; - roid.move(roid.scale * 3); // give them a little push - Game.sprites.push(roid); - } + this.breakIntoFragments(); } Game.explosionAt(other.x, other.y); this.die(); @@ -678,6 +701,41 @@ Asteroid = function () { }; Asteroid.prototype = new Sprite(); +Coin = function () { + this.init("coin", + [-5, 0, + 0, 5, + 5, 0, + 0, -5]); + + this.collidesWith = ["ship"]; + + this.newPosition = function () { + this.x = Math.random() * Game.canvasWidth; + this.y = Math.random() * Game.canvasHeight; + }; + + this.newValue = function () { + this.value = Math.floor(Math.random() * 10 + 1) * 10; + } + + this.setup = function () { + this.newPosition(); + this.newValue(); + }; + + this.collision = function (other) { + Game.score += this.value; + SFX.explosion(); + this.visible = false; + Game.nextCoinTime = Date.now() + (10000 * Math.random()); + this.newPosition(); + this.newValue(); + } + +} +Coin.prototype = new Sprite(); + Explosion = function () { this.init("explosion"); @@ -881,6 +939,7 @@ Game = { bigAlien: null, nextBigAlienTime: null, + nextCoinTime: null, spawnAsteroids: function (count) { @@ -940,6 +999,7 @@ Game = { Game.spawnAsteroids(); Game.nextBigAlienTime = Date.now() + 30000 + (30000 * Math.random()); + Game.nextCoinTime = Date.now() + 2000 + (10000 * Math.random()); this.state = 'spawn_ship'; }, @@ -968,6 +1028,10 @@ Game = { Game.bigAlien.visible = true; Game.nextBigAlienTime = Date.now() + (30000 * Math.random()); } + if (!Game.coin.visible && + Date.now() > Game.nextCoinTime) { + Game.coin.visible = true; + } }, new_level: function () { if (this.timer == null) { @@ -1095,6 +1159,11 @@ $(function () { extraDude.preMove = null; extraDude.children = []; + var coin = new Coin(); + coin.setup(); + sprites.push(coin); + Game.coin = coin; + var i, j = 0; var showFramerate = false; var avgFramerate = 0;