Jelajahi Sumber

Feature: add 2 kinds of aliens
Refactoring: better way to manage aliens
Refatcoring: creating models and animations folders to manage independent files

Fabrice Ecaille 12 tahun lalu
induk
melakukan
dbef43e61b

TEMPAT SAMPAH
images/invader.png


+ 10 - 2
index.html

@@ -23,10 +23,18 @@
 		<link href="css/scoreboard.css" type="text/css" rel="stylesheet"/>
 		<link href="css/countdown.css" type="text/css" rel="stylesheet"/>
 		
-		<script src="js/spaceinvaders-animations.js" type="text/javascript" ></script>
+		<script src="js/animations/animations.js" type="text/javascript" ></script>
+		<script src="js/animations/aliens.js" type="text/javascript" ></script>
+		<script src="js/animations/explosions.js" type="text/javascript" ></script>
+		<script src="js/animations/worlds.js" type="text/javascript" ></script>
+
 		<script src="js/spaceinvaders-ui.js" type="text/javascript" ></script>
 		<script src="js/spaceinvaders-core.js" type="text/javascript" ></script>
-		<script src="js/spaceinvaders-models.js" type="text/javascript" ></script>
+		<script src="js/spaceinvaders-utils.js" type="text/javascript" ></script>
+		<script src="js/models/models.js" type="text/javascript" ></script>
+		<script src="js/models/aliens.js" type="text/javascript" ></script>
+		<script src="js/models/waves.js" type="text/javascript" ></script>
+		<script src="js/models/weapons.js" type="text/javascript" ></script>
 
 		<link href="css/spaceinvaders.css" type="text/css" rel="stylesheet"/>		
 	</head>

+ 45 - 0
js/animations/aliens.js

@@ -0,0 +1,45 @@
+var 	ALIENS_WIDTH = 25,
+	ALIENS_WIDTH_2 = 18,
+	ALIENS_HEIGHT = 17,
+	ALIENS_SPRITE = IMAGES_PREFIX + "invader.png",
+	ALIENS_RATE = 400;
+
+var ALIENS_TYPE = [
+	{
+		animation : new $.gQ.Animation({
+			imageURL : ALIENS_SPRITE,
+			numberOfFrame : 2,
+			delta : 24,
+			rate : ALIENS_RATE,
+			type : $.gQ.ANIMATION_HORIZONTAL
+		}),
+		width : 24,
+		height: 18
+	},
+	{
+		animation : new $.gQ.Animation({
+			imageURL : ALIENS_SPRITE,
+			numberOfFrame : 2,
+			delta : ALIENS_WIDTH_2,
+			offsety : 20,
+			rate : ALIENS_RATE,
+			type : $.gQ.ANIMATION_HORIZONTAL
+		}),
+		width : ALIENS_WIDTH_2,
+		height: 17
+	},
+	{
+		animation : new $.gQ.Animation({
+			imageURL : ALIENS_SPRITE,
+			numberOfFrame : 2,
+			delta : ALIENS_WIDTH,
+			offsety : 40,
+			rate : ALIENS_RATE,
+			type : $.gQ.ANIMATION_HORIZONTAL
+		}),
+		width : ALIENS_WIDTH,
+		height: 18
+	}
+]
+
+

+ 11 - 0
js/animations/animations.js

@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2013 Fabrice ECAILLE aka Febbweiss
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+var	IMAGES_PREFIX = "images/";

+ 117 - 0
js/animations/explosions.js

@@ -0,0 +1,117 @@
+var	EXPLOSION_BIG = IMAGES_PREFIX + "explosion_big.png",
+	EXPLOSION_BIG_RATE = 50,
+	EXPLOSION_SMALL = IMAGES_PREFIX + "explosion_small.png",
+	EXPLOSION_SMALL_RATE = 50;
+
+var EXPLOSIONS = {
+	BIG : [
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 128,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 256,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 384,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 512,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 640,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 768,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK | $.gQ.ANIMATION_ONCE
+			}),
+			width : 128,
+			height: 128
+		},
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_BIG,
+				offsety : 896,
+				numberOfFrame : 8,
+				delta : 128,
+				rate : EXPLOSION_BIG_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK | $.gQ.ANIMATION_ONCE
+			}),
+			width : 128,
+			height: 128
+		}
+	],
+	SMALL : [
+		{
+			animation : new $.gQ.Animation({
+				imageURL : EXPLOSION_SMALL,
+				numberOfFrame : 10,
+				delta : 64,
+				rate : EXPLOSION_SMALL_RATE,
+				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK  | $.gQ.ANIMATION_ONCE
+			}),
+			width : 64,
+			height: 64
+		}
+	]
+}

+ 121 - 0
js/animations/worlds.js

@@ -0,0 +1,121 @@
+var FARM_SPRITE = IMAGES_PREFIX + "farm.png",
+	FARM_BACKGROUND_1 = IMAGES_PREFIX + "background.png",
+	FARM_BACKGROUND_2 = IMAGES_PREFIX + "background2.png";
+
+var WORLD = {
+	farm : {
+		hero : {
+			ship : {
+				animation : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE
+				}),
+				width : 48,
+				height : 24,
+				posx : 0,
+				posy : 17
+			},
+			/*cockpit : {
+				animation : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsety : 24,
+					offsetx : 20
+				}),
+				width : 20,
+				height : 33,
+				posx : 28,
+				posy : 3
+			},*/
+			smallWheel : {
+				animation  : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsetx : 0,
+					offsety : 24
+				}),
+				posx : 4,
+				posy : 30,
+				width: 14,
+				height: 14
+			},
+			bigWheel : {
+				animation  : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsetx : 0,
+					offsety : 38
+				}),
+				width : 19,
+				height : 19,
+				posx : 25,
+				posy : 27
+			}
+		},
+		alien : {
+			animation : new $.gQ.Animation({
+				imageURL : IMAGES_PREFIX + "invader.png",
+				numberOfFrame : 2,
+				delta : ALIENS_WIDTH,
+				rate : 400,
+				type : $.gQ.ANIMATION_HORIZONTAL
+			}),
+			width : ALIENS_WIDTH,
+			height : ALIENS_HEIGHT			
+		},
+		ufo : {
+			animation: new $.gQ.Animation({imageURL: IMAGES_PREFIX + "ufo.png"}), 
+			width: 48, 
+			height: 32,
+			posy: 10
+		},
+		life : {
+			animation : new $.gameQuery.Animation({
+				imageURL : FARM_SPRITE,
+				offsetx : 14,
+				offsety : 24
+			}),
+			width: 32,
+			height: 16
+		},
+		weapons : {
+			corn : {
+				animation : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsetx : 19,
+					offsety : 37
+				}),
+				width: 19,
+				height: 19
+			},
+			carot : {
+				animation : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsetx : 38,
+					offsety : 37
+				}),
+				width: 19,
+				height: 19
+			},
+			gun : {
+				animation : new $.gameQuery.Animation({
+					imageURL : FARM_SPRITE,
+					offsetx : 57,
+					offsety : 37
+				}),
+				width: 19,
+				height: 19
+			}
+		},
+		backgrounds : {
+			farm: {
+				background1 : {
+					animation : new $.gQ.Animation({
+						imageURL : FARM_BACKGROUND_1
+					})
+				},
+				background2 : {
+					animation : new $.gQ.Animation({
+						imageURL : FARM_BACKGROUND_2
+					})
+				}
+			}
+		}	
+	}
+};

+ 81 - 0
js/models/aliens.js

@@ -0,0 +1,81 @@
+var ALIENS = {
+	alien1 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 5,
+		aggression : 0.0005,
+		animation : ALIENS_TYPE[0]
+	},
+	alien2 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 10,
+		aggression : 0.001,
+		animation : ALIENS_TYPE[1]
+	},
+	alien3 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 20,
+		aggression : 0.0015,
+		animation : ALIENS_TYPE[2]
+	}
+}
+
+
+/*** Actors - Aliens ***/
+function Alien(id, start, move, type) {
+	"use strict";
+
+	this.id = id;
+	this.x = start.x;
+	this.y = start.y;
+	this.moveFct = move;
+
+	this.weapon = new type.weapon();
+	this.fireDirectionY = 1;
+
+	this.originX = this.x;
+	this.originY = this.y;
+	this.directionX = -1;
+	this.speed = 0.5;
+	this.animation = type.animation;
+	this.width = type.animation.width;
+	this.height = type.animation.height;
+	this.health = type.health;
+	this.aggression = type.aggression;
+	this.score = type.score;
+}
+
+Alien.prototype = {
+	moveFct : null,
+	width : 0,
+	height : 0,
+	aggression : 0,
+	animation : null,
+	score : 0,
+
+	init : function() {
+		"use strict";
+		this.speed = 0;
+		this.node.x(this.x);
+		this.node.y(this.y);
+	},
+
+	move : function() {
+		"use strict";
+		this._super("move", arguments);
+		if (typeof this.moveFct !== undefined) {
+			this.moveFct();
+		}
+	},
+	
+	destroy : function() {
+		this._super("destroy", arguments);
+		Game.addToScore( this.score );
+	}
+};
+
+heriter(Alien.prototype, Actor.prototype);
+
+/*** Actors - Aliens - END ***/

+ 45 - 11
js/spaceinvaders-models.js → js/models/models.js

@@ -153,15 +153,41 @@ var MOVE = {
 
 /*** Move - end ***/
 
+var ALIENS = {
+	alien1 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 5,
+		aggression : 0.0005,
+		animation : ALIENS_TYPE[0]
+	},
+	alien2 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 10,
+		aggression : 0.001,
+		animation : ALIENS_TYPE[1]
+	},
+	alien3 : {
+		health : 1,
+		weapon : AlienWeapon,
+		score : 20,
+		aggression : 0.0015,
+		animation : ALIENS_TYPE[2]
+	}
+}
+
+
 /*** Waves ***/
 
 var WAVES = [
 		{
-			wave : [ [ Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien ],
-				 [ Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien ],
-				 [ Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien ],
-				 [ Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien ],
-				 [ Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien, Alien ]
+			wave : [ 
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ]
 			],
 			move : MOVE.translation,
 			bonus : [40, 20]
@@ -444,7 +470,7 @@ Actor.prototype = {
 };
 
 /*** Actors - Aliens ***/
-function Alien(id, start, move) {
+function Alien(id, start, move, type) {
 	"use strict";
 
 	this.id = id;
@@ -452,20 +478,28 @@ function Alien(id, start, move) {
 	this.y = start.y;
 	this.moveFct = move;
 
-	this.weapon = new AlienWeapon();
+	this.weapon = new type.weapon();
 	this.fireDirectionY = 1;
 
 	this.originX = this.x;
 	this.originY = this.y;
 	this.directionX = -1;
 	this.speed = 0.5;
+	this.animation = type.animation;
+	this.width = type.animation.width;
+	this.height = type.animation.height;
+	this.health = type.health;
+	this.aggression = type.aggression;
+	this.score = type.score;
 }
 
 Alien.prototype = {
 	moveFct : null,
-	width : ALIENS_WIDTH,
-	height : ALIENS_HEIGHT,
-	aggression : 0.0005,
+	width : 0,
+	height : 0,
+	aggression : 0,
+	animation : null,
+	score : 0,
 
 	init : function() {
 		"use strict";
@@ -484,7 +518,7 @@ Alien.prototype = {
 	
 	destroy : function() {
 		this._super("destroy", arguments);
-		Game.addToScore( 5 );
+		Game.addToScore( this.score );
 	}
 };
 

+ 173 - 0
js/models/waves.js

@@ -0,0 +1,173 @@
+/*** Move ***/
+
+var MOVE = {
+	translation : {
+		init : function (x, y) {
+			return {directionX : 1, directionY : 0};
+		},
+		move : function() {
+			var offset = (PLAYGROUND_WIDTH - 16 * this.width) / 2;
+			if (Math.abs((this.getOriginX() - this.getX())) >= offset) {
+				this.directionX *= -1;
+				this.y = (this.y + this.height / 4);
+			}
+		},
+	},
+	mirror : {
+		init : function(x, y) {
+			if( x < PLAYGROUND_WIDTH / 2 ) {
+				return {directionX: -1, directionY: 0};
+			}
+			return {directionX: 1, directionY: 0};
+		},
+		move : function() {
+			var offset =  this.width / 2;
+			if (Math.abs((this.getOriginX() - this.getX())) >= offset) {
+				this.directionX *= -1;
+				this.y = (this.y + this.height / 4);
+			}
+		},
+	},
+	half_part_rotation : {
+		init : function (x, y) {
+			return {directionX:0, directionY:0};
+		},
+		move : function () {
+			var 	_this = $(this)[0],
+				mid = PLAYGROUND_WIDTH / 2,
+				center = _this.center, 
+				width = _this.width;
+
+			if( this.directionX == 0 && this.directionY == 0 ) {
+				center = {x: ( this.getOriginX() < mid ? PLAYGROUND_WIDTH / 4 : 3 * PLAYGROUND_WIDTH / 4), y: getAliensMidHeight() };
+				width = distance(center, {x: this.x, y: this.y});
+				var	xAxis = {x: width, y: 0}, 
+					current = {x: center.x - this.getOriginX(), y: center.y - this.getOriginY()},
+					alpha = angle( xAxis, current );
+				this.directionX = 0.01;
+				this.directionY = alpha;
+				$(this)[0].center = center;
+				$(this)[0].width = width;
+			}
+				
+			if( this.getOriginX() < mid ) {
+				this.directionY = this.directionY + this.directionX;
+			} else {
+				this.directionY = this.directionY - this.directionX;
+			}
+			if( Math.abs(this.directionY) > 2 * Math.PI ) {
+				this.directionY = 0;
+			}
+			center.y = center.y + 0.1;
+			_this.center = center;
+			this.x = center.x + width * Math.cos(this.directionY);
+			this.y = center.y + width * Math.sin(this.directionY);
+		}
+	},
+
+	rotation : {
+		init : function (x, y) {
+			return {directionX:0, directionY:0};
+		},
+		move : function () {
+			var 	_this = $(this)[0],
+				mid = PLAYGROUND_WIDTH / 2,
+				center = _this.center, 
+				width = _this.width;
+
+			if( this.directionX == 0 && this.directionY == 0 ) {
+				center = {x: mid, y: getAliensMidHeight() };
+				width = distance(center, {x: this.x, y: this.y});
+				var	xAxis = {x: width, y: 0}, 
+					current = {x: center.x - this.getOriginX(), y: center.y - this.getOriginY()},
+					alpha = angle( xAxis, current );
+				this.directionX = 0.01;
+				this.directionY = alpha;
+				$(this)[0].center = center;
+				$(this)[0].width = width;
+			}
+				
+			this.directionY = this.directionY - this.directionX;
+			if( Math.abs(this.directionY) > 2 * Math.PI ) {
+				this.directionY = 0;
+			}
+			center.y = center.y + 0.1;
+			_this.center = center;
+			this.x = center.x + width * Math.cos(this.directionY);
+			this.y = center.y + width * Math.sin(this.directionY);
+		}
+	},
+	
+	sinusoid : {
+		init : function (x, y) {
+			return {directionX : 1, directionY : 1};
+		},
+		move : function () {
+			var offset = this.width / 2;
+			if (Math.abs((this.getOriginX() - this.getX())) >= offset) {
+				this.directionX *= -1;
+			}
+			
+			if( Math.abs(this.getOriginY() - this.getY()) >= 3 * this.height ) {
+				this.directionY *= -1;
+			}
+		}
+	}
+};
+
+/*** Move - end ***/
+
+
+/*** Waves ***/
+
+var WAVES = [
+		{
+			wave : [ 
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3, ALIENS.alien3 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ],
+				 [ ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1, ALIENS.alien1 ]
+			],
+			move : MOVE.translation,
+			bonus : [40, 20]
+		},
+		{
+			wave : [ [ Alien, Alien, Alien, undefined, Alien, Alien, Alien ], 
+				 [ Alien, Alien, Alien, Alien, undefined, Alien, Alien, Alien ],
+				 [ Alien, Alien, Alien, Alien, undefined, Alien, Alien, Alien, Alien ],
+				 [ Alien, Alien, Alien, Alien, undefined, Alien, Alien, Alien, Alien, Alien ],
+				 [ Alien, Alien, Alien, Alien, Alien, undefined, Alien, Alien, Alien, Alien, Alien ] 
+			],
+			move : MOVE.mirror,
+			bonus : [30, 15]
+		}, 
+		{
+			wave : [ [ undefined, undefined, Alien, undefined, undefined, undefined, undefined, undefined, Alien, undefined, undefined ],
+				 [ undefined, Alien, Alien, Alien, undefined, undefined, undefined, Alien, Alien, Alien, undefined ],
+				 [ Alien, Alien, undefined, Alien, Alien, undefined, Alien, Alien, undefined, Alien, Alien ],
+				 [ undefined, Alien, Alien, Alien, Alien, undefined, undefined, Alien, Alien, Alien, undefined ],
+				 [ undefined, undefined, Alien, undefined, undefined, undefined, undefined, undefined, Alien, undefined, undefined ]
+			],
+			move : MOVE.half_part_rotation,
+			bonus : [20, 10]
+		},
+		{
+			wave : [ 
+				[ undefined, undefined, undefined, undefined, Alien, undefined, undefined, undefined, undefined ],
+				[ undefined, undefined, undefined, Alien, Alien, Alien, undefined, undefined, undefined ],
+				[ undefined, Alien, Alien, Alien, undefined, Alien, Alien, Alien, undefined ],
+				[ undefined, Alien, Alien, Alien, undefined, Alien, Alien, Alien, undefined ],
+				[ Alien, Alien, Alien, undefined, undefined, undefined, Alien, Alien, Alien ],
+				[ undefined, Alien, Alien, Alien, undefined, Alien, Alien, Alien, undefined ],
+				[ undefined, Alien, Alien, Alien, undefined, Alien, Alien, Alien, undefined ],
+				[ undefined, undefined, undefined, Alien, Alien, Alien, undefined, undefined, undefined ],
+				[ undefined, undefined, undefined, undefined, Alien, undefined, undefined, undefined, undefined ]
+			],
+			move : MOVE.rotation,
+			bonus : [25, 12]
+		}
+	];
+
+
+/*** Waves - end ***/

+ 139 - 0
js/models/weapons.js

@@ -0,0 +1,139 @@
+/*** Weapons ***/
+
+function Weapon() {
+	"use strict";
+}
+Weapon.prototype = {
+	speed : 5,
+	strength : 10,
+	stock: Infinity,
+	rof : 300,
+	ror : 1500,
+	load : 1,
+	max_load : 1,
+	width : 5,
+	height : 5,
+	shot_timer : false,
+	reload_timer : false,
+	directionX : 0,
+	directionY : 1,
+	animation : null,
+	clazz : "default",
+	callback : undefined,
+
+	fire : function() {
+		if (this.shot_timer || this.load <= 0) {
+			return false;
+		}
+		
+		var _this = this;
+		this.load = Math.max(0,this.load - 1);
+		this.shot_timer = setInterval(function() {
+			if (_this.load > 0) {
+				clearTimeout(_this.shot_timer);
+				_this.shot_timer = false;
+			}
+		}, this.rof);
+		
+		if( !this.reload_timer) {
+			this.reload_timer = setInterval( function() {
+				_this.load = Math.min(_this.load + 1, Math.min(_this.max_load, _this.stock));
+				if( _this.load == _this.max_load ) {
+					clearInterval(_this.reload_timer);
+					_this.reload_timer = false;
+				}
+			}, this.ror);
+		}
+		return true;
+	}
+
+}
+
+function ShotgunWeapon() {
+	"use strict";
+	this.directionY = -1;
+	this.rof = 200;
+	this.ror = 1500;
+	this.load = 2;
+	this.max_load = 2;
+	this.width = 3;
+	this.height = 3;
+	this.clazz = "Shotgun"
+}
+ShotgunWeapon.prototype = {
+}
+heriter(ShotgunWeapon.prototype, Weapon.prototype);
+
+function CarotWeapon() {
+	"use strict";
+	this.directionY = -1;
+	this.stock = 10;
+	this.clazz = "carot";
+	this.load = 5;
+	this.max_load = 5;
+	this.width = 5;
+	this.height = 10;
+}
+CarotWeapon.prototype = {
+		
+}
+heriter(CarotWeapon.prototype, Weapon.prototype);
+
+function CornWeapon() {
+	"use strict";
+	this.directionY = -1;
+	this.stock = 3;
+	this.clazz = "corn";
+	this.load = 1;
+	this.max_load = 1;
+	this.callback = function(shot) {
+		var mediumAlien = getAliensMidHeight();
+		
+		if( shot.y() < mediumAlien ) {
+			var 	x = shot.x(),
+				y = shot.y(),
+				explosion = EXPLOSIONS.SMALL[0];
+			$("#shipShots").addSprite("cornExplosion", {width: explosion.width, height: explosion.height, posx: x - explosion.width / 2, posy: y - explosion.height / 2});
+			explosionSmall($("#cornExplosion"), function() {$("#cornExplosion").remove()});
+			shot.remove();
+
+			var shipShots = $("#shipShots");
+			for( var i = 0; i < 8; i++) {
+				var cos = Math.cos( (Math.PI / 4) * i ),
+					sin = Math.sin( (Math.PI / 4) * i);
+				if( Math.abs(cos) < 0.01 ) {
+					cos = 0;
+				}
+				if( Math.abs(sin) < 0.01) {
+					sin = 0;
+				}
+				shipShots.addSprite( "shotCorn" + i, { posx : x + 5 * cos, posy : y + 5 * sin, width: 2, height: 2});
+				var shotCorn = $("#shotCorn" + i);
+				shotCorn.addClass("shipShot").addClass("shotCorn");
+				$("#shotCorn" + i)[0].weapon = $.extend({
+						directionX : cos < 0 ? -1 : cos > 0 ? 1 : 0,
+						directionY : sin < 0 ? -1 : sin > 0 ? 1 : 0,
+						speed : 1
+					}, shot.weapon); 
+			}
+		}
+	}
+}
+CornWeapon.prototype = {
+		
+}
+heriter(CornWeapon.prototype, Weapon.prototype);
+
+
+function AlienWeapon() {
+	"use strict";
+	this.directionY = 1;
+	this.width = 5;
+	this.height = 10;
+}
+AlienWeapon.prototype = {
+		
+}
+heriter(AlienWeapon.prototype, Weapon.prototype);
+/*** Weapons -END ***/
+

+ 0 - 248
js/spaceinvaders-animations.js

@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2013 Fabrice ECAILLE aka Febbweiss
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-var 	ALIENS_WIDTH = 24,
-	ALIENS_HEIGHT = 17,
-	IMAGES_PREFIX = "images/",
-	EXPLOSION_BIG = IMAGES_PREFIX + "explosion_big.png",
-	EXPLOSION_BIG_RATE = 50,
-	EXPLOSION_SMALL = IMAGES_PREFIX + "explosion_small.png",
-	EXPLOSION_SMALL_RATE = 50;
-
-var EXPLOSIONS = {
-	BIG : [
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 128,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 256,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 384,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 512,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 640,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 768,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK | $.gQ.ANIMATION_ONCE
-			}),
-			width : 128,
-			height: 128
-		},
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_BIG,
-				offsety : 896,
-				numberOfFrame : 8,
-				delta : 128,
-				rate : EXPLOSION_BIG_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK | $.gQ.ANIMATION_ONCE
-			}),
-			width : 128,
-			height: 128
-		}
-	],
-	SMALL : [
-		{
-			animation : new $.gQ.Animation({
-				imageURL : EXPLOSION_SMALL,
-				numberOfFrame : 10,
-				delta : 64,
-				rate : EXPLOSION_SMALL_RATE,
-				type : $.gQ.ANIMATION_HORIZONTAL | $.gQ.ANIMATION_CALLBACK  | $.gQ.ANIMATION_ONCE
-			}),
-			width : 64,
-			height: 64
-		}
-	]
-}
-var WORLD = {
-	farm : {
-		hero : {
-			ship : {
-				animation : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png"
-				}),
-				width : 48,
-				height : 24,
-				posx : 0,
-				posy : 17
-			},
-			/*cockpit : {
-				animation : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsety : 24,
-					offsetx : 20
-				}),
-				width : 20,
-				height : 33,
-				posx : 28,
-				posy : 3
-			},*/
-			smallWheel : {
-				animation  : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsetx : 0,
-					offsety : 24
-				}),
-				posx : 4,
-				posy : 30,
-				width: 14,
-				height: 14
-			},
-			bigWheel : {
-				animation  : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsetx : 0,
-					offsety : 38
-				}),
-				width : 19,
-				height : 19,
-				posx : 25,
-				posy : 27
-			}
-		},
-		alien : {
-			animation : new $.gQ.Animation({
-				imageURL : IMAGES_PREFIX + "invader.png",
-				numberOfFrame : 2,
-				delta : ALIENS_WIDTH,
-				rate : 400,
-				type : $.gQ.ANIMATION_HORIZONTAL
-			}),
-			width : ALIENS_WIDTH,
-			height : ALIENS_HEIGHT			
-		},
-		ufo : {
-			animation: new $.gQ.Animation({imageURL: IMAGES_PREFIX + "ufo.png"}), 
-			width: 48, 
-			height: 32,
-			posy: 10
-		},
-		life : {
-			animation : new $.gameQuery.Animation({
-				imageURL : IMAGES_PREFIX + "farm.png",
-				offsetx : 14,
-				offsety : 24
-			}),
-			width: 32,
-			height: 16
-		},
-		weapons : {
-			corn : {
-				animation : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsetx : 19,
-					offsety : 37
-				}),
-				width: 19,
-				height: 19
-			},
-			carot : {
-				animation : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsetx : 38,
-					offsety : 37
-				}),
-				width: 19,
-				height: 19
-			},
-			gun : {
-				animation : new $.gameQuery.Animation({
-					imageURL : IMAGES_PREFIX + "farm.png",
-					offsetx : 57,
-					offsety : 37
-				}),
-				width: 19,
-				height: 19
-			}
-		},
-		backgrounds : {
-			farm: {
-				background1 : {
-					animation : new $.gQ.Animation({
-						imageURL : IMAGES_PREFIX + "background.png"
-					})
-				},
-				background2 : {
-					animation : new $.gQ.Animation({
-						imageURL : IMAGES_PREFIX + "background2.png"
-					})
-				}
-			}
-		}	
-	}
-};
-

+ 5 - 5
js/spaceinvaders-core.js

@@ -104,14 +104,14 @@ Game = {
 		if( typeof type == "undefined" ) {
 			return;
 		}
-		var alien = new type("alien" + id, {
-			x : offset + x * ALIENS_WIDTH * 1.5,
-			y : START_Y + (y * 1.25 * ALIENS_HEIGHT)
-		}, move.move);
+		var alien = new Alien("alien" + id, {
+			x : offset + x * type.animation.width * 1.5,
+			y : START_Y + (y * 1.25 * type.animation.height)
+		}, move.move, type);
 		var directions = move.init( alien.x, alien.y );
 		alien.directionX = directions.directionX;
 		alien.directionY = directions.directionY;
-		$("#actors").addSprite("alien" + id, $.extend({posx : alien.x, posy : alien.y}, animations.alien));
+		$("#actors").addSprite("alien" + id, $.extend({posx : alien.x, posy : alien.y}, alien.animation));
 		alien.node = $("#alien" + id);
 		alien.node.addClass("alien");
 		$("#alien" + id)[0].alien = alien;

+ 6 - 0
js/spaceinvaders-ui.js

@@ -126,6 +126,9 @@ $(function(){
 				posy: PLAYGROUND_HEIGHT - HUD_HEIGHT - 50
 			})
 			.end()
+			.addSprite("alienA", $.extend({posx : 50, posy : 300}, ALIENS[0]))
+			.addSprite("alienB", $.extend({posx : 50, posy : 400}, ALIENS[1]))
+			.addSprite("alienC", $.extend({posx : 50, posy : 500}, ALIENS[2]))
 			.addSprite("explosion", {
 				width: 64,
 				height: 64,
@@ -190,6 +193,9 @@ $(function(){
 		.end()
 		;
 
+		$("#alienA").addClass("alien");
+		$("#alienB").addClass("alien");
+		$("#alienC").addClass("alien");
 	$("#ground").css("background-color", "brown");
 	$("#levelLbl").append("Level").lettering();
 	$("#level").append("0").lettering();

+ 12 - 0
js/spaceinvaders-utils.js

@@ -0,0 +1,12 @@
+function getAliensMidHeight() {
+	var higherAlien = Math.max.apply( null, 
+		$(".alien").map(function() {
+			return $(this).y();
+		}).get() ),
+		lowerAlien = Math.min.apply( null, 
+		$(".alien").map(function() {
+			return $(this).y();
+		}).get() );
+		
+	return (higherAlien + lowerAlien) / 2;
+}