Initial commit

This commit is contained in:
IllusionMan1212
2018-09-30 06:17:31 +02:00
commit 96ce7c0dce
75 changed files with 10420 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
Impact Commercial Software License Agreement
1. OWNERSHIP, LICENSE GRANT
Subject to the terms below (the 'License Agreement'), Dominic Szablewski
Anwendungsentwicklung ('We', 'Us') grants you to install and use the Impact
Game Engine (the 'Software').
This is a license agreement and not an agreement for sale. We reserve
ownership of all intellectual property rights inherent in or relating to
the Software, which include, but are not limited to, all copyright, patent
rights, all rights in relation to registered and unregistered trademarks
(including service marks), confidential information (including trade
secrets and know-how) and all rights other than those expressly granted by
this Agreement.
Subject to the terms and conditions of this License Agreement, We grant to
You a non-transferable, non-exclusive license for a Designated User (as
defined below) within Your organization to install and use the Software on
any workstations used exclusively by such Designated User and for You to
distribute the Software as part of your applications or games, solely in
connection with distribution of the Software in accordance with sections 3
and 4 below. This license is not sublicensable except as explicitly set
forth herein. "Designated User(s)" shall mean Your employee(s) acting
within the scope of their employment or Your consultant(s) or contractor(s)
acting within the scope of the services they provide for You or on Your
behalf.
2. PERMITTED USES, SOURCE CODE, MODIFICATIONS
We provide You with source code so that You can create Modifications of the
original Software, where Modification means: a) any addition to or deletion
from the contents of a file included in the original Software or previous
Modifications created by You, or b) any new file that contains any part of
the original Software or previous Modifications. While You retain all
rights to any original work authored by You as part of the Modifications,
We continue to own all copyright and other intellectual property rights in
the Software.
3. DISTRIBUTION
You may distribute the Software in any applications, frameworks, or
elements (collectively referred to as "Applications") that you develop
using the Software in accordance with this License Agreement, provided that
such distribution does not violate the restrictions set forth in section 4
of this agreement.
You will not owe Us any royalties for Your distribution of the Software in
accordance with this License Agreement.
4. PROHIBITED USES
You may not redistribute the Software or Modifications other than by
including the Software or a portion thereof within Your own product, which
must have substantially different functionality than the Software or
Modifications and must not allow any third party to use the Software or
Modifications, or any portions thereof, for software development or
application development purposes. You are explicitly not allowed to
redistribute the Software or Modifications as part of any product that can
be described as a development toolkit or library or is intended for use by
software developers or application developers and not end-users.
5. TERMINATION
This Agreement shall terminate automatically if you fail to comply with the
limitations described in this Agreement. No notice shall be required to
effectuate such termination. Upon termination, you must remove and destroy
all copies of the Software. For the avoidance of doubt, failure to pay
invoices, sharing of license keys between users, and/or reselling of
activated license keys will result in termination of this agreement.
6. DISCLAIMER OF WARRANTY
YOU AGREE THAT WE HAVE MADE NO EXPRESS WARRANTIES, ORAL OR WRITTEN, TO YOU
REGARDING THE SOFTWARE AND THAT THE SOFTWARE IS BEING PROVIDED TO YOU 'AS
IS' WITHOUT WARRANTY OF ANY KIND. WE DISCLAIM ANY AND ALL OTHER WARRANTIES,
WHETHER EXPRESSED, IMPLIED, OR STATUTORY. YOUR RIGHTS MAY VARY DEPENDING ON
THE STATE IN WHICH YOU LIVE. WE SHALL NOT BE LIABLE FOR INDIRECT,
INCIDENTAL, SPECIAL, COVER, RELIANCE, OR CONSEQUENTIAL DAMAGES RESULTING
FROM THE USE OF THIS PRODUCT.
7. LIMITATION OF LIABILITY
YOU USE THIS PROGRAM SOLELY AT YOUR OWN RISK. IN NO EVENT SHALL WE BE
LIABLE TO YOU FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO ANY LOSS, OR
OTHER INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND ARISING OUT
OF THE USE OF THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES. IN NO EVENT WILL WE BE LIABLE FOR ANY CLAIM, WHETHER IN
CONTRACT, TORT, OR ANY OTHER THEORY OF LIABILITY, EXCEED THE COST OF THE
SOFTWARE. THIS LIMITATION SHALL APPLY TO CLAIMS OF PERSONAL INJURY TO THE
EXTENT PERMITTED BY LAW.
8. UPDATES
You are entitled to receive minor version updates to the Software (i.e.
versions identified as follows (X.Y, X.Y+1). You are not entitled to
receive major version updates (i.e. X.Y, X+1.Y). Major version updates to
the Software are available separately for purchase.
9. MISCELLANEOUS
The license granted herein applies only to the version of the Software
available when purchased in connection with the terms of this Agreement.
Any previous or subsequent license granted to You for use of the Software
shall be governed by the terms and conditions of the agreement entered in
connection with purchase of that version of the Software. You agree that
you will comply with all applicable laws and regulations with respect to
the Software, including without limitation all export and re-export control
laws and regulations.
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>The Adventures of Kuroneko and Shironeko</title>
<style type="text/css">
html,body {
background-color: #333;
color: #fff;
font-family: helvetica, arial, sans-serif;
margin: 0;
padding: 0;
font-size: 12pt;
}
#canvas {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
</style>
<script type="text/javascript" src="lib/impact/impact.js"></script>
<script type="text/javascript" src="lib/game/main.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
+45
View File
@@ -0,0 +1,45 @@
ig.module(
'game.entities.cheese'
)
.requires(
'impact.entity',
'game.entities.kuroneko',
)
.defines(function() {
EntityCheese = ig.Entity.extend({
collides: ig.Entity.COLLIDES.LITE,
size: {x: 32, y: 20},
offset: {x: 0, y: 12},
gravityFactor: 0,
animSheet: new ig.AnimationSheet('media/cheese.png', 32, 32),
init: function(x, y, settings) {
this.parent(x, y, settings);
this.addAnim('normal', 1, [0]);
},
update: function() {
this.parent();
this.currentAnim = this.anims.normal;
},
collideWith: function(other, axis) {
this.player = ig.game.getEntitiesByType(EntityKuroneko)[0];
if (other instanceof EntityKuroneko) {
this.kill();
if (this.player.health < 4) {
this.player.health += 1;
}
}
},
kill: function() {
ig.game.removeEntity(this);
}
})
})
+25
View File
@@ -0,0 +1,25 @@
ig.module(
'game.entities.easteregg'
)
.requires(
'impact.entity',
'game.entities.kuroneko',
'game.entities.cheese',
)
.defines(function() {
EntityEasteregg = EntityCheese.extend({
animSheet: new ig.AnimationSheet('media/easteregg.png', 32, 32),
collideWith: function(other, axis) {
this.player = ig.game.getEntitiesByType(EntityKuroneko)[0];
if (other instanceof EntityKuroneko) {
this.kill();
ig.game.score += 10000;
if (this.player.health < 4) {
this.player.health += 4;
}
}
},
})
})
+24
View File
@@ -0,0 +1,24 @@
ig.module(
'game.entities.endgame'
)
.requires(
'impact.entity',
'game.entities.kuroneko',
'game.entities.nextlevel',
)
.defines(function() {
EntityEndgame = EntityNextlevel.extend({
check: function( other ) {
if(other instanceof EntityKuroneko){
this.player = ig.game.getEntitiesByType(EntityKuroneko)[0];
this.player.currentAnim = this.player.anims.nothing;
this.player.speed = 0;
if (ig.game.score == 0 || ig.game.score == 10000) {
setTimeout(function() {ig.game.loadLevel( LevelGoodend );}.bind(this), 1000);
} else {
setTimeout(function() {ig.game.loadLevel( LevelBadend );}.bind(this), 1000);
}
}
},
})
})
+132
View File
@@ -0,0 +1,132 @@
ig.module(
'game.entities.kuroneko'
)
.requires(
'impact.entity'
)
.defines(function() {
EntityKuroneko = ig.Entity.extend({
collides: ig.Entity.COLLIDES.ACTIVE,
size: {x: 24, y: 28},
offset: {x: 4, y: 4},
gravityFactor: 4,
maxVel: {x: 150, y: 520},
speed: 400,
jump_height: 800,
friction: {x: 500, y: 0},
health: 4,
type: ig.Entity.TYPE.A,
is_dead: false,
flip: false,
kuro: true,
animSheet: new ig.AnimationSheet('media/kuroneko.png', 32, 32),
jumpSheet: new ig.AnimationSheet('media/kuroneko-jump.png', 46, 32),
init: function(x, y, settings) {
this.parent(x, y, settings);
this.invincibleTimer = new ig.Timer();
this.addAnim('idle', 1, [0]);
this.addAnim('walk', 0.13, [2,3,4,5,4,3]);
this.addAnim('idle_shiro', 1, [6]);
this.addAnim('walk_shiro', 0.13, [8,9,10,11,10,9]);
this.addAnim('nothing', 1, [20]);
this.anims.jump = new ig.Animation(this.jumpSheet, 1, [0]);
this.anims.jump_shiro = new ig.Animation(this.jumpSheet, 1, [1]);
},
update: function() {
this.parent();
this.currentAnim.flip.x = this.flip;
//Handle movement
if (ig.input.state('right')) {
this.accel.x = this.speed;
this.flip = false;
} else if (ig.input.state('left')) {
this.accel.x = -this.speed;
this.flip = true;
} else {
this.accel.x = 0;
}
if (ig.input.pressed('up') && this.standing) {
if (this.vel.y == 0) {
this.vel.y -= this.jump_height;
}
}
if (this.pos.y > 640 - 32) {
this.kill();
}
//Handle animations
if (this.kuro) {
if (this.vel.y != 0 && !this.standing) {
this.offset = { x: 10, y: 4 };
this.currentAnim = this.anims.jump;
} else if (this.vel.x != 0 && this.standing) {
this.offset = { x: 4, y: 4 };
this.currentAnim = this.anims.walk;
} else {
this.offset = { x: 4, y: 4 };
this.currentAnim = this.anims.idle;
}
} else {
if (this.vel.y != 0 && !this.standing) {
this.offset = { x: 10, y: 4 };
this.currentAnim = this.anims.jump_shiro;
} else if (this.vel.x != 0 && this.standing) {
this.offset = { x: 4, y: 4 };
this.currentAnim = this.anims.walk_shiro;
} else {
this.offset = { x: 4, y: 4 };
this.currentAnim = this.anims.idle_shiro;
}
}
//Change color on different BGs
if (ig.game.currentLevel == LevelLevel1) {
if (this.pos.x > 832 && this.pos.x < 1568) {
this.kuro = false;
} else if (this.pos.x > 1568 && this.pos.x < 2368) {
this.kuro = true;
} else if (this.pos.x > 2368) {
this.kuro = false;
} else {
this.kuro = true;
}
} else if (ig.game.currentLevel == LevelLevel2) {
if (this.pos.x > 1023 && this.pos.x < 2016) {
this.kuro = false;
} else if (this.pos.x > 2016 && this.pos.x < 3008) {
this.kuro = true;
} else if (this.pos.x > 3008 && this.pos.x < 4000) {
this.kuro = false;
} else if (this.pos.x > 4000 && this.pos.x < 4992) {
this.kuro = true;
} else if (this.pos.x > 4992 && this.pos.x < 5984) {
this.kuro = false;
} else if (this.pos.x > 5984) {
this.kuro = true;
} else {
this.kuro = true;
}
}
},
kill: function() {
this.is_dead = true;
ig.game.removeEntity(this);
ig.game.score = 0;
setTimeout(function() {ig.game.loadLevel(LevelGameover)}, 700);
}
})
})
+88
View File
@@ -0,0 +1,88 @@
ig.module(
'game.entities.mouse'
)
.requires(
'impact.entity',
'game.entities.kuroneko',
)
.defines(function() {
EntityMouse = ig.Entity.extend({
collides: ig.Entity.COLLIDES.PASSIVE,
size: {x: 26, y: 9},
gravityFactor: 4,
speed: 100,
maxVel: {x: 300, y: 100},
flip: true,
player: null,
is_dead: false,
animSheet: new ig.AnimationSheet('media/mouse.png', 26, 9),
init: function(x, y, settings) {
this.parent(x, y, settings);
this.addAnim('normal', 1, [0]);
this.addAnim('dead', 1, [1]);
},
update: function() {
this.parent();
if (!this.is_dead) {
this.currentAnim = this.anims.normal;
} else {
this.currentAnim = this.anims.dead;
this.currentAnim.flip.y = true;
}
this.currentAnim.flip.x = this.flip;
var xdir = this.flip ? -1:1;
this.vel.x = this.speed * this.turnAround();;
},
handleMovementTrace: function(res) {
this.parent(res);
if (res.collision.x) {
this.flip = !this.flip;
}
},
collideWith: function(other, axis) {
this.player = ig.game.getEntitiesByType(EntityKuroneko)[0];
if (other instanceof EntityKuroneko) {
if (axis === 'y') {
this.kill();
this.player.vel.y = -200;
ig.game.score += 100;
} else if (axis === 'x') {
this.player.receiveDamage(1, this);
if (this.player.pos.x < this.pos.x) {
this.player.vel.x = -400;
} else {
this.player.vel.x = 400;
}
}
}
},
turnAround: function(){
//is the next collision tile empty
var x = this.pos.x + (this.flip ? + 5 : this.size.x - 5);
var y = this.pos.y + this.size.y + 5;
if(!ig.game.collisionMap.getTile(x, y)){
this.flip = !this.flip;
}
return this.flip ? -1 : 1;
},
kill: function() {
this.is_dead = true;
this.speed = 0;
this.collides = ig.Entity.COLLIDES.NEVER;
setTimeout(function(){ig.game.removeEntity(this);}.bind(this), 500);
}
})
})
+30
View File
@@ -0,0 +1,30 @@
ig.module(
'game.entities.nextlevel'
)
.requires(
'impact.entity',
'game.entities.kuroneko',
)
.defines(function() {
EntityNextlevel = ig.Entity.extend({
_wmDrawBox: true,
_wmBoxColor: 'rgba(0, 0, 255, 0.7)',
size: {x: 16, y: 48},
gravityFactor: 0,
checkAgainst: ig.Entity.TYPE.A,
player: null,
update: function(x, y, settings) {
this.parent(x, y, settings);
},
check: function( other ) {
if(other instanceof EntityKuroneko){
this.player = ig.game.getEntitiesByType(EntityKuroneko)[0];
this.player.currentAnim = this.player.anims.nothing;
this.player.speed = 0;
setTimeout(function() {ig.game.loadLevel( LevelLevel2 );}.bind(this), 1000);
}
},
})
})
+40
View File
@@ -0,0 +1,40 @@
ig.module( 'game.levels.badend' )
.requires( 'impact.image' )
.defines(function(){
LevelBadend=/*JSON[*/{
"entities": [],
"layer": [
{
"name": "main",
"width": 20,
"height": 15,
"linkWithCollision": false,
"visible": true,
"tilesetName": "media/badend.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[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,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],
[121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140],
[141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],
[161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],
[181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],
[201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220],
[221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240],
[241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260],
[261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280],
[281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300]
]
}
]
}/*]JSON*/;
LevelBadendResources=[new ig.Image('media/badend.png')];
});
+40
View File
@@ -0,0 +1,40 @@
ig.module( 'game.levels.gameover' )
.requires( 'impact.image' )
.defines(function(){
LevelGameover=/*JSON[*/{
"entities": [],
"layer": [
{
"name": "main",
"width": 20,
"height": 15,
"linkWithCollision": false,
"visible": true,
"tilesetName": "media/gameover.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[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,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],
[121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140],
[141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],
[161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],
[181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],
[201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220],
[221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240],
[241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260],
[261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280],
[281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300]
]
}
]
}/*]JSON*/;
LevelGameoverResources=[new ig.Image('media/gameover.png')];
});
+40
View File
@@ -0,0 +1,40 @@
ig.module( 'game.levels.goodend' )
.requires( 'impact.image' )
.defines(function(){
LevelGoodend=/*JSON[*/{
"entities": [],
"layer": [
{
"name": "main",
"width": 20,
"height": 15,
"linkWithCollision": false,
"visible": true,
"tilesetName": "media/goodend.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[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,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],
[121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140],
[141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],
[161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],
[181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],
[201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220],
[221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240],
[241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260],
[261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280],
[281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300]
]
}
]
}/*]JSON*/;
LevelGoodendResources=[new ig.Image('media/goodend.png')];
});
+111
View File
@@ -0,0 +1,111 @@
ig.module( 'game.levels.level1' )
.requires( 'impact.image','game.entities.kuroneko','game.entities.cheese','game.entities.mouse','game.entities.nextlevel','game.entities.easteregg' )
.defines(function(){
LevelLevel1=/*JSON[*/{
"entities": [
{
"type": "EntityKuroneko",
"x": 108,
"y": 580
},
{
"type": "EntityCheese",
"x": 1828,
"y": 588
},
{
"type": "EntityMouse",
"x": 1260,
"y": 584
},
{
"type": "EntityMouse",
"x": 2144,
"y": 496
},
{
"type": "EntityNextlevel",
"x": 3064,
"y": 552
},
{
"type": "EntityEasteregg",
"x": 3136,
"y": 76
}
],
"layer": [
{
"name": "main",
"width": 100,
"height": 20,
"linkWithCollision": false,
"visible": 1,
"tilesetName": "media/tutorial.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,567,567,567,567,567,567,567,567,567,567,567,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640],
[130,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,640],
[130,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,640],
[130,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,640],
[130,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,640],
[130,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,640],
[130,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,640],
[130,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,640],
[130,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,640],
[130,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,640],
[130,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,640],
[130,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,640],
[130,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,640],
[130,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,640],
[130,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1228,1228,1228,1313,1314,1228,1228,1228,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,640],
[130,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1228,1409,1410,1411,1412,1413,1414,1228,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,862,862,1437,1438,1439,1440,1441,862,862,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,0,1467,1468,1469,1470,640],
[130,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1228,1507,1508,1509,1510,1511,1512,1228,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,862,862,862,862,862,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,640],
[130,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1228,1605,1606,1607,1608,1609,1610,1228,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,640],
[130,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1228,1703,1704,1705,1706,1707,1708,1228,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,854,854,658,1342,1342,1733,1734,1735,1736,854,854,658,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,640],
[130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,567,567,567,567,567,567,567,567,567,567,567,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640]
]
},
{
"name": "collision",
"width": 100,
"height": 20,
"linkWithCollision": false,
"visible": 1,
"tilesetName": "",
"repeat": false,
"preRender": false,
"distance": 1,
"tilesize": 32,
"foreground": false,
"data": [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,12,12,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,12,12,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,12,12,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12,12,12,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]
}
]
}/*]JSON*/;
LevelLevel1Resources=[new ig.Image('media/tutorial.png')];
});
+281
View File
@@ -0,0 +1,281 @@
ig.module( 'game.levels.level2' )
.requires( 'impact.image','game.entities.mouse','game.entities.cheese','game.entities.endgame','game.entities.kuroneko' )
.defines(function(){
LevelLevel2=/*JSON[*/{
"entities": [
{
"type": "EntityMouse",
"x": 1188,
"y": 484
},
{
"type": "EntityMouse",
"x": 1248,
"y": 484
},
{
"type": "EntityCheese",
"x": 2992,
"y": 172
},
{
"type": "EntityCheese",
"x": 3420,
"y": 588
},
{
"type": "EntityCheese",
"x": 2540,
"y": 396
},
{
"type": "EntityMouse",
"x": 2420,
"y": 588
},
{
"type": "EntityCheese",
"x": 2532,
"y": 232
},
{
"type": "EntityCheese",
"x": 4352,
"y": 408
},
{
"type": "EntityMouse",
"x": 2160,
"y": 592
},
{
"type": "EntityMouse",
"x": 2700,
"y": 300
},
{
"type": "EntityMouse",
"x": 2328,
"y": 300
},
{
"type": "EntityMouse",
"x": 2812,
"y": 460
},
{
"type": "EntityMouse",
"x": 2044,
"y": 588
},
{
"type": "EntityCheese",
"x": 3480,
"y": 588
},
{
"type": "EntityMouse",
"x": 2352,
"y": 468
},
{
"type": "EntityMouse",
"x": 544,
"y": 440
},
{
"type": "EntityCheese",
"x": 3536,
"y": 588
},
{
"type": "EntityMouse",
"x": 3480,
"y": 404
},
{
"type": "EntityMouse",
"x": 1680,
"y": 488
},
{
"type": "EntityMouse",
"x": 1880,
"y": 488
},
{
"type": "EntityCheese",
"x": 1404,
"y": 492
},
{
"type": "EntityCheese",
"x": 4352,
"y": 428
},
{
"type": "EntityCheese",
"x": 4384,
"y": 428
},
{
"type": "EntityCheese",
"x": 4416,
"y": 428
},
{
"type": "EntityCheese",
"x": 4448,
"y": 428
},
{
"type": "EntityCheese",
"x": 4480,
"y": 428
},
{
"type": "EntityCheese",
"x": 4512,
"y": 428
},
{
"type": "EntityCheese",
"x": 4548,
"y": 408
},
{
"type": "EntityCheese",
"x": 4548,
"y": 428
},
{
"type": "EntityCheese",
"x": 4512,
"y": 408
},
{
"type": "EntityCheese",
"x": 4480,
"y": 408
},
{
"type": "EntityCheese",
"x": 4448,
"y": 408
},
{
"type": "EntityCheese",
"x": 4416,
"y": 408
},
{
"type": "EntityCheese",
"x": 4384,
"y": 408
},
{
"type": "EntityEndgame",
"x": 6280,
"y": 560
},
{
"type": "EntityMouse",
"x": 424,
"y": 440
},
{
"type": "EntityMouse",
"x": 648,
"y": 440
},
{
"type": "EntityMouse",
"x": 456,
"y": 440
},
{
"type": "EntityMouse",
"x": 368,
"y": 440
},
{
"type": "EntityKuroneko",
"x": 132,
"y": 580
}
],
"layer": [
{
"name": "main",
"width": 200,
"height": 20,
"linkWithCollision": false,
"visible": 1,
"tilesetName": "media/level1.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084],
[2084,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,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,2084],
[2084,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,2084],
[2084,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,2084],
[2084,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,2084],
[2084,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,2084],
[2084,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1373,1373,1373,2369,2369,2369,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,2084],
[2084,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,2084],
[2084,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,2084],
[2084,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1929,1720,1721,1722,1723,1724,1725,1726,1929,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,2084],
[2084,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1562,1562,1562,1562,1562,1857,1858,1859,1860,1861,1862,1863,1864,1865,1562,1562,1562,1562,1562,1871,1872,1873,1874,1875,1876,1877,1878,1879,2369,2369,2369,2369,2369,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1929,1918,1919,1920,1921,1922,1923,1924,1929,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,2084],
[2084,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113,2114,1929,2116,2117,2118,2119,2120,2121,2122,1929,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2084],
[2084,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2308,2309,2310,2311,2312,1562,2314,2315,2316,2317,2318,2319,2320,1562,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2084],
[2084,2377,2378,2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2084,2084,2084,2084,2084,2084,2084,2084,2084,2490,2491,2492,2493,2494,2495,2496,2497,2498,2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,1562,2512,2513,2514,2515,2516,2517,2518,1562,2520,2521,2522,2523,2524,2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2084],
[2084,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,1815,1815,1815,1815,2410,2410,2410,2410,2410,2410,1815,2596,2597,2598,2599,2600,2601,2602,2603,2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,2369,2369,2369,2369,2369,2369,2369,2369,2687,2688,2689,2690,2691,2692,2693,2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,1562,1562,1562,1562,1562,1562,1562,1562,1562,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,1933,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,1933,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2084],
[2084,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,1562,1562,1562,1562,1562,2847,2848,2849,2850,2851,2852,2853,2854,2855,1562,1562,1562,1562,1562,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1933,1933,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,2949,2950,2951,2952,2953,2954,1933,1933,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968,2969,2970,2084],
[2084,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,982,982,982,982,982,982,982,982,982,982,2026,3016,3017,3018,3019,3020,982,982,982,982,982,982,982,982,982,982,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,1933,1933,1933,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,1933,1933,1933,3156,3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,2084],
[2084,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,982,982,982,982,982,982,982,982,982,982,2026,3214,3215,3216,3217,3218,982,982,982,982,982,982,982,982,982,982,3229,3230,3231,3232,3233,3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,1933,1933,1933,1933,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,1933,1933,1933,1933,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,2084],
[2084,3367,3368,3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,982,982,982,982,982,982,982,982,982,982,2026,3412,3413,3414,3415,3416,982,982,982,982,982,982,982,982,982,982,3427,3428,3429,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443,3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,3519,3520,3521,1933,1933,1933,1933,1933,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548,1933,1933,1933,1933,1970,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,3564,2084],
[2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,1831,1831,1831,1831,1831,1831,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,982,982,982,982,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084,2084]
]
},
{
"name": "collision",
"width": 200,
"height": 20,
"linkWithCollision": false,
"visible": 0,
"tilesetName": "",
"repeat": false,
"preRender": false,
"distance": 1,
"tilesize": 32,
"foreground": false,
"data": [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]
}
]
}/*]JSON*/;
LevelLevel2Resources=[new ig.Image('media/level1.png')];
});
+40
View File
@@ -0,0 +1,40 @@
ig.module( 'game.levels.title' )
.requires( 'impact.image' )
.defines(function(){
LevelTitle=/*JSON[*/{
"entities": [],
"layer": [
{
"name": "title",
"width": 20,
"height": 15,
"linkWithCollision": false,
"visible": 1,
"tilesetName": "media/Menu.png",
"repeat": false,
"preRender": false,
"distance": "1",
"tilesize": 32,
"foreground": false,
"data": [
[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,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],
[121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140],
[141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],
[161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],
[181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],
[201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220],
[221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240],
[241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260],
[261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280],
[281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300]
]
}
]
}/*]JSON*/;
LevelTitleResources=[new ig.Image('media/Menu.png')];
});
+189
View File
@@ -0,0 +1,189 @@
ig.module(
'game.main'
)
.requires(
'impact.game',
'impact.font',
'game.entities.kuroneko',
'game.entities.cheese',
'game.entities.mouse',
'game.entities.nextlevel',
'game.entities.endgame',
'game.entities.easteregg',
'game.levels.title',
'game.levels.level1',
'game.levels.level2',
'game.levels.gameover',
'game.levels.goodend',
'game.levels.badend',
'impact.debug.debug',
)
.defines(function(){
MyGame = ig.Game.extend({
gravity: 200,
player: null,
score: 0,
checkpoint: null,
init: function() {
this.loadLevel( LevelTitle );
ig.input.bind(ig.KEY.RIGHT_ARROW, 'right');
ig.input.bind(ig.KEY.LEFT_ARROW, 'left');
ig.input.bind(ig.KEY.UP_ARROW, 'up');
ig.input.bind(ig.KEY.SPACE, 'space');
},
update: function() {
// Update all entities and backgroundMaps
this.parent();
this.player = this.getEntitiesByType(EntityKuroneko)[0];
if (this.player) {
this.scrollScreen();
}
if (this.currentLevel == LevelTitle) {
//play title music
if (ig.input.pressed('space')) {
this.loadLevel( LevelLevel1 );
}
}
if (this.currentLevel == LevelLevel1) {
//play game music
this.checkpoint = LevelLevel1;
}
if (this.currentLevel == LevelLevel2) {
//play game music
this.checkpoint = LevelLevel2;
}
if (this.currentLevel == LevelGameover) {
//play some sad music
if (ig.input.pressed('space')) {
this.loadLevel( this.checkpoint );
}
}
if (this.currentLevel == LevelBadend || this.currentLevel == LevelGoodend) {
//play ending music
if (ig.input.pressed('space')) {
this.loadLevel( LevelTitle );
}
}
},
loadLevel: function(data) {
this.parent(data);
this.currentLevel = data;
},
scrollScreen: function() {
//Camera code
if(this.player.pos.x > (ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width/2))
{
this.screen.x = ig.game.collisionMap.width*ig.game.collisionMap.tilesize-ig.system.width;
}
else if (this.player.pos.x < ig.system.width/2)
{
this.screen.x = 0;
}
else
{
this.screen.x = this.player.pos.x - ig.system.width/2;
}
if(this.player.pos.y > (ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height/2))
{
this.screen.y = ig.game.collisionMap.height*ig.game.collisionMap.tilesize-ig.system.height;
}
else if (this.player.pos.y < ig.system.height/2)
{
this.screen.y = 0;
}
else
{
this.screen.y = this.player.pos.y - ig.system.height/2;
}
},
draw: function() {
// Draw all entities and backgroundMaps
this.parent();
this.player = this.getEntitiesByType(EntityKuroneko)[0];
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.font = '30px Ariel'
if (this.currentLevel == LevelLevel1 || this.currentLevel == LevelLevel2) {
if (this.player) {
if (this.player.health == 4) {
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "#808080";
ctx.rect(60, 30, 96, 16);
ctx.stroke();
ctx.fillStyle = '#ac3232';
ctx.fillRect(63, 33, 90, 10);
}
else if (this.player.health == 3) {
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "#808080";
ctx.rect(60, 30, 96, 16);
ctx.stroke();
ctx.fillStyle = '#ac3232';
ctx.fillRect(63, 33, 67.5, 10);
}
else if (this.player.health == 2) {
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "#808080";
ctx.rect(60, 30, 96, 16);
ctx.stroke();
ctx.fillStyle = '#ac3232';
ctx.fillRect(63, 33, 45, 10);
}
else if (this.player.health == 1) {
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "#808080";
ctx.rect(60, 30, 96, 16);
ctx.stroke();
ctx.fillStyle = '#ac3232';
ctx.fillRect(63, 33, 22.5, 10);
}
ctx.fillText(`Score: ${this.score}`, 750, 45);
}
ctx.beginPath();
ctx.lineWidth = "6";
ctx.strokeStyle = "#808080";
ctx.rect(60, 30, 96, 16);
ctx.stroke();
ctx.fillStyle = '#ac3232';
ctx.fillRect(63, 33, 0, 10);
}
}
});
// Start the Game with 60fps, a resolution of 640x480, scaled
// up by a factor of 1.5
ig.main( '#canvas', MyGame, 60, 640, 480, 1.5 );
});
+130
View File
@@ -0,0 +1,130 @@
ig.module(
'impact.animation'
)
.requires(
'impact.timer',
'impact.image'
)
.defines(function(){ "use strict";
ig.AnimationSheet = ig.Class.extend({
width: 8,
height: 8,
image: null,
init: function( path, width, height ) {
this.width = width;
this.height = height;
this.image = new ig.Image( path );
}
});
ig.Animation = ig.Class.extend({
sheet: null,
timer: null,
sequence: [],
flip: {x: false, y: false},
pivot: {x: 0, y: 0},
frame: 0,
tile: 0,
loopCount: 0,
alpha: 1,
angle: 0,
init: function( sheet, frameTime, sequence, stop ) {
this.sheet = sheet;
this.pivot = {x: sheet.width/2, y: sheet.height/2 };
this.timer = new ig.Timer();
this.frameTime = frameTime;
this.sequence = sequence;
this.stop = !!stop;
this.tile = this.sequence[0];
},
rewind: function() {
this.timer.set();
this.loopCount = 0;
this.frame = 0;
this.tile = this.sequence[0];
return this;
},
gotoFrame: function( f ) {
// Offset the timer by one tenth of a millisecond to make sure we
// jump to the correct frame and circumvent rounding errors
this.timer.set( this.frameTime * -f - 0.0001 );
this.update();
},
gotoRandomFrame: function() {
this.gotoFrame( Math.floor(Math.random() * this.sequence.length) )
},
update: function() {
var frameTotal = Math.floor(this.timer.delta() / this.frameTime);
this.loopCount = Math.floor(frameTotal / this.sequence.length);
if( this.stop && this.loopCount > 0 ) {
this.frame = this.sequence.length - 1;
}
else {
this.frame = frameTotal % this.sequence.length;
}
this.tile = this.sequence[ this.frame ];
},
draw: function( targetX, targetY ) {
var bbsize = Math.max(this.sheet.width, this.sheet.height);
// On screen?
if(
targetX > ig.system.width || targetY > ig.system.height ||
targetX + bbsize < 0 || targetY + bbsize < 0
) {
return;
}
if( this.alpha != 1) {
ig.system.context.globalAlpha = this.alpha;
}
if( this.angle == 0 ) {
this.sheet.image.drawTile(
targetX, targetY,
this.tile, this.sheet.width, this.sheet.height,
this.flip.x, this.flip.y
);
}
else {
ig.system.context.save();
ig.system.context.translate(
ig.system.getDrawPos(targetX + this.pivot.x),
ig.system.getDrawPos(targetY + this.pivot.y)
);
ig.system.context.rotate( this.angle );
this.sheet.image.drawTile(
-this.pivot.x, -this.pivot.y,
this.tile, this.sheet.width, this.sheet.height,
this.flip.x, this.flip.y
);
ig.system.context.restore();
}
if( this.alpha != 1) {
ig.system.context.globalAlpha = 1;
}
}
});
});
+249
View File
@@ -0,0 +1,249 @@
ig.module(
'impact.background-map'
)
.requires(
'impact.map',
'impact.image'
)
.defines(function(){ "use strict";
ig.BackgroundMap = ig.Map.extend({
tiles: null,
scroll: {x: 0, y:0},
distance: 1,
repeat: false,
tilesetName: '',
foreground: false,
enabled: true,
preRender: false,
preRenderedChunks: null,
chunkSize: 512,
debugChunks: false,
anims: {},
init: function( tilesize, data, tileset ) {
this.parent( tilesize, data );
this.setTileset( tileset );
},
setTileset: function( tileset ) {
this.tilesetName = tileset instanceof ig.Image ? tileset.path : tileset;
this.tiles = new ig.Image( this.tilesetName );
this.preRenderedChunks = null;
},
setScreenPos: function( x, y ) {
this.scroll.x = x / this.distance;
this.scroll.y = y / this.distance;
},
preRenderMapToChunks: function() {
var totalWidth = this.width * this.tilesize * ig.system.scale,
totalHeight = this.height * this.tilesize * ig.system.scale;
// If this layer is smaller than the chunkSize, adjust the chunkSize
// accordingly, so we don't have as much overdraw
this.chunkSize = Math.min( Math.max(totalWidth, totalHeight), this.chunkSize );
var chunkCols = Math.ceil(totalWidth / this.chunkSize),
chunkRows = Math.ceil(totalHeight / this.chunkSize);
this.preRenderedChunks = [];
for( var y = 0; y < chunkRows; y++ ) {
this.preRenderedChunks[y] = [];
for( var x = 0; x < chunkCols; x++ ) {
var chunkWidth = (x == chunkCols-1)
? totalWidth - x * this.chunkSize
: this.chunkSize;
var chunkHeight = (y == chunkRows-1)
? totalHeight - y * this.chunkSize
: this.chunkSize;
this.preRenderedChunks[y][x] = this.preRenderChunk( x, y, chunkWidth, chunkHeight );
}
}
},
preRenderChunk: function( cx, cy, w, h ) {
var tw = w / this.tilesize / ig.system.scale + 1,
th = h / this.tilesize / ig.system.scale + 1;
var nx = (cx * this.chunkSize / ig.system.scale) % this.tilesize,
ny = (cy * this.chunkSize / ig.system.scale) % this.tilesize;
var tx = Math.floor(cx * this.chunkSize / this.tilesize / ig.system.scale),
ty = Math.floor(cy * this.chunkSize / this.tilesize / ig.system.scale);
var chunk = ig.$new('canvas');
chunk.width = w;
chunk.height = h;
chunk.retinaResolutionEnabled = false; // Opt out for Ejecta
var chunkContext = chunk.getContext('2d');
ig.System.scaleMode(chunk, chunkContext);
var screenContext = ig.system.context;
ig.system.context = chunkContext;
for( var x = 0; x < tw; x++ ) {
for( var y = 0; y < th; y++ ) {
if( x + tx < this.width && y + ty < this.height ) {
var tile = this.data[y+ty][x+tx];
if( tile ) {
this.tiles.drawTile(
x * this.tilesize - nx, y * this.tilesize - ny,
tile - 1, this.tilesize
);
}
}
}
}
ig.system.context = screenContext;
return chunk;
},
draw: function() {
if( !this.tiles.loaded || !this.enabled ) {
return;
}
if( this.preRender ) {
this.drawPreRendered();
}
else {
this.drawTiled();
}
},
drawPreRendered: function() {
if( !this.preRenderedChunks ) {
this.preRenderMapToChunks();
}
var dx = ig.system.getDrawPos(this.scroll.x),
dy = ig.system.getDrawPos(this.scroll.y);
if( this.repeat ) {
var w = this.width * this.tilesize * ig.system.scale;
dx = (dx%w + w) % w;
var h = this.height * this.tilesize * ig.system.scale;
dy = (dy%h + h) % h;
}
var minChunkX = Math.max( Math.floor(dx / this.chunkSize), 0 ),
minChunkY = Math.max( Math.floor(dy / this.chunkSize), 0 ),
maxChunkX = Math.ceil((dx+ig.system.realWidth) / this.chunkSize),
maxChunkY = Math.ceil((dy+ig.system.realHeight) / this.chunkSize),
maxRealChunkX = this.preRenderedChunks[0].length,
maxRealChunkY = this.preRenderedChunks.length;
if( !this.repeat ) {
maxChunkX = Math.min( maxChunkX, maxRealChunkX );
maxChunkY = Math.min( maxChunkY, maxRealChunkY );
}
var nudgeY = 0;
for( var cy = minChunkY; cy < maxChunkY; cy++ ) {
var nudgeX = 0;
for( var cx = minChunkX; cx < maxChunkX; cx++ ) {
var chunk = this.preRenderedChunks[cy % maxRealChunkY][cx % maxRealChunkX];
var x = -dx + cx * this.chunkSize - nudgeX;
var y = -dy + cy * this.chunkSize - nudgeY;
ig.system.context.drawImage( chunk, x, y);
ig.Image.drawCount++;
if( this.debugChunks ) {
ig.system.context.strokeStyle = '#f0f';
ig.system.context.strokeRect( x, y, this.chunkSize, this.chunkSize );
}
// If we repeat in X and this chunk's width wasn't the full chunk size
// and the screen is not already filled, we need to draw anohter chunk
// AND nudge it to be flush with the last chunk
if( this.repeat && chunk.width < this.chunkSize && x + chunk.width < ig.system.realWidth ) {
nudgeX += this.chunkSize - chunk.width;
maxChunkX++;
}
}
// Same as above, but for Y
if( this.repeat && chunk.height < this.chunkSize && y + chunk.height < ig.system.realHeight ) {
nudgeY += this.chunkSize - chunk.height;
maxChunkY++;
}
}
},
drawTiled: function() {
var tile = 0,
anim = null,
tileOffsetX = (this.scroll.x / this.tilesize).toInt(),
tileOffsetY = (this.scroll.y / this.tilesize).toInt(),
pxOffsetX = this.scroll.x % this.tilesize,
pxOffsetY = this.scroll.y % this.tilesize,
pxMinX = -pxOffsetX - this.tilesize,
pxMinY = -pxOffsetY - this.tilesize,
pxMaxX = ig.system.width + this.tilesize - pxOffsetX,
pxMaxY = ig.system.height + this.tilesize - pxOffsetY;
// FIXME: could be sped up for non-repeated maps: restrict the for loops
// to the map size instead of to the screen size and skip the 'repeat'
// checks inside the loop.
for( var mapY = -1, pxY = pxMinY; pxY < pxMaxY; mapY++, pxY += this.tilesize) {
var tileY = mapY + tileOffsetY;
// Repeat Y?
if( tileY >= this.height || tileY < 0 ) {
if( !this.repeat ) { continue; }
tileY = (tileY%this.height + this.height) % this.height;
}
for( var mapX = -1, pxX = pxMinX; pxX < pxMaxX; mapX++, pxX += this.tilesize ) {
var tileX = mapX + tileOffsetX;
// Repeat X?
if( tileX >= this.width || tileX < 0 ) {
if( !this.repeat ) { continue; }
tileX = (tileX%this.width + this.width) % this.width;
}
// Draw!
if( (tile = this.data[tileY][tileX]) ) {
if( (anim = this.anims[tile-1]) ) {
anim.draw( pxX, pxY );
}
else {
this.tiles.drawTile( pxX, pxY, tile-1, this.tilesize );
}
}
} // end for x
} // end for y
}
});
});
+274
View File
@@ -0,0 +1,274 @@
ig.module(
'impact.collision-map'
)
.requires(
'impact.map'
)
.defines(function(){ "use strict";
ig.CollisionMap = ig.Map.extend({
lastSlope: 1,
tiledef: null,
init: function( tilesize, data, tiledef ) {
this.parent( tilesize, data );
this.tiledef = tiledef || ig.CollisionMap.defaultTileDef;
for( var t in this.tiledef ) {
if( t|0 > this.lastSlope ) {
this.lastSlope = t|0;
}
}
},
trace: function( x, y, vx, vy, objectWidth, objectHeight ) {
// Set up the trace-result
var res = {
collision: {x: false, y: false, slope: false},
pos: {x: x, y: y},
tile: {x: 0, y: 0}
};
// Break the trace down into smaller steps if necessary
var steps = Math.ceil(Math.max(Math.abs(vx), Math.abs(vy)) / this.tilesize);
if( steps > 1 ) {
var sx = vx / steps;
var sy = vy / steps;
for( var i = 0; i < steps && (sx || sy); i++ ) {
this._traceStep( res, x, y, sx, sy, objectWidth, objectHeight, vx, vy, i );
x = res.pos.x;
y = res.pos.y;
if( res.collision.x ) { sx = 0; vx = 0; }
if( res.collision.y ) { sy = 0; vy = 0; }
if( res.collision.slope ) { break; }
}
}
// Just one step
else {
this._traceStep( res, x, y, vx, vy, objectWidth, objectHeight, vx, vy, 0 );
}
return res;
},
_traceStep: function( res, x, y, vx, vy, width, height, rvx, rvy, step ) {
res.pos.x += vx;
res.pos.y += vy;
var t = 0;
// Horizontal collision (walls)
if( vx ) {
var pxOffsetX = (vx > 0 ? width : 0);
var tileOffsetX = (vx < 0 ? this.tilesize : 0);
var firstTileY = Math.max( Math.floor(y / this.tilesize), 0 );
var lastTileY = Math.min( Math.ceil((y + height) / this.tilesize), this.height );
var tileX = Math.floor( (res.pos.x + pxOffsetX) / this.tilesize );
// We need to test the new tile position as well as the current one, as we
// could still collide with the current tile if it's a line def.
// We can skip this test if this is not the first step or the new tile position
// is the same as the current one.
var prevTileX = Math.floor( (x + pxOffsetX) / this.tilesize );
if( step > 0 || tileX == prevTileX || prevTileX < 0 || prevTileX >= this.width ) {
prevTileX = -1;
}
// Still inside this collision map?
if( tileX >= 0 && tileX < this.width ) {
for( var tileY = firstTileY; tileY < lastTileY; tileY++ ) {
if( prevTileX != -1 ) {
t = this.data[tileY][prevTileX];
if(
t > 1 && t <= this.lastSlope &&
this._checkTileDef(res, t, x, y, rvx, rvy, width, height, prevTileX, tileY)
) {
break;
}
}
t = this.data[tileY][tileX];
if(
t == 1 || t > this.lastSlope || // fully solid tile?
(t > 1 && this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, tileY)) // slope?
) {
if( t > 1 && t <= this.lastSlope && res.collision.slope ) {
break;
}
// full tile collision!
res.collision.x = true;
res.tile.x = t;
x = res.pos.x = tileX * this.tilesize - pxOffsetX + tileOffsetX;
rvx = 0;
break;
}
}
}
}
// Vertical collision (floor, ceiling)
if( vy ) {
var pxOffsetY = (vy > 0 ? height : 0);
var tileOffsetY = (vy < 0 ? this.tilesize : 0);
var firstTileX = Math.max( Math.floor(res.pos.x / this.tilesize), 0 );
var lastTileX = Math.min( Math.ceil((res.pos.x + width) / this.tilesize), this.width );
var tileY = Math.floor( (res.pos.y + pxOffsetY) / this.tilesize );
var prevTileY = Math.floor( (y + pxOffsetY) / this.tilesize );
if( step > 0 || tileY == prevTileY || prevTileY < 0 || prevTileY >= this.height ) {
prevTileY = -1;
}
// Still inside this collision map?
if( tileY >= 0 && tileY < this.height ) {
for( var tileX = firstTileX; tileX < lastTileX; tileX++ ) {
if( prevTileY != -1 ) {
t = this.data[prevTileY][tileX];
if(
t > 1 && t <= this.lastSlope &&
this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, prevTileY) ) {
break;
}
}
t = this.data[tileY][tileX];
if(
t == 1 || t > this.lastSlope || // fully solid tile?
(t > 1 && this._checkTileDef(res, t, x, y, rvx, rvy, width, height, tileX, tileY)) // slope?
) {
if( t > 1 && t <= this.lastSlope && res.collision.slope ) {
break;
}
// full tile collision!
res.collision.y = true;
res.tile.y = t;
res.pos.y = tileY * this.tilesize - pxOffsetY + tileOffsetY;
break;
}
}
}
}
// res is changed in place, nothing to return
},
_checkTileDef: function( res, t, x, y, vx, vy, width, height, tileX, tileY ) {
var def = this.tiledef[t];
if( !def ) { return false; }
var lx = (tileX + def[0]) * this.tilesize,
ly = (tileY + def[1]) * this.tilesize,
lvx = (def[2] - def[0]) * this.tilesize,
lvy = (def[3] - def[1]) * this.tilesize,
solid = def[4];
// Find the box corner to test, relative to the line
var tx = x + vx + (lvy < 0 ? width : 0) - lx,
ty = y + vy + (lvx > 0 ? height : 0) - ly;
// Is the box corner behind the line?
if( lvx * ty - lvy * tx > 0 ) {
// Lines are only solid from one side - find the dot product of
// line normal and movement vector and dismiss if wrong side
if( vx * -lvy + vy * lvx < 0 ) {
return solid;
}
// Find the line normal
var length = Math.sqrt(lvx * lvx + lvy * lvy);
var nx = lvy/length,
ny = -lvx/length;
// Project out of the line
var proj = tx * nx + ty * ny;
var px = nx * proj,
py = ny * proj;
// If we project further out than we moved in, then this is a full
// tile collision for solid tiles.
// For non-solid tiles, make sure we were in front of the line.
if( px*px+py*py >= vx*vx+vy*vy ) {
return solid || (lvx * (ty-vy) - lvy * (tx-vx) < 0.5);
}
res.pos.x = x + vx - px;
res.pos.y = y + vy - py;
res.collision.slope = {x: lvx, y: lvy, nx: nx, ny: ny};
return true;
}
return false;
}
});
// Default Slope Tile definition. Each tile is defined by an array of 5 vars:
// - 4 for the line in tile coordinates (0 -- 1)
// - 1 specifing whether the tile is 'filled' behind the line or not
// [ x1, y1, x2, y2, solid ]
// Defining 'half', 'one third' and 'two thirds' as vars makes it a bit
// easier to read... I hope.
var H = 1/2,
N = 1/3,
M = 2/3,
SOLID = true,
NON_SOLID = false;
ig.CollisionMap.defaultTileDef = {
/* 15 NE */ 5: [0,1, 1,M, SOLID], 6: [0,M, 1,N, SOLID], 7: [0,N, 1,0, SOLID],
/* 22 NE */ 3: [0,1, 1,H, SOLID], 4: [0,H, 1,0, SOLID],
/* 45 NE */ 2: [0,1, 1,0, SOLID],
/* 67 NE */ 10: [H,1, 1,0, SOLID], 21: [0,1, H,0, SOLID],
/* 75 NE */ 32: [M,1, 1,0, SOLID], 43: [N,1, M,0, SOLID], 54: [0,1, N,0, SOLID],
/* 15 SE */ 27: [0,0, 1,N, SOLID], 28: [0,N, 1,M, SOLID], 29: [0,M, 1,1, SOLID],
/* 22 SE */ 25: [0,0, 1,H, SOLID], 26: [0,H, 1,1, SOLID],
/* 45 SE */ 24: [0,0, 1,1, SOLID],
/* 67 SE */ 11: [0,0, H,1, SOLID], 22: [H,0, 1,1, SOLID],
/* 75 SE */ 33: [0,0, N,1, SOLID], 44: [N,0, M,1, SOLID], 55: [M,0, 1,1, SOLID],
/* 15 NW */ 16: [1,N, 0,0, SOLID], 17: [1,M, 0,N, SOLID], 18: [1,1, 0,M, SOLID],
/* 22 NW */ 14: [1,H, 0,0, SOLID], 15: [1,1, 0,H, SOLID],
/* 45 NW */ 13: [1,1, 0,0, SOLID],
/* 67 NW */ 8: [H,1, 0,0, SOLID], 19: [1,1, H,0, SOLID],
/* 75 NW */ 30: [N,1, 0,0, SOLID], 41: [M,1, N,0, SOLID], 52: [1,1, M,0, SOLID],
/* 15 SW */ 38: [1,M, 0,1, SOLID], 39: [1,N, 0,M, SOLID], 40: [1,0, 0,N, SOLID],
/* 22 SW */ 36: [1,H, 0,1, SOLID], 37: [1,0, 0,H, SOLID],
/* 45 SW */ 35: [1,0, 0,1, SOLID],
/* 67 SW */ 9: [1,0, H,1, SOLID], 20: [H,0, 0,1, SOLID],
/* 75 SW */ 31: [1,0, M,1, SOLID], 42: [M,0, N,1, SOLID], 53: [N,0, 0,1, SOLID],
/* Go N */ 12: [0,0, 1,0, NON_SOLID],
/* Go S */ 23: [1,1, 0,1, NON_SOLID],
/* Go E */ 34: [1,0, 1,1, NON_SOLID],
/* Go W */ 45: [0,1, 0,0, NON_SOLID]
// Now that was fun!
};
// Static Dummy CollisionMap; never collides
ig.CollisionMap.staticNoCollision = { trace: function( x, y, vx, vy ) {
return {
collision: {x: false, y: false, slope: false},
pos: {x: x+vx, y: y+vy},
tile: {x: 0, y: 0}
};
}};
});
+148
View File
@@ -0,0 +1,148 @@
.ig_debug {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #000;
border-top: 2px solid #f57401;
font-size: 12px;
color: #fff;
z-index: 1000;
-webkit-user-select: none;
}
.ig_debug_panel_menu {
height: 28px;
background: #222;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0,#000000), color-stop(1,#333));
background: -moz-linear-gradient(center bottom, #000000 0%, #333 100%);
background: -o-linear-gradient(#333, #000000);
}
.ig_debug_panel_menu div {
float: left;
height: 22px;
padding: 6px 8px 0 8px;
border-right: 1px solid #333;
}
.ig_debug_panel_menu .ig_debug_head {
font-weight: bold;
color: #888;
}
.ig_debug_menu_item:hover {
cursor: pointer;
background-color: #fff;
color: #000;
}
.ig_debug_menu_item.active, .ig_debug_menu_item.active:hover {
background-color: #000;
color: #fff;
}
.ig_debug_stats {
position: absolute;
right: 0;
top: 0;
float: right;
color: #888;
border-left: 1px solid #333;
text-align: right;
}
.ig_debug_stats span {
width: 3em;
display:inline-block;
color: #fff !important;
margin-right: 0.2em;
margin-left: 0.3em;
font-family: bitstream vera sans mono, courier new;
white-space: nowrap;
}
.ig_debug_panel {
height: 152px;
overflow: auto;
position: relative;
}
.ig_debug_panel canvas {
border-bottom: 1px solid #444;
}
.ig_debug_panel .ig_debug_panel {
padding: 8px;
height: auto;
float: left;
background-color: #000;
border-right: 2px solid #222;
}
.ig_debug_option {
padding: 2px 0 2px 8px;
cursor: pointer;
}
.ig_debug_option:first-child {
margin-top: 8px;
}
.ig_debug_option:hover {
background-color: #111;
}
.ig_debug_graph_mark {
position: absolute;
color: #888;
left: 4px;
font-size: 10px;
margin-top: -12px;
}
.ig_debug_legend {
color: #ccc;
}
.ig_debug_label_mark {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 4px;
-webkit-transition: 0.1s linear;
-moz-transition: 0.1s linear;
}
.ig_debug_legend_color {
display: inline-block;
width: 6px;
height: 10px;
margin-right: 4px;
margin-left: 16px;
}
.ig_debug_legend_number {
width: 3em;
display: inline-block;
text-align: right;
font-family: bitstream vera sans mono, courier new;
color: #fff;
margin-right: 0.2em;
}
.ig_debug_map_container {
position: relative;
overflow: hidden;
border: 1px solid #888;
}
.ig_debug_map_container canvas {
position: absolute;
}
.ig_debug_map_screen {
position: absolute;
border: 1px solid #f0f;
}
+13
View File
@@ -0,0 +1,13 @@
ig.module(
'impact.debug.debug'
)
.requires(
'impact.debug.entities-panel',
'impact.debug.maps-panel',
'impact.debug.graph-panel'
)
.defines(function(){ "use strict";
/* Empty module to require all debug panels */
});
+129
View File
@@ -0,0 +1,129 @@
ig.module(
'impact.debug.entities-panel'
)
.requires(
'impact.debug.menu',
'impact.entity'
)
.defines(function(){ "use strict";
ig.Entity.inject({
colors: {
names: '#fff',
velocities: '#0f0',
boxes: '#f00'
},
draw: function() {
this.parent();
// Collision Boxes
if( ig.Entity._debugShowBoxes ) {
ig.system.context.strokeStyle = this.colors.boxes;
ig.system.context.lineWidth = 1.0;
ig.system.context.strokeRect(
ig.system.getDrawPos(this.pos.x.round() - ig.game.screen.x) - 0.5,
ig.system.getDrawPos(this.pos.y.round() - ig.game.screen.y) - 0.5,
this.size.x * ig.system.scale,
this.size.y * ig.system.scale
);
}
// Velocities
if( ig.Entity._debugShowVelocities ) {
var x = this.pos.x + this.size.x/2;
var y = this.pos.y + this.size.y/2;
this._debugDrawLine( this.colors.velocities, x, y, x + this.vel.x, y + this.vel.y );
}
// Names & Targets
if( ig.Entity._debugShowNames ) {
if( this.name ) {
ig.system.context.fillStyle = this.colors.names;
ig.system.context.fillText(
this.name,
ig.system.getDrawPos(this.pos.x - ig.game.screen.x),
ig.system.getDrawPos(this.pos.y - ig.game.screen.y)
);
}
if( typeof(this.target) == 'object' ) {
for( var t in this.target ) {
var ent = ig.game.getEntityByName( this.target[t] );
if( ent ) {
this._debugDrawLine( this.colors.names,
this.pos.x + this.size.x/2, this.pos.y + this.size.y/2,
ent.pos.x + ent.size.x/2, ent.pos.y + ent.size.y/2
);
}
}
}
}
},
_debugDrawLine: function( color, sx, sy, dx, dy ) {
ig.system.context.strokeStyle = color;
ig.system.context.lineWidth = 1.0;
ig.system.context.beginPath();
ig.system.context.moveTo(
ig.system.getDrawPos(sx - ig.game.screen.x),
ig.system.getDrawPos(sy - ig.game.screen.y)
);
ig.system.context.lineTo(
ig.system.getDrawPos(dx - ig.game.screen.x),
ig.system.getDrawPos(dy - ig.game.screen.y)
);
ig.system.context.stroke();
ig.system.context.closePath();
}
});
ig.Entity._debugEnableChecks = true;
ig.Entity._debugShowBoxes = false;
ig.Entity._debugShowVelocities = false;
ig.Entity._debugShowNames = false;
ig.Entity.oldCheckPair = ig.Entity.checkPair;
ig.Entity.checkPair = function( a, b ) {
if( !ig.Entity._debugEnableChecks ) {
return;
}
ig.Entity.oldCheckPair( a, b );
};
ig.debug.addPanel({
type: ig.DebugPanel,
name: 'entities',
label: 'Entities',
options: [
{
name: 'Checks & Collisions',
object: ig.Entity,
property: '_debugEnableChecks'
},
{
name: 'Show Collision Boxes',
object: ig.Entity,
property: '_debugShowBoxes'
},
{
name: 'Show Velocities',
object: ig.Entity,
property: '_debugShowVelocities'
},
{
name: 'Show Names & Targets',
object: ig.Entity,
property: '_debugShowNames'
}
]
});
});
+198
View File
@@ -0,0 +1,198 @@
ig.module(
'impact.debug.graph-panel'
)
.requires(
'impact.debug.menu',
'impact.system',
'impact.game',
'impact.image'
)
.defines(function(){ "use strict";
ig.Game.inject({
draw: function() {
ig.graph.beginClock('draw');
this.parent();
ig.graph.endClock('draw');
},
update: function() {
ig.graph.beginClock('update');
this.parent();
ig.graph.endClock('update');
},
checkEntities: function() {
ig.graph.beginClock('checks');
this.parent();
ig.graph.endClock('checks');
}
});
ig.DebugGraphPanel = ig.DebugPanel.extend({
clocks: {},
marks: [],
textY: 0,
height: 128,
ms: 64,
timeBeforeRun: 0,
init: function( name, label ) {
this.parent( name, label );
this.mark16ms = (this.height - (this.height/this.ms) * 16).round();
this.mark33ms = (this.height - (this.height/this.ms) * 33).round();
this.msHeight = this.height/this.ms;
this.graph = ig.$new('canvas');
this.graph.width = window.innerWidth;
this.graph.height = this.height;
this.container.appendChild( this.graph );
this.ctx = this.graph.getContext('2d');
this.ctx.fillStyle = '#444';
this.ctx.fillRect( 0, this.mark16ms, this.graph.width, 1 );
this.ctx.fillRect( 0, this.mark33ms, this.graph.width, 1 );
this.addGraphMark( '16ms', this.mark16ms );
this.addGraphMark( '33ms', this.mark33ms );
this.addClock( 'draw', 'Draw', '#13baff' );
this.addClock( 'update', 'Entity Update', '#bb0fff' );
this.addClock( 'checks', 'Entity Checks & Collisions', '#a2e908' );
this.addClock( 'lag', 'System Lag', '#f26900' );
ig.mark = this.mark.bind(this);
ig.graph = this;
},
addGraphMark: function( name, height ) {
var span = ig.$new('span');
span.className = 'ig_debug_graph_mark';
span.textContent = name;
span.style.top = height.round() + 'px';
this.container.appendChild( span );
},
addClock: function( name, description, color ) {
var mark = ig.$new('span');
mark.className = 'ig_debug_legend_color';
mark.style.backgroundColor = color;
var number = ig.$new('span');
number.className = 'ig_debug_legend_number';
number.appendChild( document.createTextNode('0') );
var legend = ig.$new('span');
legend.className = 'ig_debug_legend';
legend.appendChild( mark );
legend.appendChild( document.createTextNode(description +' (') );
legend.appendChild( number );
legend.appendChild( document.createTextNode('ms)') );
this.container.appendChild( legend );
this.clocks[name] = {
description: description,
color: color,
current: 0,
start: Date.now(),
avg: 0,
html: number
};
},
beginClock: function( name, offset ) {
this.clocks[name].start = Date.now() + (offset || 0);
},
endClock: function( name ) {
var c = this.clocks[name];
c.current = Math.round(Date.now() - c.start);
c.avg = c.avg * 0.8 + c.current * 0.2;
},
mark: function( msg, color ) {
if( this.active ) {
this.marks.push( {msg:msg, color:(color||'#fff')} );
}
},
beforeRun: function() {
this.endClock('lag');
this.timeBeforeRun = Date.now();
},
afterRun: function() {
var frameTime = Date.now() - this.timeBeforeRun;
var nextFrameDue = (1000/ig.system.fps) - frameTime;
this.beginClock('lag', Math.max(nextFrameDue, 0));
var x = this.graph.width-1;
var y = this.height;
this.ctx.drawImage( this.graph, -1, 0 );
this.ctx.fillStyle = '#000';
this.ctx.fillRect( x, 0, 1, this.height );
this.ctx.fillStyle = '#444';
this.ctx.fillRect( x, this.mark16ms, 1, 1 );
this.ctx.fillStyle = '#444';
this.ctx.fillRect( x, this.mark33ms, 1, 1 );
for( var ci in this.clocks ) {
var c = this.clocks[ci];
c.html.textContent = c.avg.toFixed(2);
if( c.color && c.current > 0 ) {
this.ctx.fillStyle = c.color;
var h = c.current * this.msHeight;
y -= h;
this.ctx.fillRect( x, y, 1, h );
c.current = 0;
}
}
this.ctx.textAlign = 'right';
this.ctx.textBaseline = 'top';
this.ctx.globalAlpha = 0.5;
for( var i = 0; i < this.marks.length; i++ ) {
var m = this.marks[i];
this.ctx.fillStyle = m.color;
this.ctx.fillRect( x, 0, 1, this.height );
if( m.msg ) {
this.ctx.fillText( m.msg, x-1, this.textY );
this.textY = (this.textY+8)%32;
}
}
this.ctx.globalAlpha = 1;
this.marks = [];
}
});
ig.debug.addPanel({
type: ig.DebugGraphPanel,
name: 'graph',
label: 'Performance'
});
});
+156
View File
@@ -0,0 +1,156 @@
ig.module(
'impact.debug.maps-panel'
)
.requires(
'impact.debug.menu',
'impact.game',
'impact.background-map'
)
.defines(function(){ "use strict";
ig.Game.inject({
loadLevel: function( data ) {
this.parent(data);
ig.debug.panels.maps.load(this);
}
});
ig.DebugMapsPanel = ig.DebugPanel.extend({
maps: [],
mapScreens: [],
init: function( name, label ) {
this.parent( name, label );
this.load();
},
load: function( game ) {
this.options = [];
this.panels = [];
if( !game || !game.backgroundMaps.length ) {
this.container.innerHTML = '<em>No Maps Loaded</em>';
return;
}
this.maps = game.backgroundMaps;
this.mapScreens = [];
this.container.innerHTML = '';
for( var m = 0; m < this.maps.length; m++ ) {
var map = this.maps[m];
var subPanel = new ig.DebugPanel( m, 'Layer '+m );
var head = new ig.$new('strong');
head.textContent = m +': ' + map.tiles.path;
subPanel.container.appendChild( head );
subPanel.addOption( new ig.DebugOption('Enabled', map, 'enabled') );
subPanel.addOption( new ig.DebugOption('Pre Rendered', map, 'preRender') );
subPanel.addOption( new ig.DebugOption('Show Chunks', map, 'debugChunks') );
this.generateMiniMap( subPanel, map, m );
this.addPanel( subPanel );
}
},
generateMiniMap: function( panel, map, id ) {
var s = ig.system.scale; // we'll need this a lot
// resize the tileset, so that one tile is 's' pixels wide and high
var ts = ig.$new('canvas');
var tsctx = ts.getContext('2d');
var w = map.tiles.width * s;
var h = map.tiles.height * s;
var ws = w / map.tilesize;
var hs = h / map.tilesize;
ts.width = ws;
ts.height = hs;
tsctx.drawImage( map.tiles.data, 0, 0, w, h, 0, 0, ws, hs );
// create the minimap canvas
var mapCanvas = ig.$new('canvas');
mapCanvas.width = map.width * s;
mapCanvas.height = map.height * s;
var ctx = mapCanvas.getContext('2d');
if( ig.game.clearColor ) {
ctx.fillStyle = ig.game.clearColor;
ctx.fillRect(0, 0, w, h);
}
// draw the map
var tile = 0;
for( var x = 0; x < map.width; x++ ) {
for( var y = 0; y < map.height; y++ ) {
if( (tile = map.data[y][x]) ) {
ctx.drawImage(
ts,
Math.floor(((tile-1) * s) % ws),
Math.floor((tile-1) * s / ws) * s,
s, s,
x * s, y * s,
s, s
);
}
}
}
var mapContainer = ig.$new('div');
mapContainer.className = 'ig_debug_map_container';
mapContainer.style.width = map.width * s + 'px';
mapContainer.style.height = map.height * s + 'px';
var mapScreen = ig.$new('div');
mapScreen.className = 'ig_debug_map_screen';
mapScreen.style.width = ((ig.system.width / map.tilesize) * s - 2) + 'px';
mapScreen.style.height = ((ig.system.height / map.tilesize) * s - 2) + 'px';
this.mapScreens[id] = mapScreen;
mapContainer.appendChild( mapCanvas );
mapContainer.appendChild( mapScreen );
panel.container.appendChild( mapContainer );
},
afterRun: function() {
// Update the screen position DIV for each mini-map
var s = ig.system.scale;
for( var m = 0; m < this.maps.length; m++ ) {
var map = this.maps[m];
var screen = this.mapScreens[m];
if( !map || !screen ) { // Quick sanity check
continue;
}
var x = map.scroll.x / map.tilesize;
var y = map.scroll.y / map.tilesize;
if( map.repeat ) {
x %= map.width;
y %= map.height;
}
screen.style.left = (x * s) + 'px';
screen.style.top = (y * s) + 'px';
}
}
});
ig.debug.addPanel({
type: ig.DebugMapsPanel,
name: 'maps',
label: 'Background Maps'
});
});
+299
View File
@@ -0,0 +1,299 @@
ig.module(
'impact.debug.menu'
)
.requires(
'dom.ready',
'impact.system'
)
.defines(function(){ "use strict";
ig.System.inject({
run: function() {
ig.debug.beforeRun();
this.parent();
ig.debug.afterRun();
},
setGameNow: function( gameClass ) {
this.parent( gameClass );
ig.debug.ready();
}
});
ig.Debug = ig.Class.extend({
options: {},
panels: {},
numbers:{},
container: null,
panelMenu: null,
activePanel: null,
debugTime: 0,
debugTickAvg: 0.016,
debugRealTime: Date.now(),
init: function() {
// Inject the Stylesheet
var style = ig.$new('link');
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = ig.prefix + 'lib/impact/debug/debug.css';
ig.$('body')[0].appendChild( style );
// Create the Debug Container
this.container = ig.$new('div');
this.container.className ='ig_debug';
ig.$('body')[0].appendChild( this.container );
// Create and add the Menu Container
this.panelMenu = ig.$new('div');
this.panelMenu.innerHTML = '<div class="ig_debug_head">Impact.Debug:</div>';
this.panelMenu.className ='ig_debug_panel_menu';
this.container.appendChild( this.panelMenu );
// Create and add the Stats Container
this.numberContainer = ig.$new('div');
this.numberContainer.className ='ig_debug_stats';
this.panelMenu.appendChild( this.numberContainer );
// Set ig.log(), ig.assert() and ig.show()
if( window.console && window.console.log && window.console.assert ) {
// Can't use .bind() on native functions in IE9 :/
ig.log = console.log.bind ? console.log.bind(console) : console.log;
ig.assert = console.assert.bind ? console.assert.bind(console) : console.assert;
}
ig.show = this.showNumber.bind(this);
},
addNumber: function( name, width ) {
var number = ig.$new('span');
this.numberContainer.appendChild( number );
this.numberContainer.appendChild( document.createTextNode(name) );
this.numbers[name] = number;
},
showNumber: function( name, number, width ) {
if( !this.numbers[name] ) {
this.addNumber( name, width );
}
this.numbers[name].textContent = number;
},
addPanel: function( panelDef ) {
// Create the panel and options
var panel = new (panelDef.type)( panelDef.name, panelDef.label );
if( panelDef.options ) {
for( var i = 0; i < panelDef.options.length; i++ ) {
var opt = panelDef.options[i];
panel.addOption( new ig.DebugOption(opt.name, opt.object, opt.property) );
}
}
this.panels[ panel.name ] = panel;
panel.container.style.display = 'none';
this.container.appendChild( panel.container );
// Create the menu item
var menuItem = ig.$new('div');
menuItem.className = 'ig_debug_menu_item';
menuItem.textContent = panel.label;
menuItem.addEventListener(
'click',
(function(ev){ this.togglePanel(panel); }).bind(this),
false
);
panel.menuItem = menuItem;
// Insert menu item in alphabetical order into the menu
var inserted = false;
for( var i = 1; i < this.panelMenu.childNodes.length; i++ ) {
var cn = this.panelMenu.childNodes[i];
if( cn.textContent > panel.label ) {
this.panelMenu.insertBefore( menuItem, cn );
inserted = true;
break;
}
}
if( !inserted ) {
// Not inserted? Append at the end!
this.panelMenu.appendChild( menuItem );
}
},
showPanel: function( name ) {
this.togglePanel( this.panels[name] );
},
togglePanel: function( panel ) {
if( panel != this.activePanel && this.activePanel ) {
this.activePanel.toggle( false );
this.activePanel.menuItem.className = 'ig_debug_menu_item';
this.activePanel = null;
}
var dsp = panel.container.style.display;
var active = (dsp != 'block');
panel.toggle( active );
panel.menuItem.className = 'ig_debug_menu_item' + (active ? ' active' : '');
if( active ) {
this.activePanel = panel;
}
},
ready: function() {
for( var p in this.panels ) {
this.panels[p].ready();
}
},
beforeRun: function() {
var timeBeforeRun = Date.now();
this.debugTickAvg = this.debugTickAvg * 0.8 + (timeBeforeRun - this.debugRealTime) * 0.2;
this.debugRealTime = timeBeforeRun;
if( this.activePanel ) {
this.activePanel.beforeRun();
}
},
afterRun: function() {
var frameTime = Date.now() - this.debugRealTime;
var nextFrameDue = (1000/ig.system.fps) - frameTime;
this.debugTime = this.debugTime * 0.8 + frameTime * 0.2;
if( this.activePanel ) {
this.activePanel.afterRun();
}
this.showNumber( 'ms', this.debugTime.toFixed(2) );
this.showNumber( 'fps', Math.round(1000/this.debugTickAvg) );
this.showNumber( 'draws', ig.Image.drawCount );
if( ig.game && ig.game.entities ) {
this.showNumber( 'entities', ig.game.entities.length );
}
ig.Image.drawCount = 0;
}
});
ig.DebugPanel = ig.Class.extend({
active: false,
container: null,
options: [],
panels: [],
label: '',
name: '',
init: function( name, label ) {
this.name = name;
this.label = label;
this.container = ig.$new('div');
this.container.className = 'ig_debug_panel ' + this.name;
},
toggle: function( active ) {
this.active = active;
this.container.style.display = active ? 'block' : 'none';
},
addPanel: function( panel ) {
this.panels.push( panel );
this.container.appendChild( panel.container );
},
addOption: function( option ) {
this.options.push( option );
this.container.appendChild( option.container );
},
ready: function(){},
beforeRun: function(){},
afterRun: function(){}
});
ig.DebugOption = ig.Class.extend({
name: '',
labelName: '',
className: 'ig_debug_option',
label: null,
mark: null,
container: null,
active: false,
colors: {
enabled: '#fff',
disabled: '#444'
},
init: function( name, object, property ) {
this.name = name;
this.object = object;
this.property = property;
this.active = this.object[this.property];
this.container = ig.$new('div');
this.container.className = 'ig_debug_option';
this.label = ig.$new('span');
this.label.className = 'ig_debug_label';
this.label.textContent = this.name;
this.mark = ig.$new('span');
this.mark.className = 'ig_debug_label_mark';
this.container.appendChild( this.mark );
this.container.appendChild( this.label );
this.container.addEventListener( 'click', this.click.bind(this), false );
this.setLabel();
},
setLabel: function() {
this.mark.style.backgroundColor = this.active ? this.colors.enabled : this.colors.disabled;
},
click: function( ev ) {
this.active = !this.active;
this.object[this.property] = this.active;
this.setLabel();
ev.stopPropagation();
ev.preventDefault();
return false;
}
});
// Create the debug instance!
ig.debug = new ig.Debug();
});
+60
View File
@@ -0,0 +1,60 @@
ig.module(
'impact.entity-pool'
)
.requires(
'impact.game'
)
.defines(function(){ "use strict";
ig.EntityPool = {
pools: {},
mixin: {
staticInstantiate: function( x, y, settings ) {
return ig.EntityPool.getFromPool( this.classId, x, y, settings );
},
erase: function() {
ig.EntityPool.putInPool( this );
}
},
enableFor: function( Class ) {
Class.inject(this.mixin);
},
getFromPool: function( classId, x, y, settings ) {
var pool = this.pools[classId];
if( !pool || !pool.length ) { return null; }
var instance = pool.pop();
instance.reset(x, y, settings);
return instance;
},
putInPool: function( instance ) {
if( !this.pools[instance.classId] ) {
this.pools[instance.classId] = [instance];
}
else {
this.pools[instance.classId].push(instance);
}
},
drainPool: function( classId ) {
delete this.pools[classId];
},
drainAllPools: function() {
this.pools = {};
}
};
ig.Game.inject({
loadLevel: function( data ) {
ig.EntityPool.drainAllPools();
this.parent(data);
}
});
});
+434
View File
@@ -0,0 +1,434 @@
ig.module(
'impact.entity'
)
.requires(
'impact.animation',
'impact.impact'
)
.defines(function(){ "use strict";
ig.Entity = ig.Class.extend({
id: 0,
settings: {},
size: {x: 16, y:16},
offset: {x: 0, y: 0},
pos: {x: 0, y:0},
last: {x: 0, y:0},
vel: {x: 0, y: 0},
accel: {x: 0, y: 0},
friction: {x: 0, y: 0},
maxVel: {x: 100, y: 100},
zIndex: 0,
gravityFactor: 1,
standing: false,
bounciness: 0,
minBounceVelocity: 40,
anims: {},
animSheet: null,
currentAnim: null,
health: 10,
type: 0, // TYPE.NONE
checkAgainst: 0, // TYPE.NONE
collides: 0, // COLLIDES.NEVER
_killed: false,
slopeStanding: {min: (44).toRad(), max: (136).toRad() },
init: function( x, y, settings ) {
this.id = ++ig.Entity._lastId;
this.pos.x = this.last.x = x;
this.pos.y = this.last.y = y;
ig.merge( this, settings );
},
reset: function( x, y, settings ) {
var proto = this.constructor.prototype;
this.pos.x = x;
this.pos.y = y;
this.last.x = x;
this.last.y = y;
this.vel.x = proto.vel.x;
this.vel.y = proto.vel.y;
this.accel.x = proto.accel.x;
this.accel.y = proto.accel.y;
this.health = proto.health;
this._killed = proto._killed;
this.standing = proto.standing;
this.type = proto.type;
this.checkAgainst = proto.checkAgainst;
this.collides = proto.collides;
ig.merge( this, settings );
},
addAnim: function( name, frameTime, sequence, stop ) {
if( !this.animSheet ) {
throw( 'No animSheet to add the animation '+name+' to.' );
}
var a = new ig.Animation( this.animSheet, frameTime, sequence, stop );
this.anims[name] = a;
if( !this.currentAnim ) {
this.currentAnim = a;
}
return a;
},
update: function() {
this.last.x = this.pos.x;
this.last.y = this.pos.y;
this.vel.y += ig.game.gravity * ig.system.tick * this.gravityFactor;
this.vel.x = this.getNewVelocity( this.vel.x, this.accel.x, this.friction.x, this.maxVel.x );
this.vel.y = this.getNewVelocity( this.vel.y, this.accel.y, this.friction.y, this.maxVel.y );
// movement & collision
var mx = this.vel.x * ig.system.tick;
var my = this.vel.y * ig.system.tick;
var res = ig.game.collisionMap.trace(
this.pos.x, this.pos.y, mx, my, this.size.x, this.size.y
);
this.handleMovementTrace( res );
if( this.currentAnim ) {
this.currentAnim.update();
}
},
getNewVelocity: function( vel, accel, friction, max ) {
if( accel ) {
return ( vel + accel * ig.system.tick ).limit( -max, max );
}
else if( friction ) {
var delta = friction * ig.system.tick;
if( vel - delta > 0) {
return vel - delta;
}
else if( vel + delta < 0 ) {
return vel + delta;
}
else {
return 0;
}
}
return vel.limit( -max, max );
},
handleMovementTrace: function( res ) {
this.standing = false;
if( res.collision.y ) {
if( this.bounciness > 0 && Math.abs(this.vel.y) > this.minBounceVelocity ) {
this.vel.y *= -this.bounciness;
}
else {
if( this.vel.y > 0 ) {
this.standing = true;
}
this.vel.y = 0;
}
}
if( res.collision.x ) {
if( this.bounciness > 0 && Math.abs(this.vel.x) > this.minBounceVelocity ) {
this.vel.x *= -this.bounciness;
}
else {
this.vel.x = 0;
}
}
if( res.collision.slope ) {
var s = res.collision.slope;
if( this.bounciness > 0 ) {
var proj = this.vel.x * s.nx + this.vel.y * s.ny;
this.vel.x = (this.vel.x - s.nx * proj * 2) * this.bounciness;
this.vel.y = (this.vel.y - s.ny * proj * 2) * this.bounciness;
}
else {
var lengthSquared = s.x * s.x + s.y * s.y;
var dot = (this.vel.x * s.x + this.vel.y * s.y)/lengthSquared;
this.vel.x = s.x * dot;
this.vel.y = s.y * dot;
var angle = Math.atan2( s.x, s.y );
if( angle > this.slopeStanding.min && angle < this.slopeStanding.max ) {
this.standing = true;
}
}
}
this.pos = res.pos;
},
draw: function() {
if( this.currentAnim ) {
this.currentAnim.draw(
this.pos.x - this.offset.x - ig.game._rscreen.x,
this.pos.y - this.offset.y - ig.game._rscreen.y
);
}
},
kill: function() {
ig.game.removeEntity( this );
},
receiveDamage: function( amount, from ) {
this.health -= amount;
if( this.health <= 0 ) {
this.kill();
}
},
touches: function( other ) {
return !(
this.pos.x >= other.pos.x + other.size.x ||
this.pos.x + this.size.x <= other.pos.x ||
this.pos.y >= other.pos.y + other.size.y ||
this.pos.y + this.size.y <= other.pos.y
);
},
distanceTo: function( other ) {
var xd = (this.pos.x + this.size.x/2) - (other.pos.x + other.size.x/2);
var yd = (this.pos.y + this.size.y/2) - (other.pos.y + other.size.y/2);
return Math.sqrt( xd*xd + yd*yd );
},
angleTo: function( other ) {
return Math.atan2(
(other.pos.y + other.size.y/2) - (this.pos.y + this.size.y/2),
(other.pos.x + other.size.x/2) - (this.pos.x + this.size.x/2)
);
},
check: function( other ) {},
collideWith: function( other, axis ) {},
ready: function() {},
erase: function() {}
});
// Last used entity id; incremented with each spawned entity
ig.Entity._lastId = 0;
// Collision Types - Determine if and how entities collide with each other
// In ACTIVE vs. LITE or FIXED vs. ANY collisions, only the "weak" entity moves,
// while the other one stays fixed. In ACTIVE vs. ACTIVE and ACTIVE vs. PASSIVE
// collisions, both entities are moved. LITE or PASSIVE entities don't collide
// with other LITE or PASSIVE entities at all. The behaiviour for FIXED vs.
// FIXED collisions is undefined.
ig.Entity.COLLIDES = {
NEVER: 0,
LITE: 1,
PASSIVE: 2,
ACTIVE: 4,
FIXED: 8
};
// Entity Types - used for checks
ig.Entity.TYPE = {
NONE: 0,
A: 1,
B: 2,
BOTH: 3
};
ig.Entity.checkPair = function( a, b ) {
// Do these entities want checks?
if( a.checkAgainst & b.type ) {
a.check( b );
}
if( b.checkAgainst & a.type ) {
b.check( a );
}
// If this pair allows collision, solve it! At least one entity must
// collide ACTIVE or FIXED, while the other one must not collide NEVER.
if(
a.collides && b.collides &&
a.collides + b.collides > ig.Entity.COLLIDES.ACTIVE
) {
ig.Entity.solveCollision( a, b );
}
};
ig.Entity.solveCollision = function( a, b ) {
// If one entity is FIXED, or the other entity is LITE, the weak
// (FIXED/NON-LITE) entity won't move in collision response
var weak = null;
if(
a.collides == ig.Entity.COLLIDES.LITE ||
b.collides == ig.Entity.COLLIDES.FIXED
) {
weak = a;
}
else if(
b.collides == ig.Entity.COLLIDES.LITE ||
a.collides == ig.Entity.COLLIDES.FIXED
) {
weak = b;
}
// Did they already overlap on the X-axis in the last frame? If so,
// this must be a vertical collision!
if(
a.last.x + a.size.x > b.last.x &&
a.last.x < b.last.x + b.size.x
) {
// Which one is on top?
if( a.last.y < b.last.y ) {
ig.Entity.seperateOnYAxis( a, b, weak );
}
else {
ig.Entity.seperateOnYAxis( b, a, weak );
}
a.collideWith( b, 'y' );
b.collideWith( a, 'y' );
}
// Horizontal collision
else if(
a.last.y + a.size.y > b.last.y &&
a.last.y < b.last.y + b.size.y
){
// Which one is on the left?
if( a.last.x < b.last.x ) {
ig.Entity.seperateOnXAxis( a, b, weak );
}
else {
ig.Entity.seperateOnXAxis( b, a, weak );
}
a.collideWith( b, 'x' );
b.collideWith( a, 'x' );
}
};
// FIXME: This is a mess. Instead of doing all the movements here, the entities
// should get notified of the collision (with all details) and resolve it
// themselfs.
ig.Entity.seperateOnXAxis = function( left, right, weak ) {
var nudge = (left.pos.x + left.size.x - right.pos.x);
// We have a weak entity, so just move this one
if( weak ) {
var strong = left === weak ? right : left;
weak.vel.x = -weak.vel.x * weak.bounciness + strong.vel.x;
var resWeak = ig.game.collisionMap.trace(
weak.pos.x, weak.pos.y, weak == left ? -nudge : nudge, 0, weak.size.x, weak.size.y
);
weak.pos.x = resWeak.pos.x;
}
// Normal collision - both move
else {
var v2 = (left.vel.x - right.vel.x)/2;
left.vel.x = -v2;
right.vel.x = v2;
var resLeft = ig.game.collisionMap.trace(
left.pos.x, left.pos.y, -nudge/2, 0, left.size.x, left.size.y
);
left.pos.x = Math.floor(resLeft.pos.x);
var resRight = ig.game.collisionMap.trace(
right.pos.x, right.pos.y, nudge/2, 0, right.size.x, right.size.y
);
right.pos.x = Math.ceil(resRight.pos.x);
}
};
ig.Entity.seperateOnYAxis = function( top, bottom, weak ) {
var nudge = (top.pos.y + top.size.y - bottom.pos.y);
// We have a weak entity, so just move this one
if( weak ) {
var strong = top === weak ? bottom : top;
weak.vel.y = -weak.vel.y * weak.bounciness + strong.vel.y;
// Riding on a platform?
var nudgeX = 0;
if( weak == top && Math.abs(weak.vel.y - strong.vel.y) < weak.minBounceVelocity ) {
weak.standing = true;
nudgeX = strong.vel.x * ig.system.tick;
}
var resWeak = ig.game.collisionMap.trace(
weak.pos.x, weak.pos.y, nudgeX, weak == top ? -nudge : nudge, weak.size.x, weak.size.y
);
weak.pos.y = resWeak.pos.y;
weak.pos.x = resWeak.pos.x;
}
// Bottom entity is standing - just bounce the top one
else if( ig.game.gravity && (bottom.standing || top.vel.y > 0) ) {
var resTop = ig.game.collisionMap.trace(
top.pos.x, top.pos.y, 0, -(top.pos.y + top.size.y - bottom.pos.y), top.size.x, top.size.y
);
top.pos.y = resTop.pos.y;
if( top.bounciness > 0 && top.vel.y > top.minBounceVelocity ) {
top.vel.y *= -top.bounciness;
}
else {
top.standing = true;
top.vel.y = 0;
}
}
// Normal collision - both move
else {
var v2 = (top.vel.y - bottom.vel.y)/2;
top.vel.y = -v2;
bottom.vel.y = v2;
var nudgeX = bottom.vel.x * ig.system.tick;
var resTop = ig.game.collisionMap.trace(
top.pos.x, top.pos.y, nudgeX, -nudge/2, top.size.x, top.size.y
);
top.pos.y = resTop.pos.y;
var resBottom = ig.game.collisionMap.trace(
bottom.pos.x, bottom.pos.y, 0, nudge/2, bottom.size.x, bottom.size.y
);
bottom.pos.y = resBottom.pos.y;
}
};
});
+152
View File
@@ -0,0 +1,152 @@
ig.module(
'impact.font'
)
.requires(
'impact.image'
)
.defines(function(){ "use strict";
ig.Font = ig.Image.extend({
widthMap: [],
indices: [],
firstChar: 32,
alpha: 1,
letterSpacing: 1,
lineSpacing: 0,
onload: function( ev ) {
this._loadMetrics( this.data );
this.parent( ev );
},
widthForString: function( text ) {
// Multiline?
if( text.indexOf('\n') !== -1 ) {
var lines = text.split( '\n' );
var width = 0;
for( var i = 0; i < lines.length; i++ ) {
width = Math.max( width, this._widthForLine(lines[i]) );
}
return width;
}
else {
return this._widthForLine( text );
}
},
_widthForLine: function( text ) {
var width = 0;
for( var i = 0; i < text.length; i++ ) {
width += this.widthMap[text.charCodeAt(i) - this.firstChar] + this.letterSpacing;
}
return width;
},
heightForString: function( text ) {
return text.split('\n').length * (this.height + this.lineSpacing);
},
draw: function( text, x, y, align ) {
if( typeof(text) != 'string' ) {
text = text.toString();
}
// Multiline?
if( text.indexOf('\n') !== -1 ) {
var lines = text.split( '\n' );
var lineHeight = this.height + this.lineSpacing;
for( var i = 0; i < lines.length; i++ ) {
this.draw( lines[i], x, y + i * lineHeight, align );
}
return;
}
if( align == ig.Font.ALIGN.RIGHT || align == ig.Font.ALIGN.CENTER ) {
var width = this._widthForLine( text );
x -= align == ig.Font.ALIGN.CENTER ? width/2 : width;
}
if( this.alpha !== 1 ) {
ig.system.context.globalAlpha = this.alpha;
}
for( var i = 0; i < text.length; i++ ) {
var c = text.charCodeAt(i);
x += this._drawChar( c - this.firstChar, x, y );
}
if( this.alpha !== 1 ) {
ig.system.context.globalAlpha = 1;
}
ig.Image.drawCount += text.length;
},
_drawChar: function( c, targetX, targetY ) {
if( !this.loaded || c < 0 || c >= this.indices.length ) { return 0; }
var scale = ig.system.scale;
var charX = this.indices[c] * scale;
var charY = 0;
var charWidth = this.widthMap[c] * scale;
var charHeight = (this.height-2) * scale;
ig.system.context.drawImage(
this.data,
charX, charY,
charWidth, charHeight,
ig.system.getDrawPos(targetX), ig.system.getDrawPos(targetY),
charWidth, charHeight
);
return this.widthMap[c] + this.letterSpacing;
},
_loadMetrics: function( image ) {
// Draw the bottommost line of this font image into an offscreen canvas
// and analyze it pixel by pixel.
// A run of non-transparent pixels represents a character and its width
this.height = image.height-1;
this.widthMap = [];
this.indices = [];
var px = ig.getImagePixels( image, 0, image.height-1, image.width, 1 );
var currentChar = 0;
var currentWidth = 0;
for( var x = 0; x < image.width; x++ ) {
var index = x * 4 + 3; // alpha component of this pixel
if( px.data[index] > 127 ) {
currentWidth++;
}
else if( px.data[index] < 128 && currentWidth ) {
this.widthMap.push( currentWidth );
this.indices.push( x-currentWidth );
currentChar++;
currentWidth = 0;
}
}
this.widthMap.push( currentWidth );
this.indices.push( x-currentWidth );
}
});
ig.Font.ALIGN = {
LEFT: 0,
RIGHT: 1,
CENTER: 2
};
});
+326
View File
@@ -0,0 +1,326 @@
ig.module(
'impact.game'
)
.requires(
'impact.impact',
'impact.entity',
'impact.collision-map',
'impact.background-map'
)
.defines(function(){ "use strict";
ig.Game = ig.Class.extend({
clearColor: '#000000',
gravity: 0,
screen: {x: 0, y: 0},
_rscreen: {x: 0, y: 0},
entities: [],
namedEntities: {},
collisionMap: ig.CollisionMap.staticNoCollision,
backgroundMaps: [],
backgroundAnims: {},
autoSort: false,
sortBy: null,
cellSize: 64,
_deferredKill: [],
_levelToLoad: null,
_doSortEntities: false,
staticInstantiate: function() {
this.sortBy = this.sortBy || ig.Game.SORT.Z_INDEX;
ig.game = this;
return null;
},
loadLevel: function( data ) {
this.screen = {x: 0, y: 0};
// Entities
this.entities = [];
this.namedEntities = {};
for( var i = 0; i < data.entities.length; i++ ) {
var ent = data.entities[i];
this.spawnEntity( ent.type, ent.x, ent.y, ent.settings );
}
this.sortEntities();
// Map Layer
this.collisionMap = ig.CollisionMap.staticNoCollision;
this.backgroundMaps = [];
for( var i = 0; i < data.layer.length; i++ ) {
var ld = data.layer[i];
if( ld.name == 'collision' ) {
this.collisionMap = new ig.CollisionMap(ld.tilesize, ld.data );
}
else {
var newMap = new ig.BackgroundMap(ld.tilesize, ld.data, ld.tilesetName);
newMap.anims = this.backgroundAnims[ld.tilesetName] || {};
newMap.repeat = ld.repeat;
newMap.distance = ld.distance;
newMap.foreground = !!ld.foreground;
newMap.preRender = !!ld.preRender;
newMap.name = ld.name;
this.backgroundMaps.push( newMap );
}
}
// Call post-init ready function on all entities
for( var i = 0; i < this.entities.length; i++ ) {
this.entities[i].ready();
}
},
loadLevelDeferred: function( data ) {
this._levelToLoad = data;
},
getMapByName: function( name ) {
if( name == 'collision' ) {
return this.collisionMap;
}
for( var i = 0; i < this.backgroundMaps.length; i++ ) {
if( this.backgroundMaps[i].name == name ) {
return this.backgroundMaps[i];
}
}
return null;
},
getEntityByName: function( name ) {
return this.namedEntities[name];
},
getEntitiesByType: function( type ) {
var entityClass = typeof(type) === 'string'
? ig.global[type]
: type;
var a = [];
for( var i = 0; i < this.entities.length; i++ ) {
var ent = this.entities[i];
if( ent instanceof entityClass && !ent._killed ) {
a.push( ent );
}
}
return a;
},
spawnEntity: function( type, x, y, settings ) {
var entityClass = typeof(type) === 'string'
? ig.global[type]
: type;
if( !entityClass ) {
throw("Can't spawn entity of type " + type);
}
var ent = new (entityClass)( x, y, settings || {} );
this.entities.push( ent );
if( ent.name ) {
this.namedEntities[ent.name] = ent;
}
return ent;
},
sortEntities: function() {
this.entities.sort( this.sortBy );
},
sortEntitiesDeferred: function() {
this._doSortEntities = true;
},
removeEntity: function( ent ) {
// Remove this entity from the named entities
if( ent.name ) {
delete this.namedEntities[ent.name];
}
// We can not remove the entity from the entities[] array in the midst
// of an update cycle, so remember all killed entities and remove
// them later.
// Also make sure this entity doesn't collide anymore and won't get
// updated or checked
ent._killed = true;
ent.type = ig.Entity.TYPE.NONE;
ent.checkAgainst = ig.Entity.TYPE.NONE;
ent.collides = ig.Entity.COLLIDES.NEVER;
this._deferredKill.push( ent );
},
run: function() {
this.update();
this.draw();
},
update: function(){
// load new level?
if( this._levelToLoad ) {
this.loadLevel( this._levelToLoad );
this._levelToLoad = null;
}
// update entities
this.updateEntities();
this.checkEntities();
// remove all killed entities
for( var i = 0; i < this._deferredKill.length; i++ ) {
this._deferredKill[i].erase();
this.entities.erase( this._deferredKill[i] );
}
this._deferredKill = [];
// sort entities?
if( this._doSortEntities || this.autoSort ) {
this.sortEntities();
this._doSortEntities = false;
}
// update background animations
for( var tileset in this.backgroundAnims ) {
var anims = this.backgroundAnims[tileset];
for( var a in anims ) {
anims[a].update();
}
}
},
updateEntities: function() {
for( var i = 0; i < this.entities.length; i++ ) {
var ent = this.entities[i];
if( !ent._killed ) {
ent.update();
}
}
},
draw: function(){
if( this.clearColor ) {
ig.system.clear( this.clearColor );
}
// This is a bit of a circle jerk. Entities reference game._rscreen
// instead of game.screen when drawing themselfs in order to be
// "synchronized" to the rounded(?) screen position
this._rscreen.x = ig.system.getDrawPos(this.screen.x)/ig.system.scale;
this._rscreen.y = ig.system.getDrawPos(this.screen.y)/ig.system.scale;
var mapIndex;
for( mapIndex = 0; mapIndex < this.backgroundMaps.length; mapIndex++ ) {
var map = this.backgroundMaps[mapIndex];
if( map.foreground ) {
// All foreground layers are drawn after the entities
break;
}
map.setScreenPos( this.screen.x, this.screen.y );
map.draw();
}
this.drawEntities();
for( mapIndex; mapIndex < this.backgroundMaps.length; mapIndex++ ) {
var map = this.backgroundMaps[mapIndex];
map.setScreenPos( this.screen.x, this.screen.y );
map.draw();
}
},
drawEntities: function() {
for( var i = 0; i < this.entities.length; i++ ) {
this.entities[i].draw();
}
},
checkEntities: function() {
// Insert all entities into a spatial hash and check them against any
// other entity that already resides in the same cell. Entities that are
// bigger than a single cell, are inserted into each one they intersect
// with.
// A list of entities, which the current one was already checked with,
// is maintained for each entity.
var hash = {};
for( var e = 0; e < this.entities.length; e++ ) {
var entity = this.entities[e];
// Skip entities that don't check, don't get checked and don't collide
if(
entity.type == ig.Entity.TYPE.NONE &&
entity.checkAgainst == ig.Entity.TYPE.NONE &&
entity.collides == ig.Entity.COLLIDES.NEVER
) {
continue;
}
var checked = {},
xmin = Math.floor( entity.pos.x/this.cellSize ),
ymin = Math.floor( entity.pos.y/this.cellSize ),
xmax = Math.floor( (entity.pos.x+entity.size.x)/this.cellSize ) + 1,
ymax = Math.floor( (entity.pos.y+entity.size.y)/this.cellSize ) + 1;
for( var x = xmin; x < xmax; x++ ) {
for( var y = ymin; y < ymax; y++ ) {
// Current cell is empty - create it and insert!
if( !hash[x] ) {
hash[x] = {};
hash[x][y] = [entity];
}
else if( !hash[x][y] ) {
hash[x][y] = [entity];
}
// Check against each entity in this cell, then insert
else {
var cell = hash[x][y];
for( var c = 0; c < cell.length; c++ ) {
// Intersects and wasn't already checkd?
if( entity.touches(cell[c]) && !checked[cell[c].id] ) {
checked[cell[c].id] = true;
ig.Entity.checkPair( entity, cell[c] );
}
}
cell.push(entity);
}
} // end for y size
} // end for x size
} // end for entities
}
});
ig.Game.SORT = {
Z_INDEX: function( a, b ){ return a.zIndex - b.zIndex; },
POS_X: function( a, b ){ return (a.pos.x+a.size.x) - (b.pos.x+b.size.x); },
POS_Y: function( a, b ){ return (a.pos.y+a.size.y) - (b.pos.y+b.size.y); }
};
});
+178
View File
@@ -0,0 +1,178 @@
ig.module(
'impact.image'
)
.defines(function(){ "use strict";
ig.Image = ig.Class.extend({
data: null,
width: 0,
height: 0,
loaded: false,
failed: false,
loadCallback: null,
path: '',
staticInstantiate: function( path ) {
return ig.Image.cache[path] || null;
},
init: function( path ) {
this.path = path;
this.load();
},
load: function( loadCallback ) {
if( this.loaded ) {
if( loadCallback ) {
loadCallback( this.path, true );
}
return;
}
else if( !this.loaded && ig.ready ) {
this.loadCallback = loadCallback || null;
this.data = new Image();
this.data.onload = this.onload.bind(this);
this.data.onerror = this.onerror.bind(this);
this.data.src = ig.prefix + this.path + ig.nocache;
}
else {
ig.addResource( this );
}
ig.Image.cache[this.path] = this;
},
reload: function() {
this.loaded = false;
this.data = new Image();
this.data.onload = this.onload.bind(this);
this.data.src = this.path + '?' + Date.now();
},
onload: function( event ) {
this.width = this.data.width;
this.height = this.data.height;
this.loaded = true;
if( ig.system.scale != 1 ) {
this.resize( ig.system.scale );
}
if( this.loadCallback ) {
this.loadCallback( this.path, true );
}
},
onerror: function( event ) {
this.failed = true;
if( this.loadCallback ) {
this.loadCallback( this.path, false );
}
},
resize: function( scale ) {
// Nearest-Neighbor scaling
// The original image is drawn into an offscreen canvas of the same size
// and copied into another offscreen canvas with the new size.
// The scaled offscreen canvas becomes the image (data) of this object.
var origPixels = ig.getImagePixels( this.data, 0, 0, this.width, this.height );
var widthScaled = this.width * scale;
var heightScaled = this.height * scale;
var scaled = ig.$new('canvas');
scaled.width = widthScaled;
scaled.height = heightScaled;
var scaledCtx = scaled.getContext('2d');
var scaledPixels = scaledCtx.getImageData( 0, 0, widthScaled, heightScaled );
for( var y = 0; y < heightScaled; y++ ) {
for( var x = 0; x < widthScaled; x++ ) {
var index = (Math.floor(y / scale) * this.width + Math.floor(x / scale)) * 4;
var indexScaled = (y * widthScaled + x) * 4;
scaledPixels.data[ indexScaled ] = origPixels.data[ index ];
scaledPixels.data[ indexScaled+1 ] = origPixels.data[ index+1 ];
scaledPixels.data[ indexScaled+2 ] = origPixels.data[ index+2 ];
scaledPixels.data[ indexScaled+3 ] = origPixels.data[ index+3 ];
}
}
scaledCtx.putImageData( scaledPixels, 0, 0 );
this.data = scaled;
},
draw: function( targetX, targetY, sourceX, sourceY, width, height ) {
if( !this.loaded ) { return; }
var scale = ig.system.scale;
sourceX = sourceX ? sourceX * scale : 0;
sourceY = sourceY ? sourceY * scale : 0;
width = (width ? width : this.width) * scale;
height = (height ? height : this.height) * scale;
ig.system.context.drawImage(
this.data, sourceX, sourceY, width, height,
ig.system.getDrawPos(targetX),
ig.system.getDrawPos(targetY),
width, height
);
ig.Image.drawCount++;
},
drawTile: function( targetX, targetY, tile, tileWidth, tileHeight, flipX, flipY ) {
tileHeight = tileHeight ? tileHeight : tileWidth;
if( !this.loaded || tileWidth > this.width || tileHeight > this.height ) { return; }
var scale = ig.system.scale;
var tileWidthScaled = Math.floor(tileWidth * scale);
var tileHeightScaled = Math.floor(tileHeight * scale);
var scaleX = flipX ? -1 : 1;
var scaleY = flipY ? -1 : 1;
if( flipX || flipY ) {
ig.system.context.save();
ig.system.context.scale( scaleX, scaleY );
}
ig.system.context.drawImage(
this.data,
( Math.floor(tile * tileWidth) % this.width ) * scale,
( Math.floor(tile * tileWidth / this.width) * tileHeight ) * scale,
tileWidthScaled,
tileHeightScaled,
ig.system.getDrawPos(targetX) * scaleX - (flipX ? tileWidthScaled : 0),
ig.system.getDrawPos(targetY) * scaleY - (flipY ? tileHeightScaled : 0),
tileWidthScaled,
tileHeightScaled
);
if( flipX || flipY ) {
ig.system.context.restore();
}
ig.Image.drawCount++;
}
});
ig.Image.drawCount = 0;
ig.Image.cache = {};
ig.Image.reloadCache = function() {
for( var path in ig.Image.cache ) {
ig.Image.cache[path].reload();
}
};
});
+590
View File
@@ -0,0 +1,590 @@
// -----------------------------------------------------------------------------
// Impact Game Engine 1.24
// http://impactjs.com/
// -----------------------------------------------------------------------------
(function(window){ "use strict";
// -----------------------------------------------------------------------------
// Native Object extensions
Number.prototype.map = function(istart, istop, ostart, ostop) {
return ostart + (ostop - ostart) * ((this - istart) / (istop - istart));
};
Number.prototype.limit = function(min, max) {
return Math.min(max, Math.max(min, this));
};
Number.prototype.round = function(precision) {
precision = Math.pow(10, precision || 0);
return Math.round(this * precision) / precision;
};
Number.prototype.floor = function() {
return Math.floor(this);
};
Number.prototype.ceil = function() {
return Math.ceil(this);
};
Number.prototype.toInt = function() {
return (this | 0);
};
Number.prototype.toRad = function() {
return (this / 180) * Math.PI;
};
Number.prototype.toDeg = function() {
return (this * 180) / Math.PI;
};
Object.defineProperty(Array.prototype, 'erase', {value: function(item) {
for( var i = this.length; i--; ) {
if( this[i] === item ) {
this.splice(i, 1);
}
}
return this;
}});
Object.defineProperty(Array.prototype, 'random', {value: function(item) {
return this[ Math.floor(Math.random() * this.length) ];
}});
Function.prototype.bind = Function.prototype.bind || function (oThis) {
if( typeof this !== "function" ) {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(
(this instanceof fNOP && oThis ? this : oThis),
aArgs.concat(Array.prototype.slice.call(arguments))
);
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
// -----------------------------------------------------------------------------
// ig Namespace
window.ig = {
game: null,
debug: null,
version: '1.24',
global: window,
modules: {},
resources: [],
ready: false,
baked: false,
nocache: '',
ua: {},
prefix: (window.ImpactPrefix || ''),
lib: 'lib/',
_current: null,
_loadQueue: [],
_waitForOnload: 0,
$: function( selector ) {
return selector.charAt(0) == '#'
? document.getElementById( selector.substr(1) )
: document.getElementsByTagName( selector );
},
$new: function( name ) {
return document.createElement( name );
},
copy: function( object ) {
if(
!object || typeof(object) != 'object' ||
object instanceof HTMLElement ||
object instanceof ig.Class
) {
return object;
}
else if( object instanceof Array ) {
var c = [];
for( var i = 0, l = object.length; i < l; i++) {
c[i] = ig.copy(object[i]);
}
return c;
}
else {
var c = {};
for( var i in object ) {
c[i] = ig.copy(object[i]);
}
return c;
}
},
merge: function( original, extended ) {
for( var key in extended ) {
var ext = extended[key];
if(
typeof(ext) != 'object' ||
ext instanceof HTMLElement ||
ext instanceof ig.Class ||
ext === null
) {
original[key] = ext;
}
else {
if( !original[key] || typeof(original[key]) != 'object' ) {
original[key] = (ext instanceof Array) ? [] : {};
}
ig.merge( original[key], ext );
}
}
return original;
},
ksort: function( obj ) {
if( !obj || typeof(obj) != 'object' ) {
return [];
}
var keys = [], values = [];
for( var i in obj ) {
keys.push(i);
}
keys.sort();
for( var i = 0; i < keys.length; i++ ) {
values.push( obj[keys[i]] );
}
return values;
},
// Ah, yes. I love vendor prefixes. So much fun!
setVendorAttribute: function( el, attr, val ) {
var uc = attr.charAt(0).toUpperCase() + attr.substr(1);
el[attr] = el['ms'+uc] = el['moz'+uc] = el['webkit'+uc] = el['o'+uc] = val;
},
getVendorAttribute: function( el, attr ) {
var uc = attr.charAt(0).toUpperCase() + attr.substr(1);
return el[attr] || el['ms'+uc] || el['moz'+uc] || el['webkit'+uc] || el['o'+uc];
},
normalizeVendorAttribute: function( el, attr ) {
var prefixedVal = ig.getVendorAttribute( el, attr );
if( !el[attr] && prefixedVal ) {
el[attr] = prefixedVal;
}
},
// This function normalizes getImageData to extract the real, actual
// pixels from an image. The naive method recently failed on retina
// devices with a backgingStoreRatio != 1
getImagePixels: function( image, x, y, width, height ) {
var canvas = ig.$new('canvas');
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext('2d');
// Try to draw pixels as accurately as possible
ig.System.SCALE.CRISP(canvas, ctx);
var ratio = ig.getVendorAttribute( ctx, 'backingStorePixelRatio' ) || 1;
ig.normalizeVendorAttribute( ctx, 'getImageDataHD' );
var realWidth = image.width / ratio,
realHeight = image.height / ratio;
canvas.width = Math.ceil( realWidth );
canvas.height = Math.ceil( realHeight );
ctx.drawImage( image, 0, 0, realWidth, realHeight );
return (ratio === 1)
? ctx.getImageData( x, y, width, height )
: ctx.getImageDataHD( x, y, width, height );
},
module: function( name ) {
if( ig._current ) {
throw( "Module '"+ig._current.name+"' defines nothing" );
}
if( ig.modules[name] && ig.modules[name].body ) {
throw( "Module '"+name+"' is already defined" );
}
ig._current = {name: name, requires: [], loaded: false, body: null};
ig.modules[name] = ig._current;
ig._loadQueue.push(ig._current);
return ig;
},
requires: function() {
ig._current.requires = Array.prototype.slice.call(arguments);
return ig;
},
defines: function( body ) {
ig._current.body = body;
ig._current = null;
ig._initDOMReady();
},
addResource: function( resource ) {
ig.resources.push( resource );
},
setNocache: function( set ) {
ig.nocache = set
? '?' + Date.now()
: '';
},
// Stubs for ig.Debug
log: function() {},
assert: function( condition, msg ) {},
show: function( name, number ) {},
mark: function( msg, color ) {},
_loadScript: function( name, requiredFrom ) {
ig.modules[name] = {name: name, requires:[], loaded: false, body: null};
ig._waitForOnload++;
var path = ig.prefix + ig.lib + name.replace(/\./g, '/') + '.js' + ig.nocache;
var script = ig.$new('script');
script.type = 'text/javascript';
script.src = path;
script.onload = function() {
ig._waitForOnload--;
ig._execModules();
};
script.onerror = function() {
throw(
'Failed to load module '+name+' at ' + path + ' ' +
'required from ' + requiredFrom
);
};
ig.$('head')[0].appendChild(script);
},
_execModules: function() {
var modulesLoaded = false;
for( var i = 0; i < ig._loadQueue.length; i++ ) {
var m = ig._loadQueue[i];
var dependenciesLoaded = true;
for( var j = 0; j < m.requires.length; j++ ) {
var name = m.requires[j];
if( !ig.modules[name] ) {
dependenciesLoaded = false;
ig._loadScript( name, m.name );
}
else if( !ig.modules[name].loaded ) {
dependenciesLoaded = false;
}
}
if( dependenciesLoaded && m.body ) {
ig._loadQueue.splice(i, 1);
m.loaded = true;
m.body();
modulesLoaded = true;
i--;
}
}
if( modulesLoaded ) {
ig._execModules();
}
// No modules executed, no more files to load but loadQueue not empty?
// Must be some unresolved dependencies!
else if( !ig.baked && ig._waitForOnload == 0 && ig._loadQueue.length != 0 ) {
var unresolved = [];
for( var i = 0; i < ig._loadQueue.length; i++ ) {
// Which dependencies aren't loaded?
var unloaded = [];
var requires = ig._loadQueue[i].requires;
for( var j = 0; j < requires.length; j++ ) {
var m = ig.modules[ requires[j] ];
if( !m || !m.loaded ) {
unloaded.push( requires[j] );
}
}
unresolved.push( ig._loadQueue[i].name + ' (requires: ' + unloaded.join(', ') + ')');
}
throw(
"Unresolved (or circular?) dependencies. " +
"Most likely there's a name/path mismatch for one of the listed modules " +
"or a previous syntax error prevents a module from loading:\n" +
unresolved.join('\n')
);
}
},
_DOMReady: function() {
if( !ig.modules['dom.ready'].loaded ) {
if ( !document.body ) {
return setTimeout( ig._DOMReady, 13 );
}
ig.modules['dom.ready'].loaded = true;
ig._waitForOnload--;
ig._execModules();
}
return 0;
},
_boot: function() {
if( document.location.href.match(/\?nocache/) ) {
ig.setNocache( true );
}
// Probe user agent string
ig.ua.pixelRatio = window.devicePixelRatio || 1;
ig.ua.viewport = {
width: window.innerWidth,
height: window.innerHeight
};
ig.ua.screen = {
width: window.screen.availWidth * ig.ua.pixelRatio,
height: window.screen.availHeight * ig.ua.pixelRatio
};
ig.ua.iPhone = /iPhone/i.test(navigator.userAgent);
ig.ua.iPhone4 = (ig.ua.iPhone && ig.ua.pixelRatio == 2);
ig.ua.iPad = /iPad/i.test(navigator.userAgent);
ig.ua.android = /android/i.test(navigator.userAgent);
ig.ua.winPhone = /Windows Phone/i.test(navigator.userAgent);
ig.ua.iOS = ig.ua.iPhone || ig.ua.iPad;
ig.ua.mobile = ig.ua.iOS || ig.ua.android || ig.ua.winPhone || /mobile/i.test(navigator.userAgent);
ig.ua.touchDevice = (('ontouchstart' in window) || (window.navigator.msMaxTouchPoints));
},
_initDOMReady: function() {
if( ig.modules['dom.ready'] ) {
ig._execModules();
return;
}
ig._boot();
ig.modules['dom.ready'] = { requires: [], loaded: false, body: null };
ig._waitForOnload++;
if ( document.readyState === 'complete' ) {
ig._DOMReady();
}
else {
document.addEventListener( 'DOMContentLoaded', ig._DOMReady, false );
window.addEventListener( 'load', ig._DOMReady, false );
}
}
};
// -----------------------------------------------------------------------------
// Provide ig.setAnimation and ig.clearAnimation as a compatible way to use
// requestAnimationFrame if available or setInterval otherwise
// Use requestAnimationFrame if available
ig.normalizeVendorAttribute( window, 'requestAnimationFrame' );
if( window.requestAnimationFrame ) {
var next = 1,
anims = {};
window.ig.setAnimation = function( callback, element ) {
var current = next++;
anims[current] = true;
var animate = function() {
if( !anims[current] ) { return; } // deleted?
window.requestAnimationFrame( animate, element );
callback();
};
window.requestAnimationFrame( animate, element );
return current;
};
window.ig.clearAnimation = function( id ) {
delete anims[id];
};
}
// [set/clear]Interval fallback
else {
window.ig.setAnimation = function( callback, element ) {
return window.setInterval( callback, 1000/60 );
};
window.ig.clearAnimation = function( id ) {
window.clearInterval( id );
};
}
// -----------------------------------------------------------------------------
// Class object based on John Resigs code; inspired by base2 and Prototype
// http://ejohn.org/blog/simple-javascript-inheritance/
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\bparent\b/ : /.*/;
var lastClassId = 0;
window.ig.Class = function(){};
var inject = function(prop) {
var proto = this.prototype;
var parent = {};
for( var name in prop ) {
if(
typeof(prop[name]) == "function" &&
typeof(proto[name]) == "function" &&
fnTest.test(prop[name])
) {
parent[name] = proto[name]; // save original function
proto[name] = (function(name, fn){
return function() {
var tmp = this.parent;
this.parent = parent[name];
var ret = fn.apply(this, arguments);
this.parent = tmp;
return ret;
};
})( name, prop[name] );
}
else {
proto[name] = prop[name];
}
}
};
window.ig.Class.extend = function(prop) {
var parent = this.prototype;
initializing = true;
var prototype = new this();
initializing = false;
for( var name in prop ) {
if(
typeof(prop[name]) == "function" &&
typeof(parent[name]) == "function" &&
fnTest.test(prop[name])
) {
prototype[name] = (function(name, fn){
return function() {
var tmp = this.parent;
this.parent = parent[name];
var ret = fn.apply(this, arguments);
this.parent = tmp;
return ret;
};
})( name, prop[name] );
}
else {
prototype[name] = prop[name];
}
}
function Class() {
if( !initializing ) {
// If this class has a staticInstantiate method, invoke it
// and check if we got something back. If not, the normal
// constructor (init) is called.
if( this.staticInstantiate ) {
var obj = this.staticInstantiate.apply(this, arguments);
if( obj ) {
return obj;
}
}
for( var p in this ) {
if( typeof(this[p]) == 'object' ) {
this[p] = ig.copy(this[p]); // deep copy!
}
}
if( this.init ) {
this.init.apply(this, arguments);
}
}
return this;
}
Class.prototype = prototype;
Class.prototype.constructor = Class;
Class.extend = window.ig.Class.extend;
Class.inject = inject;
Class.classId = prototype.classId = ++lastClassId;
return Class;
};
// Merge the ImpactMixin - if present - into the 'ig' namespace. This gives other
// code the chance to modify 'ig' before it's doing any work.
if( window.ImpactMixin ) {
ig.merge(ig, window.ImpactMixin);
}
})(window);
// -----------------------------------------------------------------------------
// The main() function creates the system, input, sound and game objects,
// creates a preloader and starts the run loop
ig.module(
'impact.impact'
)
.requires(
'dom.ready',
'impact.loader',
'impact.system',
'impact.input',
'impact.sound'
)
.defines(function(){ "use strict";
ig.main = function( canvasId, gameClass, fps, width, height, scale, loaderClass ) {
ig.system = new ig.System( canvasId, fps, width, height, scale || 1 );
ig.input = new ig.Input();
ig.soundManager = new ig.SoundManager();
ig.music = new ig.Music();
ig.ready = true;
var loader = new (loaderClass || ig.Loader)( gameClass, ig.resources );
loader.load();
};
});
+321
View File
@@ -0,0 +1,321 @@
ig.module(
'impact.input'
)
.defines(function(){ "use strict";
ig.KEY = {
'MOUSE1': -1,
'MOUSE2': -3,
'MWHEEL_UP': -4,
'MWHEEL_DOWN': -5,
'BACKSPACE': 8,
'TAB': 9,
'ENTER': 13,
'PAUSE': 19,
'CAPS': 20,
'ESC': 27,
'SPACE': 32,
'PAGE_UP': 33,
'PAGE_DOWN': 34,
'END': 35,
'HOME': 36,
'LEFT_ARROW': 37,
'UP_ARROW': 38,
'RIGHT_ARROW': 39,
'DOWN_ARROW': 40,
'INSERT': 45,
'DELETE': 46,
'_0': 48,
'_1': 49,
'_2': 50,
'_3': 51,
'_4': 52,
'_5': 53,
'_6': 54,
'_7': 55,
'_8': 56,
'_9': 57,
'A': 65,
'B': 66,
'C': 67,
'D': 68,
'E': 69,
'F': 70,
'G': 71,
'H': 72,
'I': 73,
'J': 74,
'K': 75,
'L': 76,
'M': 77,
'N': 78,
'O': 79,
'P': 80,
'Q': 81,
'R': 82,
'S': 83,
'T': 84,
'U': 85,
'V': 86,
'W': 87,
'X': 88,
'Y': 89,
'Z': 90,
'NUMPAD_0': 96,
'NUMPAD_1': 97,
'NUMPAD_2': 98,
'NUMPAD_3': 99,
'NUMPAD_4': 100,
'NUMPAD_5': 101,
'NUMPAD_6': 102,
'NUMPAD_7': 103,
'NUMPAD_8': 104,
'NUMPAD_9': 105,
'MULTIPLY': 106,
'ADD': 107,
'SUBSTRACT': 109,
'DECIMAL': 110,
'DIVIDE': 111,
'F1': 112,
'F2': 113,
'F3': 114,
'F4': 115,
'F5': 116,
'F6': 117,
'F7': 118,
'F8': 119,
'F9': 120,
'F10': 121,
'F11': 122,
'F12': 123,
'SHIFT': 16,
'CTRL': 17,
'ALT': 18,
'PLUS': 187,
'COMMA': 188,
'MINUS': 189,
'PERIOD': 190
};
ig.Input = ig.Class.extend({
bindings: {},
actions: {},
presses: {},
locks: {},
delayedKeyup: {},
isUsingMouse: false,
isUsingKeyboard: false,
isUsingAccelerometer: false,
mouse: {x: 0, y: 0},
accel: {x: 0, y: 0, z: 0},
initMouse: function() {
if( this.isUsingMouse ) { return; }
this.isUsingMouse = true;
var mouseWheelBound = this.mousewheel.bind(this);
ig.system.canvas.addEventListener('mousewheel', mouseWheelBound, false );
ig.system.canvas.addEventListener('DOMMouseScroll', mouseWheelBound, false );
ig.system.canvas.addEventListener('contextmenu', this.contextmenu.bind(this), false );
ig.system.canvas.addEventListener('mousedown', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('mouseup', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('mousemove', this.mousemove.bind(this), false );
if( ig.ua.touchDevice ) {
// Standard
ig.system.canvas.addEventListener('touchstart', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('touchend', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('touchmove', this.mousemove.bind(this), false );
// MS
ig.system.canvas.addEventListener('MSPointerDown', this.keydown.bind(this), false );
ig.system.canvas.addEventListener('MSPointerUp', this.keyup.bind(this), false );
ig.system.canvas.addEventListener('MSPointerMove', this.mousemove.bind(this), false );
ig.system.canvas.style.msTouchAction = 'none';
}
},
initKeyboard: function() {
if( this.isUsingKeyboard ) { return; }
this.isUsingKeyboard = true;
window.addEventListener('keydown', this.keydown.bind(this), false );
window.addEventListener('keyup', this.keyup.bind(this), false );
},
initAccelerometer: function() {
if( this.isUsingAccelerometer ) { return; }
this.isUsingAccelerometer = true;
window.addEventListener('devicemotion', this.devicemotion.bind(this), false );
},
mousewheel: function( event ) {
var delta = event.wheelDelta ? event.wheelDelta : (event.detail * -1);
var code = delta > 0 ? ig.KEY.MWHEEL_UP : ig.KEY.MWHEEL_DOWN;
var action = this.bindings[code];
if( action ) {
this.actions[action] = true;
this.presses[action] = true;
this.delayedKeyup[action] = true;
event.stopPropagation();
event.preventDefault();
}
},
mousemove: function( event ) {
var internalWidth = parseInt(ig.system.canvas.offsetWidth) || ig.system.realWidth;
var scale = ig.system.scale * (internalWidth / ig.system.realWidth);
var pos = {left: 0, top: 0};
if( ig.system.canvas.getBoundingClientRect ) {
pos = ig.system.canvas.getBoundingClientRect();
}
var ev = event.touches ? event.touches[0] : event;
this.mouse.x = (ev.clientX - pos.left) / scale;
this.mouse.y = (ev.clientY - pos.top) / scale;
},
contextmenu: function( event ) {
if( this.bindings[ig.KEY.MOUSE2] ) {
event.stopPropagation();
event.preventDefault();
}
},
keydown: function( event ) {
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keydown'
? event.keyCode
: (event.button == 2 ? ig.KEY.MOUSE2 : ig.KEY.MOUSE1);
// Focus window element for mouse clicks. Prevents issues when
// running the game in an iframe.
if( code < 0 && !ig.ua.mobile ) {
window.focus();
}
if( event.type == 'touchstart' || event.type == 'mousedown' ) {
this.mousemove( event );
}
var action = this.bindings[code];
if( action ) {
this.actions[action] = true;
if( !this.locks[action] ) {
this.presses[action] = true;
this.locks[action] = true;
}
event.preventDefault();
}
},
keyup: function( event ) {
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keyup'
? event.keyCode
: (event.button == 2 ? ig.KEY.MOUSE2 : ig.KEY.MOUSE1);
var action = this.bindings[code];
if( action ) {
this.delayedKeyup[action] = true;
event.preventDefault();
}
},
devicemotion: function( event ) {
this.accel = event.accelerationIncludingGravity;
},
bind: function( key, action ) {
if( key < 0 ) { this.initMouse(); }
else if( key > 0 ) { this.initKeyboard(); }
this.bindings[key] = action;
},
bindTouch: function( selector, action ) {
var element = ig.$( selector );
var that = this;
element.addEventListener('touchstart', function(ev) {that.touchStart( ev, action );}, false);
element.addEventListener('touchend', function(ev) {that.touchEnd( ev, action );}, false);
element.addEventListener('MSPointerDown', function(ev) {that.touchStart( ev, action );}, false);
element.addEventListener('MSPointerUp', function(ev) {that.touchEnd( ev, action );}, false);
},
unbind: function( key ) {
var action = this.bindings[key];
this.delayedKeyup[action] = true;
this.bindings[key] = null;
},
unbindAll: function() {
this.bindings = {};
this.actions = {};
this.presses = {};
this.locks = {};
this.delayedKeyup = {};
},
state: function( action ) {
return this.actions[action];
},
pressed: function( action ) {
return this.presses[action];
},
released: function( action ) {
return !!this.delayedKeyup[action];
},
clearPressed: function() {
for( var action in this.delayedKeyup ) {
this.actions[action] = false;
this.locks[action] = false;
}
this.delayedKeyup = {};
this.presses = {};
},
touchStart: function( event, action ) {
this.actions[action] = true;
this.presses[action] = true;
event.stopPropagation();
event.preventDefault();
return false;
},
touchEnd: function( event, action ) {
this.delayedKeyup[action] = true;
event.stopPropagation();
event.preventDefault();
return false;
}
});
});
+101
View File
@@ -0,0 +1,101 @@
ig.module(
'impact.loader'
)
.requires(
'impact.image',
'impact.font',
'impact.sound'
)
.defines(function(){ "use strict";
ig.Loader = ig.Class.extend({
resources: [],
gameClass: null,
status: 0,
done: false,
_unloaded: [],
_drawStatus: 0,
_intervalId: 0,
_loadCallbackBound: null,
init: function( gameClass, resources ) {
this.gameClass = gameClass;
this.resources = resources;
this._loadCallbackBound = this._loadCallback.bind(this);
for( var i = 0; i < this.resources.length; i++ ) {
this._unloaded.push( this.resources[i].path );
}
},
load: function() {
ig.system.clear( '#000' );
if( !this.resources.length ) {
this.end();
return;
}
for( var i = 0; i < this.resources.length; i++ ) {
this.loadResource( this.resources[i] );
}
this._intervalId = setInterval( this.draw.bind(this), 16 );
},
loadResource: function( res ) {
res.load( this._loadCallbackBound );
},
end: function() {
if( this.done ) { return; }
this.done = true;
clearInterval( this._intervalId );
ig.system.setGame( this.gameClass );
},
draw: function() {
this._drawStatus += (this.status - this._drawStatus)/5;
var s = ig.system.scale;
var w = ig.system.width * 0.6;
var h = ig.system.height * 0.1;
var x = ig.system.width * 0.5-w/2;
var y = ig.system.height * 0.5-h/2;
ig.system.context.fillStyle = '#000';
ig.system.context.fillRect( 0, 0, 480, 320 );
ig.system.context.fillStyle = '#fff';
ig.system.context.fillRect( x*s, y*s, w*s, h*s );
ig.system.context.fillStyle = '#000';
ig.system.context.fillRect( x*s+s, y*s+s, w*s-s-s, h*s-s-s );
ig.system.context.fillStyle = '#fff';
ig.system.context.fillRect( x*s, y*s, w*s*this._drawStatus, h*s );
},
_loadCallback: function( path, status ) {
if( status ) {
this._unloaded.erase( path );
}
else {
throw( 'Failed to load resource: ' + path );
}
this.status = 1 - (this._unloaded.length / this.resources.length);
if( this._unloaded.length == 0 ) { // all done?
setTimeout( this.end.bind(this), 250 );
}
}
});
});
+52
View File
@@ -0,0 +1,52 @@
ig.module(
'impact.map'
)
.defines(function(){ "use strict";
ig.Map = ig.Class.extend({
tilesize: 8,
width: 1,
height: 1,
data: [[]],
name: null,
init: function( tilesize, data ) {
this.tilesize = tilesize;
this.data = data;
this.height = data.length;
this.width = data[0].length;
this.pxWidth = this.width * this.tilesize;
this.pxHeight = this.height * this.tilesize;
},
getTile: function( x, y ) {
var tx = Math.floor( x / this.tilesize );
var ty = Math.floor( y / this.tilesize );
if(
(tx >= 0 && tx < this.width) &&
(ty >= 0 && ty < this.height)
) {
return this.data[ty][tx];
}
else {
return 0;
}
},
setTile: function( x, y, tile ) {
var tx = Math.floor( x / this.tilesize );
var ty = Math.floor( y / this.tilesize );
if(
(tx >= 0 && tx < this.width) &&
(ty >= 0 && ty < this.height)
) {
this.data[ty][tx] = tile;
}
}
});
});
+516
View File
@@ -0,0 +1,516 @@
ig.module(
'impact.sound'
)
.defines(function(){ "use strict";
ig.SoundManager = ig.Class.extend({
clips: {},
volume: 1,
format: null,
init: function() {
// Quick sanity check if the Browser supports the Audio tag
if( !ig.Sound.enabled || !window.Audio ) {
ig.Sound.enabled = false;
return;
}
// Probe sound formats and determine the file extension to load
var probe = new Audio();
for( var i = 0; i < ig.Sound.use.length; i++ ) {
var format = ig.Sound.use[i];
if( probe.canPlayType(format.mime) ) {
this.format = format;
break;
}
}
// No compatible format found? -> Disable sound
if( !this.format ) {
ig.Sound.enabled = false;
}
// Create WebAudio Context
if( ig.Sound.enabled && ig.Sound.useWebAudio ) {
this.audioContext = new AudioContext();
this.boundWebAudioUnlock = this.unlockWebAudio.bind(this);
document.addEventListener('touchstart', this.boundWebAudioUnlock, false);
}
},
unlockWebAudio: function() {
document.removeEventListener('touchstart', this.boundWebAudioUnlock, false);
// create empty buffer
var buffer = this.audioContext.createBuffer(1, 1, 22050);
var source = this.audioContext.createBufferSource();
source.buffer = buffer;
source.connect(this.audioContext.destination);
source.start(0);
},
load: function( path, multiChannel, loadCallback ) {
if( multiChannel && ig.Sound.useWebAudio ) {
// Requested as Multichannel and we're using WebAudio?
return this.loadWebAudio( path, multiChannel, loadCallback );
}
else {
// Oldschool HTML5 Audio - always used for Music
return this.loadHTML5Audio( path, multiChannel, loadCallback );
}
},
loadWebAudio: function( path, multiChannel, loadCallback ) {
// Path to the soundfile with the right extension (.ogg or .mp3)
var realPath = ig.prefix + path.replace(/[^\.]+$/, this.format.ext) + ig.nocache;
if( this.clips[path] ) {
return this.clips[path];
}
var audioSource = new ig.Sound.WebAudioSource()
this.clips[path] = audioSource;
var request = new XMLHttpRequest();
request.open('GET', realPath, true);
request.responseType = 'arraybuffer';
var that = this;
request.onload = function(ev) {
that.audioContext.decodeAudioData(request.response,
function(buffer) {
audioSource.buffer = buffer;
loadCallback( path, true, ev );
},
function(ev) {
loadCallback( path, false, ev );
}
);
};
request.onerror = function(ev) {
loadCallback( path, false, ev );
};
request.send();
return audioSource;
},
loadHTML5Audio: function( path, multiChannel, loadCallback ) {
// Path to the soundfile with the right extension (.ogg or .mp3)
var realPath = ig.prefix + path.replace(/[^\.]+$/, this.format.ext) + ig.nocache;
// Sound file already loaded?
if( this.clips[path] ) {
// Loaded as WebAudio, but now requested as HTML5 Audio? Probably Music?
if( this.clips[path] instanceof ig.Sound.WebAudioSource ) {
return this.clips[path];
}
// Only loaded as single channel and now requested as multichannel?
if( multiChannel && this.clips[path].length < ig.Sound.channels ) {
for( var i = this.clips[path].length; i < ig.Sound.channels; i++ ) {
var a = new Audio( realPath );
a.load();
this.clips[path].push( a );
}
}
return this.clips[path][0];
}
var clip = new Audio( realPath );
if( loadCallback ) {
// The canplaythrough event is dispatched when the browser determines
// that the sound can be played without interuption, provided the
// download rate doesn't change.
// Mobile browsers stubbornly refuse to preload HTML5, so we simply
// ignore the canplaythrough event and immediately "fake" a successful
// load callback
if( ig.ua.mobile ) {
setTimeout(function(){
loadCallback( path, true, null );
}, 0);
}
else {
clip.addEventListener( 'canplaythrough', function cb(ev){
clip.removeEventListener('canplaythrough', cb, false);
loadCallback( path, true, ev );
}, false );
clip.addEventListener( 'error', function(ev){
loadCallback( path, false, ev );
}, false);
}
}
clip.preload = 'auto';
clip.load();
this.clips[path] = [clip];
if( multiChannel ) {
for( var i = 1; i < ig.Sound.channels; i++ ) {
var a = new Audio(realPath);
a.load();
this.clips[path].push( a );
}
}
return clip;
},
get: function( path ) {
// Find and return a channel that is not currently playing
var channels = this.clips[path];
// Is this a WebAudio source? We only ever have one for each Sound
if( channels && channels instanceof ig.Sound.WebAudioSource ) {
return channels;
}
// Oldschool HTML5 Audio - find a channel that's not currently
// playing or, if all are playing, rewind one
for( var i = 0, clip; clip = channels[i++]; ) {
if( clip.paused || clip.ended ) {
if( clip.ended ) {
clip.currentTime = 0;
}
return clip;
}
}
// Still here? Pause and rewind the first channel
channels[0].pause();
channels[0].currentTime = 0;
return channels[0];
}
});
ig.Music = ig.Class.extend({
tracks: [],
namedTracks: {},
currentTrack: null,
currentIndex: 0,
random: false,
_volume: 1,
_loop: false,
_fadeInterval: 0,
_fadeTimer: null,
_endedCallbackBound: null,
init: function() {
this._endedCallbackBound = this._endedCallback.bind(this);
Object.defineProperty(this,"volume", {
get: this.getVolume.bind(this),
set: this.setVolume.bind(this)
});
Object.defineProperty(this,"loop", {
get: this.getLooping.bind(this),
set: this.setLooping.bind(this)
});
},
add: function( music, name ) {
if( !ig.Sound.enabled ) {
return;
}
var path = music instanceof ig.Sound ? music.path : music;
var track = ig.soundManager.load(path, false);
// Did we get a WebAudio Source? This is suboptimal; Music should be loaded
// as HTML5 Audio so it can be streamed
if( track instanceof ig.Sound.WebAudioSource ) {
// Since this error will likely occour at game start, we stop the game
// to not produce any more errors.
ig.system.stopRunLoop();
throw(
"Sound '"+path+"' loaded as Multichannel but used for Music. " +
"Set the multiChannel param to false when loading, e.g.: new ig.Sound(path, false)"
);
}
track.loop = this._loop;
track.volume = this._volume;
track.addEventListener( 'ended', this._endedCallbackBound, false );
this.tracks.push( track );
if( name ) {
this.namedTracks[name] = track;
}
if( !this.currentTrack ) {
this.currentTrack = track;
}
},
next: function() {
if( !this.tracks.length ) { return; }
this.stop();
this.currentIndex = this.random
? Math.floor(Math.random() * this.tracks.length)
: (this.currentIndex + 1) % this.tracks.length;
this.currentTrack = this.tracks[this.currentIndex];
this.play();
},
pause: function() {
if( !this.currentTrack ) { return; }
this.currentTrack.pause();
},
stop: function() {
if( !this.currentTrack ) { return; }
this.currentTrack.pause();
this.currentTrack.currentTime = 0;
},
play: function( name ) {
// If a name was provided, stop playing the current track (if any)
// and play the named track
if( name && this.namedTracks[name] ) {
var newTrack = this.namedTracks[name];
if( newTrack != this.currentTrack ) {
this.stop();
this.currentTrack = newTrack;
}
}
else if( !this.currentTrack ) {
return;
}
this.currentTrack.play();
},
getLooping: function() {
return this._loop;
},
setLooping: function( l ) {
this._loop = l;
for( var i in this.tracks ) {
this.tracks[i].loop = l;
}
},
getVolume: function() {
return this._volume;
},
setVolume: function( v ) {
this._volume = v.limit(0,1);
for( var i in this.tracks ) {
this.tracks[i].volume = this._volume;
}
},
fadeOut: function( time ) {
if( !this.currentTrack ) { return; }
clearInterval( this._fadeInterval );
this.fadeTimer = new ig.Timer( time );
this._fadeInterval = setInterval( this._fadeStep.bind(this), 50 );
},
_fadeStep: function() {
var v = this.fadeTimer.delta()
.map(-this.fadeTimer.target, 0, 1, 0)
.limit( 0, 1 )
* this._volume;
if( v <= 0.01 ) {
this.stop();
this.currentTrack.volume = this._volume;
clearInterval( this._fadeInterval );
}
else {
this.currentTrack.volume = v;
}
},
_endedCallback: function() {
if( this._loop ) {
this.play();
}
else {
this.next();
}
}
});
ig.Sound = ig.Class.extend({
path: '',
volume: 1,
currentClip: null,
multiChannel: true,
_loop: false,
init: function( path, multiChannel ) {
this.path = path;
this.multiChannel = (multiChannel !== false);
Object.defineProperty(this,"loop", {
get: this.getLooping.bind(this),
set: this.setLooping.bind(this)
});
this.load();
},
getLooping: function() {
return this._loop;
},
setLooping: function( loop ) {
this._loop = loop;
if( this.currentClip ) {
this.currentClip.loop = loop;
}
},
load: function( loadCallback ) {
if( !ig.Sound.enabled ) {
if( loadCallback ) {
loadCallback( this.path, true );
}
return;
}
if( ig.ready ) {
ig.soundManager.load( this.path, this.multiChannel, loadCallback );
}
else {
ig.addResource( this );
}
},
play: function() {
if( !ig.Sound.enabled ) {
return;
}
this.currentClip = ig.soundManager.get( this.path );
this.currentClip.loop = this._loop;
this.currentClip.volume = ig.soundManager.volume * this.volume;
this.currentClip.play();
},
stop: function() {
if( this.currentClip ) {
this.currentClip.pause();
this.currentClip.currentTime = 0;
}
}
});
ig.Sound.WebAudioSource = ig.Class.extend({
sources: [],
gain: null,
buffer: null,
_loop: false,
init: function() {
this.gain = ig.soundManager.audioContext.createGain();
this.gain.connect(ig.soundManager.audioContext.destination);
Object.defineProperty(this,"loop", {
get: this.getLooping.bind(this),
set: this.setLooping.bind(this)
});
Object.defineProperty(this,"volume", {
get: this.getVolume.bind(this),
set: this.setVolume.bind(this)
});
},
play: function() {
if( !this.buffer ) { return; }
var source = ig.soundManager.audioContext.createBufferSource();
source.buffer = this.buffer;
source.connect(this.gain);
source.loop = this._loop;
// Add this new source to our sources array and remove it again
// later when it has finished playing.
var that = this;
this.sources.push(source);
source.onended = function(){ that.sources.erase(source); }
source.start(0);
},
pause: function() {
for( var i = 0; i < this.sources.length; i++ ) {
try{
this.sources[i].stop();
} catch(err){}
}
},
getLooping: function() {
return this._loop;
},
setLooping: function( loop ) {
this._loop = loop;
for( var i = 0; i < this.sources.length; i++ ) {
this.sources[i].loop = loop;
}
},
getVolume: function() {
return this.gain.gain.value;
},
setVolume: function( volume ) {
this.gain.gain.value = volume;
}
});
ig.Sound.FORMAT = {
MP3: {ext: 'mp3', mime: 'audio/mpeg'},
M4A: {ext: 'm4a', mime: 'audio/mp4; codecs=mp4a'},
OGG: {ext: 'ogg', mime: 'audio/ogg; codecs=vorbis'},
WEBM: {ext: 'webm', mime: 'audio/webm; codecs=vorbis'},
CAF: {ext: 'caf', mime: 'audio/x-caf'}
};
ig.Sound.use = [ig.Sound.FORMAT.OGG, ig.Sound.FORMAT.MP3];
ig.Sound.channels = 4;
ig.Sound.enabled = true;
ig.normalizeVendorAttribute(window, 'AudioContext');
ig.Sound.useWebAudio = !!window.AudioContext && !window.nwf;
});
+145
View File
@@ -0,0 +1,145 @@
ig.module(
'impact.system'
)
.requires(
'impact.timer',
'impact.image'
)
.defines(function(){ "use strict";
ig.System = ig.Class.extend({
fps: 30,
width: 320,
height: 240,
realWidth: 320,
realHeight: 240,
scale: 1,
tick: 0,
animationId: 0,
newGameClass: null,
running: false,
delegate: null,
clock: null,
canvas: null,
context: null,
init: function( canvasId, fps, width, height, scale ) {
this.fps = fps;
this.clock = new ig.Timer();
this.canvas = ig.$(canvasId);
this.resize( width, height, scale );
this.context = this.canvas.getContext('2d');
this.getDrawPos = ig.System.drawMode;
// Automatically switch to crisp scaling when using a scale
// other than 1
if( this.scale != 1 ) {
ig.System.scaleMode = ig.System.SCALE.CRISP;
}
ig.System.scaleMode( this.canvas, this.context );
},
resize: function( width, height, scale ) {
this.width = width;
this.height = height;
this.scale = scale || this.scale;
this.realWidth = this.width * this.scale;
this.realHeight = this.height * this.scale;
this.canvas.width = this.realWidth;
this.canvas.height = this.realHeight;
},
setGame: function( gameClass ) {
if( this.running ) {
this.newGameClass = gameClass;
}
else {
this.setGameNow( gameClass );
}
},
setGameNow: function( gameClass ) {
ig.game = new (gameClass)();
ig.system.setDelegate( ig.game );
},
setDelegate: function( object ) {
if( typeof(object.run) == 'function' ) {
this.delegate = object;
this.startRunLoop();
} else {
throw( 'System.setDelegate: No run() function in object' );
}
},
stopRunLoop: function() {
ig.clearAnimation( this.animationId );
this.running = false;
},
startRunLoop: function() {
this.stopRunLoop();
this.animationId = ig.setAnimation( this.run.bind(this), this.canvas );
this.running = true;
},
clear: function( color ) {
this.context.fillStyle = color;
this.context.fillRect( 0, 0, this.realWidth, this.realHeight );
},
run: function() {
ig.Timer.step();
this.tick = this.clock.tick();
this.delegate.run();
ig.input.clearPressed();
if( this.newGameClass ) {
this.setGameNow( this.newGameClass );
this.newGameClass = null;
}
},
getDrawPos: null // Set through constructor
});
ig.System.DRAW = {
AUTHENTIC: function( p ) { return Math.round(p) * this.scale; },
SMOOTH: function( p ) { return Math.round(p * this.scale); },
SUBPIXEL: function( p ) { return p * this.scale; }
};
ig.System.drawMode = ig.System.DRAW.SMOOTH;
ig.System.SCALE = {
CRISP: function( canvas, context ) {
ig.setVendorAttribute( context, 'imageSmoothingEnabled', false );
canvas.style.imageRendering = '-moz-crisp-edges';
canvas.style.imageRendering = '-o-crisp-edges';
canvas.style.imageRendering = '-webkit-optimize-contrast';
canvas.style.imageRendering = 'crisp-edges';
canvas.style.msInterpolationMode = 'nearest-neighbor'; // No effect on Canvas :/
},
SMOOTH: function( canvas, context ) {
ig.setVendorAttribute( context, 'imageSmoothingEnabled', true );
canvas.style.imageRendering = '';
canvas.style.msInterpolationMode = '';
}
};
ig.System.scaleMode = ig.System.SCALE.SMOOTH;
});
+72
View File
@@ -0,0 +1,72 @@
ig.module(
'impact.timer'
)
.defines(function(){ "use strict";
ig.Timer = ig.Class.extend({
target: 0,
base: 0,
last: 0,
pausedAt: 0,
init: function( seconds ) {
this.base = ig.Timer.time;
this.last = ig.Timer.time;
this.target = seconds || 0;
},
set: function( seconds ) {
this.target = seconds || 0;
this.base = ig.Timer.time;
this.pausedAt = 0;
},
reset: function() {
this.base = ig.Timer.time;
this.pausedAt = 0;
},
tick: function() {
var delta = ig.Timer.time - this.last;
this.last = ig.Timer.time;
return (this.pausedAt ? 0 : delta);
},
delta: function() {
return (this.pausedAt || ig.Timer.time) - this.base - this.target;
},
pause: function() {
if( !this.pausedAt ) {
this.pausedAt = ig.Timer.time;
}
},
unpause: function() {
if( this.pausedAt ) {
this.base += ig.Timer.time - this.pausedAt;
this.pausedAt = 0;
}
}
});
ig.Timer._last = 0;
ig.Timer.time = Number.MIN_VALUE;
ig.Timer.timeScale = 1;
ig.Timer.maxStep = 0.05;
ig.Timer.step = function() {
var current = Date.now();
var delta = (current - ig.Timer._last) / 1000;
ig.Timer.time += Math.min(delta, ig.Timer.maxStep) * ig.Timer.timeScale;
ig.Timer._last = current;
};
});
+40
View File
@@ -0,0 +1,40 @@
<?php
require_once( 'config.php' );
$dir = WM_Config::$fileRoot . str_replace( '..', '', $_GET['dir'] );
if( $dir{strlen($dir)-1} != '/' ) {
$dir .= '/';
}
$find = '*.*';
switch( $_GET['type'] ) {
case 'images':
$find = '*.{png,gif,jpg,jpeg}';
break;
case 'scripts':
$find = '*.js';
break;
}
$dirs = glob( $dir.'*', GLOB_ONLYDIR );
if( $dirs === false ) { $dirs = array(); };
$files = glob( $dir.$find, GLOB_BRACE );
if( $files === false ) { $files = array(); }
$fileRootLength = strlen( WM_Config::$fileRoot );
foreach( $files as $i => $f ) {
$files[$i] = substr( $f, $fileRootLength );
}
foreach( $dirs as $i => $d ) {
$dirs[$i] = substr( $d, $fileRootLength );
}
$parent = substr($_GET['dir'], 0, strrpos($_GET['dir'], '/'));
echo json_encode( array(
'parent' => (empty($_GET['dir']) ? false : $parent),
'dirs' => $dirs,
'files' => $files
));
?>
+22
View File
@@ -0,0 +1,22 @@
<?php
class WM_Config {
public static $fileRoot = '../../../';
}
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map( 'stripslashes_deep', $value ) :
stripslashes($value);
return $value;
}
// revert magic quotes
if( function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ) {
$_GET = array_map( 'stripslashes_deep', $_GET );
$_POST = array_map( 'stripslashes_deep', $_POST );
}
?>
+21
View File
@@ -0,0 +1,21 @@
<?php
require_once( 'config.php' );
$globs = is_array($_GET['glob']) ? $_GET['glob'] : array($_GET['glob']);
$files = array();
foreach( $globs as $glob ) {
$pattern = WM_Config::$fileRoot . str_replace( '..', '', $glob );
$currentFiles = glob( $pattern );
if( $currentFiles !== false ) {
$files = array_merge( $files, $currentFiles );
}
}
$fileRootLength = strlen( WM_Config::$fileRoot );
foreach( $files as $i => $f ) {
$files[$i] = substr( $f, $fileRootLength );
}
echo json_encode( $files );
?>
+34
View File
@@ -0,0 +1,34 @@
<?php
require_once( 'config.php' );
$result = array('error' => 0);
if( !empty($_POST['path']) && !empty($_POST['data']) ) {
$path = WM_Config::$fileRoot . str_replace( '..', '', $_POST['path'] );
if( preg_match('/\.js$/', $path) ) {
$success = @file_put_contents( $path, $_POST['data'] );
if( $success === false ) {
$result = array(
'error' => '2',
'msg' => "Couldn't write to file: $path"
);
}
}
else {
$result = array(
'error' => '3',
'msg' => "File must have a .js suffix"
);
}
}
else {
$result = array(
'error' => '1',
'msg' => "No Data or Path specified"
);
}
echo json_encode($result);
?>
Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+127
View File
@@ -0,0 +1,127 @@
ig.module(
'weltmeister.config'
)
.defines(function(){ "use strict";
wm.config = {
project: {
// The prefix path of your game's source code. You only have to change
// this if you use the 'ImpactPrefix' in your dev environment.
'modulePath': 'lib/',
// This "glob" tells Weltmeister where to load the entity files
// from. If you want to load entities from several directories,
// you can specify an array here. E.g.:
// 'entityFiles': ['lib/game/powerups/*.js', 'lib/game/entities/*.js']
'entityFiles': 'lib/game/entities/*.js',
// The default path for the level file selection box
'levelPath': 'lib/game/levels/',
// Whether to save levels as plain JSON or wrapped in a module. If
// you want to load levels asynchronously via AJAX, saving as plain
// JSON can be helpful.
'outputFormat': 'module', // 'module' or 'json'
// Whether to pretty print the JSON data in level files. If you have
// any issues with your levels, it's usually a good idea to turn this
// on and look at the saved level files with a text editor.
'prettyPrint': true
},
// Plugins for Weltmeister: an array of module names to load
plugins: [],
// Default settings when creating new layers in Weltmeister. Change these
// as you like
'layerDefaults': {
'width': 30,
'height': 20,
'tilesize': 8
},
// Whether to ask before closing Weltmeister when there are unsaved changes
'askBeforeClose': true,
// Whether to attempt to load the last opened level on startup
'loadLastLevel': true,
// Size of the "snap" grid when moving entities
'entityGrid': 4,
// Number of undo levels. You may want to increase this if you use 'undo'
// frequently.
'undoLevels': 50,
// Mouse and Key bindings in Weltmeister. Some function are bound to
// several keys. See the documentation of ig.Input for a list of available
// key names.
'binds': {
'MOUSE1': 'draw',
'MOUSE2': 'drag',
'SHIFT': 'select',
'CTRL': 'drag',
'SPACE': 'menu',
'DELETE': 'delete',
'BACKSPACE': 'delete',
'G': 'grid',
'C': 'clone',
'Z': 'undo',
'Y': 'redo',
'MWHEEL_UP': 'zoomin',
'PLUS': 'zoomin',
'MWHEEL_DOWN': 'zoomout',
'MINUS': 'zoomout'
},
// Whether to enable unidirectional scrolling for touchpads; this
// automatically unbinds the MWHEEL_UP and MWHEEL_DOWN actions.
'touchScroll': false,
// View settings. You can change the default Zoom level and whether
// to show the grid on startup here.
'view': {
'zoom': 1,
'zoomMax': 4,
'zoomMin': 0.125,
'grid': false
},
// Font face and size for entity labels and the grid coordinates
'labels': {
'draw': true,
'step': 32,
'font': '10px Bitstream Vera Sans Mono, Monaco, sans-serif'
},
// Colors to use for the background, selection boxes, text and the grid
'colors': {
'clear': '#000000', // Background Color
'highlight': '#ceff36', // Currently selected tile or entity
'primary': '#ffffff', // Labels and layer bounds
'secondary': '#555555', // Grid and tile selection bounds
'selection': '#ff9933' // Selection cursor box on tile maps
},
// Settings for the Collision tiles. You shouldn't need to change these.
// The tilesize only specifies the size in the image - resizing to final
// size for each layer happens in Weltmeister.
'collisionTiles': {
'path': 'lib/weltmeister/collisiontiles-64.png',
'tilesize': 64
},
// API paths for saving levels and browsing directories. If you use a
// different backend (i.e. not the official PHP backend), you may have
// to change these.
'api': {
'save': 'lib/weltmeister/api/save.php',
'browse': 'lib/weltmeister/api/browse.php',
'glob': 'lib/weltmeister/api/glob.php'
}
};
});
+697
View File
@@ -0,0 +1,697 @@
ig.module(
'weltmeister.edit-entities'
)
.requires(
'impact.game',
'impact.background-map',
'weltmeister.config',
'weltmeister.tile-select',
'weltmeister.entities'
)
.defines(function(){ "use strict";
wm.EditEntities = ig.Class.extend({
visible: true,
active: true,
div: null,
hotkey: -1,
ignoreLastClick: false,
name: 'entities',
entities: [],
namedEntities: {},
selectedEntity: null,
entityClasses: {},
menuDiv: null,
selector: {size:{x:2, y:2}, pos:{x:0,y:0}, offset:{x:0,y:0}},
wasSelectedOnScaleBorder: false,
gridSize: wm.config.entityGrid,
entityDefinitions: null,
init: function( div ) {
this.div = div;
div.bind( 'mouseup', this.click.bind(this) );
this.div.children('.visible').bind( 'mousedown', this.toggleVisibilityClick.bind(this) );
this.menu = $('#entityMenu');
this.importEntityClass( wm.entityModules );
this.entityDefinitions = $('#entityDefinitions');
$('#entityKey').bind( 'keydown', function(ev){
if( ev.which == 13 ){
$('#entityValue').focus();
return false;
}
return true;
});
$('#entityValue').bind( 'keydown', this.setEntitySetting.bind(this) );
},
clear: function() {
this.entities = [];
this.selectEntity( null );
},
sort: function() {
this.entities.sort( ig.Game.SORT.Z_INDEX );
},
// -------------------------------------------------------------------------
// Loading, Saving
fileNameToClassName: function( name ) {
var typeName = '-' + name.replace(/^.*\/|\.js/g,'');
typeName = typeName.replace(/-(\w)/g, function( m, a ) {
return a.toUpperCase();
});
return 'Entity' + typeName;
},
importEntityClass: function( modules ) {
var unloadedClasses = [];
for( var m in modules ) {
var className = this.fileNameToClassName(modules[m]);
var entityName = className.replace(/^Entity/, '');
// ig.global[className] should be the actual class object
if( className && ig.global[className] ) {
// Ignore entities that have the _wmIgnore flag
if( !ig.global[className].prototype._wmIgnore ) {
var a = $( '<div/>', {
'id': className,
'href': '#',
'html': entityName,
'mouseup': this.newEntityClick.bind(this)
});
this.menu.append( a );
this.entityClasses[className] = m;
}
}
else {
unloadedClasses.push( modules[m] + ' (expected name: ' + className + ')' );
}
}
if( unloadedClasses.length > 0 ) {
var warning = 'The following entity classes were not loaded due to\n'
+ 'file and class name mismatches: \n\n'
+ unloadedClasses.join( '\n' );
alert( warning );
}
},
getEntityByName: function( name ) {
return this.namedEntities[name];
},
getSaveData: function() {
var ents = [];
for( var i = 0; i < this.entities.length; i++ ) {
var ent = this.entities[i];
var type = ent._wmClassName;
var data = {type:type,x:ent.pos.x,y:ent.pos.y};
var hasSettings = false;
for( var p in ent._wmSettings ) {
hasSettings = true;
}
if( hasSettings ) {
data.settings = ent._wmSettings;
}
ents.push( data );
}
return ents;
},
// -------------------------------------------------------------------------
// Selecting
selectEntityAt: function( x, y ) {
this.selector.pos = { x: x, y: y };
// Find all possible selections
var possibleSelections = [];
for( var i = 0; i < this.entities.length; i++ ) {
if( this.entities[i].touches(this.selector) ) {
possibleSelections.push( this.entities[i] );
}
}
// Nothing found? Early out.
if( !possibleSelections.length ) {
this.selectEntity( null );
return false;
}
// Find the 'next' selection
var selectedIndex = possibleSelections.indexOf(this.selectedEntity);
var nextSelection = (selectedIndex + 1) % possibleSelections.length;
var ent = possibleSelections[nextSelection];
// Select it!
this.selector.offset = {
x: (x - ent.pos.x + ent.offset.x),
y: (y - ent.pos.y + ent.offset.y)
};
this.selectEntity( ent );
this.wasSelectedOnScaleBorder = this.isOnScaleBorder( ent, this.selector );
return ent;
},
selectEntity: function( entity ) {
if( entity && entity != this.selectedEntity ) {
this.selectedEntity = entity;
$('#entitySettings').fadeOut(100,(function(){
this.loadEntitySettings();
$('#entitySettings').fadeIn(100);
}).bind(this));
}
else if( !entity ) {
$('#entitySettings').fadeOut(100);
$('#entityKey').blur();
$('#entityValue').blur();
}
this.selectedEntity = entity;
$('#entityKey').val('');
$('#entityValue').val('');
},
// -------------------------------------------------------------------------
// Creating, Deleting, Moving
deleteSelectedEntity: function() {
if( !this.selectedEntity ) {
return false;
}
ig.game.undo.commitEntityDelete( this.selectedEntity );
this.removeEntity( this.selectedEntity );
this.selectEntity( null );
return true;
},
removeEntity: function( ent ) {
if( ent.name ) {
delete this.namedEntities[ent.name];
}
this.entities.erase( ent );
},
cloneSelectedEntity: function() {
if( !this.selectedEntity ) {
return false;
}
var className = this.selectedEntity._wmClassName;
var settings = ig.copy(this.selectedEntity._wmSettings);
if( settings.name ) {
settings.name = settings.name + '_clone';
}
var x = this.selectedEntity.pos.x + this.gridSize;
var y = this.selectedEntity.pos.y;
var newEntity = this.spawnEntity( className, x, y, settings );
newEntity._wmSettings = settings;
this.selectEntity( newEntity );
ig.game.undo.commitEntityCreate( newEntity );
return true;
},
dragOnSelectedEntity: function( x, y ) {
if( !this.selectedEntity ) {
return false;
}
// scale or move?
if( this.selectedEntity._wmScalable && this.wasSelectedOnScaleBorder ) {
this.scaleSelectedEntity( x, y );
}
else {
this.moveSelectedEntity( x, y )
}
ig.game.undo.pushEntityEdit( this.selectedEntity );
return true;
},
moveSelectedEntity: function( x, y ) {
x =
Math.round( (x - this.selector.offset.x ) / this.gridSize )
* this.gridSize + this.selectedEntity.offset.x;
y =
Math.round( (y - this.selector.offset.y ) / this.gridSize )
* this.gridSize + this.selectedEntity.offset.y;
// new position?
if( this.selectedEntity.pos.x != x || this.selectedEntity.pos.y != y ) {
$('#entityDefinitionPosX').text( x );
$('#entityDefinitionPosY').text( y );
this.selectedEntity.pos.x = x;
this.selectedEntity.pos.y = y;
}
},
scaleSelectedEntity: function( x, y ) {
var scale = this.wasSelectedOnScaleBorder;
var w = Math.round( x / this.gridSize ) * this.gridSize - this.selectedEntity.pos.x;
if( !this.selectedEntity._wmSettings.size ) {
this.selectedEntity._wmSettings.size = {};
}
if( scale == 'n' ) {
var h = this.selectedEntity.pos.y - Math.round( y / this.gridSize ) * this.gridSize;
if( this.selectedEntity.size.y + h <= this.gridSize ) {
h = (this.selectedEntity.size.y - this.gridSize) * -1;
}
this.selectedEntity.size.y += h;
this.selectedEntity.pos.y -= h;
}
else if( scale == 's' ) {
var h = Math.round( y / this.gridSize ) * this.gridSize - this.selectedEntity.pos.y;
this.selectedEntity.size.y = Math.max( this.gridSize, h );
}
else if( scale == 'e' ) {
var w = Math.round( x / this.gridSize ) * this.gridSize - this.selectedEntity.pos.x;
this.selectedEntity.size.x = Math.max( this.gridSize, w );
}
else if( scale == 'w' ) {
var w = this.selectedEntity.pos.x - Math.round( x / this.gridSize ) * this.gridSize;
if( this.selectedEntity.size.x + w <= this.gridSize ) {
w = (this.selectedEntity.size.x - this.gridSize) * -1;
}
this.selectedEntity.size.x += w;
this.selectedEntity.pos.x -= w;
}
this.selectedEntity._wmSettings.size.x = this.selectedEntity.size.x;
this.selectedEntity._wmSettings.size.y = this.selectedEntity.size.y;
this.loadEntitySettings();
},
newEntityClick: function( ev ) {
this.hideMenu();
var newEntity = this.spawnEntity( ev.target.id, 0, 0, {} );
this.selectEntity( newEntity );
this.moveSelectedEntity( this.selector.pos.x, this.selector.pos.y );
ig.editor.setModified();
ig.game.undo.commitEntityCreate( newEntity );
},
spawnEntity: function( className, x, y, settings ) {
settings = settings || {};
var entityClass = ig.global[ className ];
if( entityClass ) {
var newEntity = new (entityClass)( x, y, settings );
newEntity._wmInEditor = true;
newEntity._wmClassName = className;
newEntity._wmSettings = {};
for( var s in settings ) {
newEntity._wmSettings[s] = settings[s];
}
this.entities.push( newEntity );
if( settings.name ) {
this.namedEntities[settings.name] = newEntity;
}
this.sort();
return newEntity;
}
return null;
},
isOnScaleBorder: function( entity, selector ) {
var border = 2;
var w = selector.pos.x - entity.pos.x;
var h = selector.pos.y - entity.pos.y;
if( w < border ) return 'w';
if( w > entity.size.x - border ) return 'e';
if( h < border ) return 'n';
if( h > entity.size.y - border ) return 's';
return false;
},
// -------------------------------------------------------------------------
// Settings
loadEntitySettings: function(ent) {
if( !this.selectedEntity ) {
return;
}
var html =
'<div class="entityDefinition"><span class="key">x</span>:<span class="value" id="entityDefinitionPosX">'+this.selectedEntity.pos.x+'</span></div>'
+ '<div class="entityDefinition"><span class="key">y</span>:<span class="value" id="entityDefinitionPosY">'+this.selectedEntity.pos.y+'</span></div>';
html += this.loadEntitySettingsRecursive( this.selectedEntity._wmSettings );
this.entityDefinitions.html( html );
var className = this.selectedEntity._wmClassName.replace(/^Entity/, '');
$('#entityClass').text( className );
$('.entityDefinition').bind( 'mouseup', this.selectEntitySetting );
},
loadEntitySettingsRecursive: function( settings, path ) {
path = path || "";
var html = "";
for( var key in settings ) {
var value = settings[key];
if( typeof(value) == 'object' ) {
html += this.loadEntitySettingsRecursive( value, path + key + "." );
}
else {
html += '<div class="entityDefinition"><span class="key">'+path+key+'</span>:<span class="value">'+value+'</span></div>';
}
}
return html;
},
setEntitySetting: function( ev ) {
if( ev.which != 13 ) {
return true;
}
var key = $('#entityKey').val();
var value = $('#entityValue').val();
var floatVal = parseFloat(value);
if( value == floatVal ) {
value = floatVal;
}
if( key == 'name' ) {
if( this.selectedEntity.name ) {
delete this.namedEntities[this.selectedEntity.name];
}
this.namedEntities[ value ] = this.selectedEntity;
}
if( key == 'x' ) {
this.selectedEntity.pos.x = Math.round(value);
}
else if( key == 'y' ) {
this.selectedEntity.pos.y = Math.round(value);
}
else {
this.writeSettingAtPath( this.selectedEntity._wmSettings, key, value );
ig.merge( this.selectedEntity, this.selectedEntity._wmSettings );
}
this.sort();
ig.game.setModified();
ig.game.draw();
$('#entityKey').val('');
$('#entityValue').val('');
$('#entityValue').blur();
this.loadEntitySettings();
$('#entityKey').focus();
return false;
},
writeSettingAtPath: function( root, path, value ) {
path = path.split('.');
var cur = root;
for( var i = 0; i < path.length; i++ ) {
var n = path[i];
if( i < path.length-1 && typeof(cur[n]) != 'object' ) {
cur[n] = {};
}
if( i == path.length-1 ) {
cur[n] = value;
}
cur = cur[n];
}
this.trimObject( root );
},
trimObject: function( obj ) {
var isEmpty = true;
for( var i in obj ) {
if(
(obj[i] === "") ||
(typeof(obj[i]) == 'object' && this.trimObject(obj[i]))
) {
delete obj[i];
}
if( typeof(obj[i]) != 'undefined' ) {
isEmpty = false;
}
}
return isEmpty;
},
selectEntitySetting: function( ev ) {
$('#entityKey').val( $(this).children('.key').text() );
$('#entityValue').val( $(this).children('.value').text() );
$('#entityValue').select();
},
// -------------------------------------------------------------------------
// UI
setHotkey: function( hotkey ) {
this.hotkey = hotkey;
this.div.attr('title', 'Select Layer ('+this.hotkey+')' );
},
showMenu: function( x, y ) {
this.selector.pos = {
x: Math.round( (x + ig.editor.screen.x) / this.gridSize ) * this.gridSize,
y: Math.round( (y + ig.editor.screen.y) / this.gridSize ) * this.gridSize
};
this.menu.css({top: (y * ig.system.scale + 2), left: (x * ig.system.scale + 2) });
this.menu.show();
},
hideMenu: function( x, y ) {
ig.editor.mode = ig.editor.MODE.DEFAULT;
this.menu.hide();
},
setActive: function( active ) {
this.active = active;
if( active ) {
this.div.addClass( 'layerActive' );
} else {
this.div.removeClass( 'layerActive' );
}
},
toggleVisibility: function() {
this.visible ^= 1;
if( this.visible ) {
this.div.children('.visible').addClass('checkedVis');
} else {
this.div.children('.visible').removeClass('checkedVis');
}
ig.game.draw();
},
toggleVisibilityClick: function( ev ) {
if( !this.active ) {
this.ignoreLastClick = true;
}
this.toggleVisibility()
},
click: function() {
if( this.ignoreLastClick ) {
this.ignoreLastClick = false;
return;
}
ig.editor.setActiveLayer( 'entities' );
},
mousemove: function( x, y ) {
this.selector.pos = { x: x, y: y };
if( this.selectedEntity ) {
if( this.selectedEntity._wmScalable && this.selectedEntity.touches(this.selector) ) {
var scale = this.isOnScaleBorder( this.selectedEntity, this.selector );
if( scale == 'n' || scale == 's' ) {
$('body').css('cursor', 'n-resize');
return;
}
else if( scale == 'e' || scale == 'w' ) {
$('body').css('cursor', 'e-resize');
return;
}
}
}
$('body').css('cursor', 'default');
},
// -------------------------------------------------------------------------
// Drawing
draw: function() {
if( this.visible ) {
for( var i = 0; i < this.entities.length; i++ ) {
this.drawEntity( this.entities[i] );
}
}
},
drawEntity: function( ent ) {
// entity itself
ent.draw();
// box
if( ent._wmDrawBox ) {
ig.system.context.fillStyle = ent._wmBoxColor || 'rgba(128, 128, 128, 0.9)';
ig.system.context.fillRect(
ig.system.getDrawPos(ent.pos.x - ig.game.screen.x),
ig.system.getDrawPos(ent.pos.y - ig.game.screen.y),
ent.size.x * ig.system.scale,
ent.size.y * ig.system.scale
);
}
if( wm.config.labels.draw ) {
// description
var className = ent._wmClassName.replace(/^Entity/, '');
var description = className + (ent.name ? ': ' + ent.name : '' );
// text-shadow
ig.system.context.fillStyle = 'rgba(0,0,0,0.4)';
ig.system.context.fillText(
description,
ig.system.getDrawPos(ent.pos.x - ig.game.screen.x),
ig.system.getDrawPos(ent.pos.y - ig.game.screen.y + 0.5)
);
// text
ig.system.context.fillStyle = wm.config.colors.primary;
ig.system.context.fillText(
description,
ig.system.getDrawPos(ent.pos.x - ig.game.screen.x),
ig.system.getDrawPos(ent.pos.y - ig.game.screen.y)
);
}
// line to targets
if( typeof(ent.target) == 'object' ) {
for( var t in ent.target ) {
this.drawLineToTarget( ent, ent.target[t] );
}
}
},
drawLineToTarget: function( ent, target ) {
target = ig.game.getEntityByName( target );
if( !target ) {
return;
}
ig.system.context.strokeStyle = '#fff';
ig.system.context.lineWidth = 1;
ig.system.context.beginPath();
ig.system.context.moveTo(
ig.system.getDrawPos(ent.pos.x + ent.size.x/2 - ig.game.screen.x),
ig.system.getDrawPos(ent.pos.y + ent.size.y/2 - ig.game.screen.y)
);
ig.system.context.lineTo(
ig.system.getDrawPos(target.pos.x + target.size.x/2 - ig.game.screen.x),
ig.system.getDrawPos(target.pos.y + target.size.y/2 - ig.game.screen.y)
);
ig.system.context.stroke();
ig.system.context.closePath();
},
drawCursor: function( x, y ) {
if( this.selectedEntity ) {
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.highlight;
ig.system.context.strokeRect(
ig.system.getDrawPos(this.selectedEntity.pos.x - ig.editor.screen.x) - 0.5,
ig.system.getDrawPos(this.selectedEntity.pos.y - ig.editor.screen.y) - 0.5,
this.selectedEntity.size.x * ig.system.scale + 1,
this.selectedEntity.size.y * ig.system.scale + 1
);
}
}
});
});
+388
View File
@@ -0,0 +1,388 @@
ig.module(
'weltmeister.edit-map'
)
.requires(
'impact.background-map',
'weltmeister.tile-select'
)
.defines(function(){ "use strict";
wm.EditMap = ig.BackgroundMap.extend({
name: '',
visible: true,
active: true,
linkWithCollision: false,
div: null,
brush: [[0]],
oldData: null,
hotkey: -1,
ignoreLastClick: false,
tileSelect: null,
isSelecting: false,
selectionBegin: null,
init: function( name, tilesize, tileset, foreground ) {
this.name = name;
this.parent( tilesize, [[0]], tileset || '' );
this.foreground = foreground;
this.div = $( '<div/>', {
'class': 'layer layerActive',
'id': ('layer_' + name),
'mouseup': this.click.bind(this)
});
this.setName( name );
if( this.foreground ) {
$('#layers').prepend( this.div );
}
else {
$('#layerEntities').after( this.div );
}
this.tileSelect = new wm.TileSelect( this );
},
getSaveData: function() {
return {
name: this.name,
width: this.width,
height: this.height,
linkWithCollision: this.linkWithCollision,
visible: this.visible,
tilesetName: this.tilesetName,
repeat: this.repeat,
preRender: this.preRender,
distance: this.distance,
tilesize: this.tilesize,
foreground: this.foreground,
data: this.data
};
},
resize: function( newWidth, newHeight ) {
var newData = new Array( newHeight );
for( var y = 0; y < newHeight; y++ ) {
newData[y] = new Array( newWidth );
for( var x = 0; x < newWidth; x++ ) {
newData[y][x] = (x < this.width && y < this.height) ? this.data[y][x] : 0;
}
}
this.data = newData;
this.width = newWidth;
this.height = newHeight;
this.resetDiv();
},
beginEditing: function() {
this.oldData = ig.copy(this.data);
},
getOldTile: function( x, y ) {
var tx = Math.floor( x / this.tilesize );
var ty = Math.floor( y / this.tilesize );
if(
(tx >= 0 && tx < this.width) &&
(ty >= 0 && ty < this.height)
) {
return this.oldData[ty][tx];
}
else {
return 0;
}
},
setTileset: function( tileset ) {
if( this.name == 'collision' ) {
this.setCollisionTileset();
}
else {
this.parent( tileset );
}
},
setCollisionTileset: function() {
var path = wm.config.collisionTiles.path;
var scale = this.tilesize / wm.config.collisionTiles.tilesize;
this.tiles = new ig.AutoResizedImage( path, scale );
},
// -------------------------------------------------------------------------
// UI
setHotkey: function( hotkey ) {
this.hotkey = hotkey;
this.setName( this.name );
},
setName: function( name ) {
this.name = name.replace(/[^0-9a-zA-Z]/g, '_');
this.resetDiv();
},
resetDiv: function() {
var visClass = this.visible ? ' checkedVis' : '';
this.div.html(
'<span class="visible'+visClass+'" title="Toggle Visibility (Shift+'+this.hotkey+')"></span>' +
'<span class="name">' + this.name + '</span>' +
'<span class="size"> (' + this.width + 'x' + this.height + ')</span>'
);
this.div.attr('title', 'Select Layer ('+this.hotkey+')' );
this.div.children('.visible').bind('mousedown', this.toggleVisibilityClick.bind(this) );
},
setActive: function( active ) {
this.active = active;
if( active ) {
this.div.addClass( 'layerActive' );
} else {
this.div.removeClass( 'layerActive' );
}
},
toggleVisibility: function() {
this.visible ^= 1;
this.resetDiv();
if( this.visible ) {
this.div.children('.visible').addClass('checkedVis');
} else {
this.div.children('.visible').removeClass('checkedVis');
}
ig.game.draw();
},
toggleVisibilityClick: function( event ) {
if( !this.active ) {
this.ignoreLastClick = true;
}
this.toggleVisibility()
},
click: function() {
if( this.ignoreLastClick ) {
this.ignoreLastClick = false;
return;
}
ig.editor.setActiveLayer( this.name );
},
destroy: function() {
this.div.remove();
},
// -------------------------------------------------------------------------
// Selecting
beginSelecting: function( x, y ) {
this.isSelecting = true;
this.selectionBegin = {x:x, y:y};
},
endSelecting: function( x, y ) {
var r = this.getSelectionRect( x, y);
var brush = [];
for( var ty = r.y; ty < r.y+r.h; ty++ ) {
var row = [];
for( var tx = r.x; tx < r.x+r.w; tx++ ) {
if( tx < 0 || ty < 0 || tx >= this.width || ty >= this.height ) {
row.push( 0 );
}
else {
row.push( this.data[ty][tx] );
}
}
brush.push( row );
}
this.isSelecting = false;
this.selectionBegin = null;
return brush;
},
getSelectionRect: function( x, y ) {
var sx = this.selectionBegin ? this.selectionBegin.x : x,
sy = this.selectionBegin ? this.selectionBegin.y : y;
var
txb = Math.floor( (sx + this.scroll.x) / this.tilesize ),
tyb = Math.floor( (sy + this.scroll.y) / this.tilesize ),
txe = Math.floor( (x + this.scroll.x) / this.tilesize ),
tye = Math.floor( (y + this.scroll.y) / this.tilesize );
return {
x: Math.min( txb, txe ),
y: Math.min( tyb, tye ),
w: Math.abs( txb - txe) + 1,
h: Math.abs( tyb - tye) + 1
}
},
// -------------------------------------------------------------------------
// Drawing
draw: function() {
// For performance reasons, repeated background maps are not drawn
// when zoomed out
if( this.visible && !(wm.config.view.zoom < 1 && this.repeat) ) {
this.drawTiled();
}
// Grid
if( this.active && wm.config.view.grid ) {
var x = -ig.system.getDrawPos(this.scroll.x % this.tilesize) - 0.5;
var y = -ig.system.getDrawPos(this.scroll.y % this.tilesize) - 0.5;
var step = this.tilesize * ig.system.scale;
ig.system.context.beginPath();
for( x; x < ig.system.realWidth; x += step ) {
ig.system.context.moveTo( x, 0 );
ig.system.context.lineTo( x, ig.system.realHeight );
}
for( y; y < ig.system.realHeight; y += step ) {
ig.system.context.moveTo( 0, y );
ig.system.context.lineTo( ig.system.realWidth, y );
}
ig.system.context.strokeStyle = wm.config.colors.secondary;
ig.system.context.stroke();
ig.system.context.closePath();
// Not calling beginPath() again has some weird performance issues
// in Firefox 5. closePath has no effect. So to make it happy:
ig.system.context.beginPath();
}
// Bounds
if( this.active ) {
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.primary;
ig.system.context.strokeRect(
-ig.system.getDrawPos(this.scroll.x) - 0.5,
-ig.system.getDrawPos(this.scroll.y) - 0.5,
this.width * this.tilesize * ig.system.scale + 1,
this.height * this.tilesize * ig.system.scale + 1
);
}
},
getCursorOffset: function() {
var w = this.brush[0].length;
var h = this.brush.length;
//return {x:0, y:0};
return {
x: (w/2-0.5).toInt() * this.tilesize,
y: (h/2-0.5).toInt() * this.tilesize
}
},
drawCursor: function( x, y ) {
if( this.isSelecting ) {
var r = this.getSelectionRect( x, y);
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.selection;
ig.system.context.strokeRect(
(r.x * this.tilesize - this.scroll.x) * ig.system.scale - 0.5,
(r.y * this.tilesize - this.scroll.y) * ig.system.scale - 0.5,
r.w * this.tilesize * ig.system.scale + 1,
r.h * this.tilesize * ig.system.scale + 1
);
}
else {
var w = this.brush[0].length;
var h = this.brush.length;
var co = this.getCursorOffset();
var cx = Math.floor( (x+this.scroll.x) / this.tilesize ) * this.tilesize - this.scroll.x - co.x;
var cy = Math.floor( (y+this.scroll.y) / this.tilesize ) * this.tilesize - this.scroll.y - co.y;
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.primary;
ig.system.context.strokeRect(
ig.system.getDrawPos(cx)-0.5,
ig.system.getDrawPos(cy)-0.5,
w * this.tilesize * ig.system.scale + 1,
h * this.tilesize * ig.system.scale + 1
);
ig.system.context.globalAlpha = 0.5;
for( var ty = 0; ty < h; ty++ ) {
for( var tx = 0; tx < w; tx++ ) {
var t = this.brush[ty][tx];
if( t ) {
var px = cx + tx * this.tilesize;
var py = cy + ty * this.tilesize;
this.tiles.drawTile( px, py, t-1, this.tilesize );
}
}
}
ig.system.context.globalAlpha = 1;
}
}
});
ig.AutoResizedImage = ig.Image.extend({
internalScale: 1,
staticInstantiate: function() {
return null; // Never cache!
},
init: function( path, internalScale ) {
this.internalScale = internalScale;
this.parent( path );
},
onload: function( event ) {
this.width = Math.ceil(this.data.width * this.internalScale);
this.height = Math.ceil(this.data.height * this.internalScale);
if( this.internalScale != 1 ) {
var scaled = ig.$new('canvas');
scaled.width = this.width;
scaled.height = this.height;
var scaledCtx = scaled.getContext('2d');
scaledCtx.drawImage( this.data, 0, 0, this.data.width, this.data.height, 0, 0, this.width , this.height );
this.data = scaled;
}
this.loaded = true;
if( ig.system.scale != 1 ) {
this.resize( ig.system.scale );
}
if( this.loadCallback ) {
this.loadCallback( this.path, true );
}
}
});
});
+58
View File
@@ -0,0 +1,58 @@
ig.module(
'weltmeister.entityLoader'
)
.requires(
'weltmeister.config'
)
.defines(function(){ "use strict";
// Load the list of entity files via AJAX PHP glob
var path = wm.config.api.glob + '?',
globs = typeof wm.config.project.entityFiles == 'string' ?
[wm.config.project.entityFiles] :
wm.config.project.entityFiles;
for (var i = 0; i < globs.length; i++) {
path += 'glob[]=' + encodeURIComponent(globs[i]) + '&';
}
path += 'nocache=' + Math.random();
var req = $.ajax({
url: path,
method: 'get',
dataType: 'json',
// MUST load synchronous, as the engine would otherwise determine that it
// can't resolve dependencies to weltmeister.entities when there are
// no more files to load and weltmeister.entities is still not defined
// because the ajax request hasn't finished yet.
// FIXME FFS!
async: false,
success: function(files) {
// File names to Module names
var moduleNames = [];
var modules = {};
for( var i = 0; i < files.length; i++ ) {
var name = files[i]
.replace(new RegExp("^"+ig.lib+"|\\.js$", "g"), '')
.replace(/\//g, '.');
moduleNames.push( name );
modules[name] = files[i];
}
// Define a Module that requires all entity Modules
ig.module('weltmeister.entities')
.requires.apply(ig, moduleNames)
.defines(function(){ wm.entityModules = modules; });
},
error: function( xhr, status, error ){
throw(
"Failed to load entity list via glob.php: " + error + "\n" +
xhr.responseText
);
}
});
});
+79
View File
@@ -0,0 +1,79 @@
ig.module(
'weltmeister.evented-input'
)
.requires(
'impact.input'
)
.defines(function(){ "use strict";
wm.EventedInput = ig.Input.extend({
mousemoveCallback: null,
keyupCallback: null,
keydownCallback: null,
delayedKeyup: {push:function(){},length: 0},
keydown: function( event ) {
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keydown'
? event.keyCode
: (event.button == 2 ? ig.KEY.MOUSE2 : ig.KEY.MOUSE1);
var action = this.bindings[code];
if( action ) {
if( !this.actions[action] ) {
this.actions[action] = true;
if( this.keydownCallback ) {
this.keydownCallback( action );
}
}
event.stopPropagation();
event.preventDefault();
}
},
keyup: function( event ) {
var tag = event.target.tagName;
if( tag == 'INPUT' || tag == 'TEXTAREA' ) { return; }
var code = event.type == 'keyup'
? event.keyCode
: (event.button == 2 ? ig.KEY.MOUSE2 : ig.KEY.MOUSE1);
var action = this.bindings[code];
if( action ) {
this.actions[action] = false;
if( this.keyupCallback ) {
this.keyupCallback( action );
}
event.stopPropagation();
event.preventDefault();
}
},
mousewheel: function( event ) {
var delta = event.wheelDelta ? event.wheelDelta : (event.detail * -1);
var code = delta > 0 ? ig.KEY.MWHEEL_UP : ig.KEY.MWHEEL_DOWN;
var action = this.bindings[code];
if( action ) {
if( this.keyupCallback ) {
this.keyupCallback( action );
}
event.stopPropagation();
event.preventDefault();
}
},
mousemove: function( event ) {
this.parent( event );
if( this.mousemoveCallback ) {
this.mousemoveCallback();
}
}
});
});
File diff suppressed because one or more lines are too long
+107
View File
@@ -0,0 +1,107 @@
/*!
* jQuery UI 1.8.1
*
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI
*/
jQuery.ui||function(c){c.ui={version:"1.8.1",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")=="hidden")return false;
b=b&&b=="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,f,g){return c.ui.isOverAxis(a,d,f)&&c.ui.isOverAxis(b,e,g)},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,
PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||
/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==
undefined)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b=="absolute"||b=="relative"||b=="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b||"area"==b?a.href||!isNaN(d):!isNaN(d))&&
!c(a)["area"==b?"parents":"closest"](":hidden").length},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}(jQuery);
;/*!
* jQuery UI Widget 1.8.1
*
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Widget
*/
(function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend({},c.options);b[e][a].prototype=
b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==undefined){h=i;return false}}):this.each(function(){var g=
b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();
this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(f,
h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=
b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
;/*!
* jQuery UI Mouse 1.8.1
*
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Mouse
*
* Depends:
* jquery.ui.widget.js
*/
(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
;/*
* jQuery UI Sortable 1.8.1
*
* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://docs.jquery.com/UI/Sortables
*
* Depends:
* jquery.ui.core.js
* jquery.ui.mouse.js
* jquery.ui.widget.js
*/
(function(d){d.widget("ui.sortable",d.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable");
this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(self,
arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=
c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,
{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();
if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",
a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop+b.scrollSpeed;else if(a.pageY-this.overflowOffset.top<b.scrollSensitivity)this.scrollParent[0].scrollTop=c=this.scrollParent[0].scrollTop-b.scrollSpeed;if(this.overflowOffset.left+
this.scrollParent[0].offsetWidth-a.pageX<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft+b.scrollSpeed;else if(a.pageX-this.overflowOffset.left<b.scrollSensitivity)this.scrollParent[0].scrollLeft=c=this.scrollParent[0].scrollLeft-b.scrollSpeed}else{if(a.pageY-d(document).scrollTop()<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()-b.scrollSpeed);else if(d(window).height()-(a.pageY-d(document).scrollTop())<b.scrollSensitivity)c=d(document).scrollTop(d(document).scrollTop()+
b.scrollSpeed);if(a.pageX-d(document).scrollLeft()<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()-b.scrollSpeed);else if(d(window).width()-(a.pageX-d(document).scrollLeft())<b.scrollSensitivity)c=d(document).scrollLeft(d(document).scrollLeft()+b.scrollSpeed)}c!==false&&d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+
"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(b=this.items.length-1;b>=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,
c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==
document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp();this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",
null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):
d(this.domPosition.parent).prepend(this.currentItem);return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},
_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+j<k&&b+l>g&&b+l<h;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?j:g<b+this.helperProportions.width/
2&&c-this.helperProportions.width/2<h&&i<e+this.helperProportions.height/2&&f-this.helperProportions.height/2<k},_intersectsWithPointer:function(a){var b=d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width);b=b&&a;a=this._getDragVerticalDirection();var c=this._getDragHorizontalDirection();if(!b)return false;return this.floating?c&&c=="right"||a=="down"?2:1:a&&(a=="down"?2:1)},_intersectsWithSides:function(a){var b=
d.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height);a=d.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width);var c=this._getDragVerticalDirection(),e=this._getDragHorizontalDirection();return this.floating&&e?e=="right"&&a||e=="left"&&!a:c&&(c=="down"&&b||c=="up"&&!b)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=
this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?
h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),
b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var b=this.items,c=[[d.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):d(this.options.items,this.element),this]],e=this._connectWith();if(e)for(var f=e.length-1;f>=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?
i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h<g;h++){i=d(e[h]);i.data("sortable-item",a);b.push({item:i,instance:a,width:0,height:0,left:0,top:0})}}},refreshPositions:function(a){if(this.offsetParent&&this.helper)this.offset.parent=this._getParentOffset();for(var b=this.items.length-1;b>=0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement,
c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=
this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-
parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],
this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=
1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)<b){b=Math.abs(h-f);e=this.items[g]}}if(e||this.options.dropOnEmpty){this.currentContainer=this.containers[c];e?this._rearrange(a,e,null,true):this._rearrange(a,null,this.containers[c].element,true);this._trigger("change",a,this._uiHash());this.containers[c]._trigger("change",
a,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}}},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a,this.currentItem])):b.helper=="clone"?this.currentItem.clone():this.currentItem;a.parents("body").length||d(b.appendTo!="parent"?b.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);if(a[0]==
this.currentItem[0])this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")};if(a[0].style.width==""||b.forceHelperSize)a.width(this.currentItem.width());if(a[0].style.height==""||b.forceHelperSize)a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||
0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-
(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;
if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var b=
d(a.containment)[0];a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-
this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);return{top:b.top+
this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],
this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();var f=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.left<this.containment[0])f=this.containment[0]+this.offset.click.left;if(a.pageY-this.offset.click.top<this.containment[1])g=this.containment[1]+this.offset.click.top;
if(a.pageX-this.offset.click.left>this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:!(g-this.offset.click.top<this.containment[1])?g-b.grid[1]:g+b.grid[1]:g;f=this.originalPageX+Math.round((f-
this.originalPageX)/b.grid[0])*b.grid[0];f=this.containment?!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:!(f-this.offset.click.left<this.containment[0])?f-b.grid[0]:f+b.grid[0]:f}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:c.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+
(d.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:c.scrollLeft())}},_rearrange:function(a,b,c,e){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var f=this,g=this.counter;window.setTimeout(function(){g==f.counter&&f.refreshPositions(!e)},0)},_clear:function(a,b){this.reverting=false;var c=[];!this._noFinalSort&&
this.currentItem[0].parentNode&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var e in this._storedCSS)if(this._storedCSS[e]=="auto"||this._storedCSS[e]=="static")this._storedCSS[e]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!b&&c.push(function(f){this._trigger("receive",f,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||
this.domPosition.parent!=this.currentItem.parent()[0])&&!b)c.push(function(f){this._trigger("update",f,this._uiHash())});if(!d.ui.contains(this.element[0],this.currentItem[0])){b||c.push(function(f){this._trigger("remove",f,this._uiHash())});for(e=this.containers.length-1;e>=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",
g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",
this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}return false}b||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!b){for(e=
0;e<c.length;e++)c[e].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){d.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},_uiHash:function(a){var b=a||this;return{helper:b.helper,placeholder:b.placeholder||d([]),position:b.position,originalPosition:b.originalPosition,offset:b.positionAbs,item:b.currentItem,sender:a?a.element:null}}});d.extend(d.ui.sortable,{version:"1.8.1"})})(jQuery);
;
+108
View File
@@ -0,0 +1,108 @@
ig.module(
'weltmeister.modal-dialogs'
)
.requires(
'weltmeister.select-file-dropdown'
)
.defines(function(){ "use strict";
wm.ModalDialog = ig.Class.extend({
onOk: null,
onCancel: null,
text: '',
okText: '',
cancelText: '',
background: null,
dialogBox: null,
buttonDiv: null,
init: function( text, okText, cancelText ) {
this.text = text;
this.okText = okText || 'OK';
this.cancelText = cancelText || 'Cancel';
this.background = $('<div/>', {'class':'modalDialogBackground'});
this.dialogBox = $('<div/>', {'class':'modalDialogBox'});
this.background.append( this.dialogBox );
$('body').append( this.background );
this.initDialog( text );
},
initDialog: function() {
this.buttonDiv = $('<div/>', {'class': 'modalDialogButtons'} );
var okButton = $('<input/>', {'type': 'button', 'class':'button', 'value': this.okText});
var cancelButton = $('<input/>', {'type': 'button', 'class':'button', 'value': this.cancelText});
okButton.bind( 'click', this.clickOk.bind(this) );
cancelButton.bind( 'click', this.clickCancel.bind(this) );
this.buttonDiv.append( okButton ).append( cancelButton );
this.dialogBox.html('<div class="modalDialogText">' + this.text + '</div>' );
this.dialogBox.append( this.buttonDiv );
},
clickOk: function() {
if( this.onOk ) { this.onOk(this); }
this.close();
},
clickCancel: function() {
if( this.onCancel ) { this.onCancel(this); }
this.close();
},
open: function() {
this.background.fadeIn(100);
},
close: function() {
this.background.fadeOut(100);
}
});
wm.ModalDialogPathSelect = wm.ModalDialog.extend({
pathDropdown: null,
pathInput: null,
fileType: '',
init: function( text, okText, type ) {
this.fileType = type || '';
this.parent( text, (okText || 'Select') );
},
setPath: function( path ) {
var dir = path.replace(/\/[^\/]*$/, '');
this.pathInput.val( path );
this.pathDropdown.loadDir( dir );
},
initDialog: function() {
this.parent();
this.pathInput = $('<input/>', {'type': 'text', 'class': 'modalDialogPath'} );
this.buttonDiv.before( this.pathInput );
this.pathDropdown = new wm.SelectFileDropdown( this.pathInput, wm.config.api.browse, this.fileType );
},
clickOk: function() {
if( this.onOk ) {
this.onOk(this, this.pathInput.val());
}
this.close();
}
});
});
+99
View File
@@ -0,0 +1,99 @@
ig.module(
'weltmeister.select-file-dropdown'
)
.defines(function(){ "use strict";
wm.SelectFileDropdown = ig.Class.extend({
input: null,
boundShow: null,
div: null,
filelistPHP: '',
filetype: '',
init: function( elementId, filelistPHP, filetype ) {
this.filetype = filetype || '';
this.filelistPHP = filelistPHP;
this.input = $(elementId);
this.boundHide = this.hide.bind(this);
this.input.bind('focus', this.show.bind(this) );
this.div = $('<div/>', {'class':'selectFileDialog'});
this.input.after( this.div );
this.div.bind('mousedown', this.noHide.bind(this) );
this.loadDir( '' );
},
loadDir: function( dir ) {
var path = this.filelistPHP + '?dir=' + encodeURIComponent( dir || '' ) + '&type=' + this.filetype;
var req = $.ajax({
url:path,
dataType: 'json',
async: false,
success:this.showFiles.bind(this)
});
},
selectDir: function( event ) {
this.loadDir( $(event.target).attr('href') );
return false;
},
selectFile: function( event ) {
this.input.val( $(event.target).attr('href') );
this.input.blur();
this.hide();
return false;
},
showFiles: function( data ) {
this.div.empty();
if( data.parent !== false ) {
var parentDir = $('<a/>', {'class':'dir', href:data.parent, html: '&hellip;parent directory'});
parentDir.bind( 'click', this.selectDir.bind(this) );
this.div.append( parentDir );
}
for( var i = 0; i < data.dirs.length; i++ ) {
var name = data.dirs[i].match(/[^\/]*$/)[0] + '/';
var dir = $('<a/>', {'class':'dir', href:data.dirs[i], html: name, title: name});
dir.bind( 'click', this.selectDir.bind(this) );
this.div.append( dir );
}
for( var i = 0; i < data.files.length; i++ ) {
var name = data.files[i].match(/[^\/]*$/)[0];
var file = $('<a/>', {'class':'file', href:data.files[i], html: name, title: name});
file.bind( 'click', this.selectFile.bind(this) );
this.div.append( file );
}
},
noHide: function(event) {
event.stopPropagation();
},
show: function( event ) {
var inputPos = this.input.position();//this.input.getPosition(this.input.getOffsetParent());
var inputHeight = parseInt(this.input.innerHeight()) + parseInt(this.input.css('margin-top'));
var inputWidth = this.input.innerWidth();
$(document).bind( 'mousedown', this.boundHide );
this.div.css({
'top': inputPos.top + inputHeight + 1,
'left': inputPos.left,
'width': inputWidth
}).slideDown(100);
},
hide: function() {
$(document).unbind( 'mousedown', this.boundHide );
this.div.slideUp(100);
}
});
});
+155
View File
@@ -0,0 +1,155 @@
ig.module(
'weltmeister.tile-select'
)
.defines(function(){ "use strict";
wm.TileSelect = ig.Class.extend({
pos: {x:0, y:0},
layer: null,
selectionBegin: null,
init: function( layer ) {
this.layer = layer;
},
getCurrentTile: function() {
var b = this.layer.brush;
if( b.length == 1 && b[0].length == 1 ) {
return b[0][0] - 1;
}
else {
return -1;
}
},
setPosition: function( x, y ) {
this.selectionBegin = null;
var tile = this.getCurrentTile();
this.pos.x =
Math.floor( x / this.layer.tilesize ) * this.layer.tilesize
- Math.floor( tile * this.layer.tilesize ) % this.layer.tiles.width;
this.pos.y =
Math.floor( y / this.layer.tilesize ) * this.layer.tilesize
- Math.floor( tile * this.layer.tilesize / this.layer.tiles.width ) * this.layer.tilesize
- (tile == -1 ? this.layer.tilesize : 0);
this.pos.x = this.pos.x.limit( 0, ig.system.width - this.layer.tiles.width - (ig.system.width % this.layer.tilesize) );
this.pos.y = this.pos.y.limit( 0, ig.system.height - this.layer.tiles.height - (ig.system.height % this.layer.tilesize) );
},
beginSelecting: function( x, y ) {
this.selectionBegin = {x:x, y:y};
},
endSelecting: function( x, y ) {
var r = this.getSelectionRect( x, y);
var mw = Math.floor( this.layer.tiles.width / this.layer.tilesize );
var mh = Math.floor( this.layer.tiles.height / this.layer.tilesize );
var brush = [];
for( var ty = r.y; ty < r.y+r.h; ty++ ) {
var row = [];
for( var tx = r.x; tx < r.x+r.w; tx++ ) {
if( tx < 0 || ty < 0 || tx >= mw || ty >= mh) {
row.push( 0 );
}
else {
row.push( ty * Math.floor(this.layer.tiles.width / this.layer.tilesize) + tx + 1 );
}
}
brush.push( row );
}
this.selectionBegin = null;
return brush;
},
getSelectionRect: function( x, y ) {
var sx = this.selectionBegin ? this.selectionBegin.x : x,
sy = this.selectionBegin ? this.selectionBegin.y : y;
var
txb = Math.floor( (sx - this.pos.x) / this.layer.tilesize ),
tyb = Math.floor( (sy - this.pos.y) / this.layer.tilesize ),
txe = Math.floor( (x - this.pos.x) / this.layer.tilesize ),
tye = Math.floor( (y - this.pos.y) / this.layer.tilesize );
return {
x: Math.min( txb, txe ),
y: Math.min( tyb, tye ),
w: Math.abs( txb - txe) + 1,
h: Math.abs( tyb - tye) + 1
}
},
draw: function() {
ig.system.clear( "rgba(0,0,0,0.8)" );
if( !this.layer.tiles.loaded ) {
return;
}
// Tileset
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.secondary;
ig.system.context.fillStyle = wm.config.colors.clear;
ig.system.context.fillRect(
this.pos.x * ig.system.scale,
this.pos.y * ig.system.scale,
this.layer.tiles.width * ig.system.scale,
this.layer.tiles.height * ig.system.scale
);
ig.system.context.strokeRect(
this.pos.x * ig.system.scale - 0.5,
this.pos.y * ig.system.scale - 0.5,
this.layer.tiles.width * ig.system.scale + 1,
this.layer.tiles.height * ig.system.scale + 1
);
this.layer.tiles.draw( this.pos.x, this.pos.y );
// Selected Tile
var tile = this.getCurrentTile();
var tx = Math.floor( tile * this.layer.tilesize ) % this.layer.tiles.width + this.pos.x;
var ty =
Math.floor( tile * this.layer.tilesize / this.layer.tiles.width )
* this.layer.tilesize + this.pos.y
+ (tile == -1 ? this.layer.tilesize : 0);
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.highlight;
ig.system.context.strokeRect(
tx * ig.system.scale - 0.5,
ty * ig.system.scale - 0.5,
this.layer.tilesize * ig.system.scale + 1,
this.layer.tilesize * ig.system.scale + 1
);
},
drawCursor: function( x, y ) {
var cx = Math.floor( x / this.layer.tilesize ) * this.layer.tilesize;
var cy = Math.floor( y / this.layer.tilesize ) * this.layer.tilesize;
var r = this.getSelectionRect( x, y);
ig.system.context.lineWidth = 1;
ig.system.context.strokeStyle = wm.config.colors.selection;
ig.system.context.strokeRect(
(r.x * this.layer.tilesize + this.pos.x) * ig.system.scale - 0.5,
(r.y * this.layer.tilesize + this.pos.y) * ig.system.scale - 0.5,
r.w * this.layer.tilesize * ig.system.scale + 1,
r.h * this.layer.tilesize * ig.system.scale + 1
);
}
});
});
+234
View File
@@ -0,0 +1,234 @@
ig.module(
'weltmeister.undo'
)
.requires(
'weltmeister.config'
)
.defines(function(){ "use strict";
wm.Undo = ig.Class.extend({
levels: 10,
chain: [],
rpos: 0,
currentAction: null,
init: function( levels ) {
this.levels = levels || 10;
},
clear: function() {
this.chain = [];
this.currentAction = null;
},
commit: function( action ) {
if( this.rpos ) {
this.chain.splice( this.chain.length - this.rpos, this.rpos );
this.rpos = 0;
}
action.activeLayer = ig.game.activeLayer ? ig.game.activeLayer.name : '';
this.chain.push( action );
if( this.chain.length > this.levels ) {
this.chain.shift();
}
},
undo: function() {
var action = this.chain[ this.chain.length - this.rpos - 1 ];
if( !action ) {
return;
}
this.rpos++;
ig.game.setActiveLayer( action.activeLayer );
if( action.type == wm.Undo.MAP_DRAW ) {
for( var i = 0; i < action.changes.length; i++ ) {
var change = action.changes[i];
change.layer.setTile( change.x, change.y, change.old );
}
}
else if( action.type == wm.Undo.ENTITY_EDIT ) {
action.entity.pos.x = action.old.x;
action.entity.pos.y = action.old.y;
action.entity.size.x = action.old.w;
action.entity.size.y = action.old.h;
ig.game.entities.selectEntity( action.entity );
ig.game.entities.loadEntitySettings();
}
else if( action.type == wm.Undo.ENTITY_CREATE ) {
ig.game.entities.removeEntity( action.entity );
ig.game.entities.selectEntity( null );
}
else if( action.type == wm.Undo.ENTITY_DELETE ) {
ig.game.entities.entities.push( action.entity );
if( action.entity.name ) {
this.namedEntities[action.entity.name] = action.entity;
}
ig.game.entities.selectEntity( action.entity );
}
ig.game.setModified();
},
redo: function() {
if( !this.rpos ) {
return;
}
var action = this.chain[ this.chain.length - this.rpos ];
if( !action ) {
return;
}
this.rpos--;
ig.game.setActiveLayer( action.activeLayer );
if( action.type == wm.Undo.MAP_DRAW ) {
for( var i = 0; i < action.changes.length; i++ ) {
var change = action.changes[i];
change.layer.setTile( change.x, change.y, change.current );
}
}
else if( action.type == wm.Undo.ENTITY_EDIT ) {
action.entity.pos.x = action.current.x;
action.entity.pos.y = action.current.y;
action.entity.size.x = action.current.w;
action.entity.size.y = action.current.h;
ig.game.entities.selectEntity( action.entity );
ig.game.entities.loadEntitySettings();
}
else if( action.type == wm.Undo.ENTITY_CREATE ) {
ig.game.entities.entities.push( action.entity );
if( action.entity.name ) {
this.namedEntities[action.entity.name] = action.entity;
}
ig.game.entities.selectEntity( action.entity );
}
else if( action.type == wm.Undo.ENTITY_DELETE ) {
ig.game.entities.removeEntity( action.entity );
ig.game.entities.selectEntity( null );
}
ig.game.setModified();
},
// -------------------------------------------------------------------------
// Map changes
beginMapDraw: function( layer ) {
this.currentAction = {
type: wm.Undo.MAP_DRAW,
time: Date.now(),
changes: []
};
},
pushMapDraw: function( layer, x, y, oldTile, currentTile ) {
if( !this.currentAction ) {
return;
}
this.currentAction.changes.push({
layer: layer,
x: x,
y: y,
old: oldTile,
current: currentTile
});
},
endMapDraw: function() {
if( !this.currentAction || !this.currentAction.changes.length ) {
return;
}
this.commit( this.currentAction );
this.currentAction = null;
},
// -------------------------------------------------------------------------
// Entity changes
beginEntityEdit: function( entity ) {
this.currentAction = {
type: wm.Undo.ENTITY_EDIT,
time: Date.now(),
entity: entity,
old: {
x: entity.pos.x,
y: entity.pos.y,
w: entity.size.x,
h: entity.size.y
},
current: {
x: entity.pos.x,
y: entity.pos.y,
w: entity.size.x,
h: entity.size.y
}
};
},
pushEntityEdit: function( entity ) {
if( !this.currentAction ) {
return;
}
this.currentAction.current = {
x: entity.pos.x,
y: entity.pos.y,
w: entity.size.x,
h: entity.size.y
};
},
endEntityEdit: function() {
var a = this.currentAction;
if( !a || (
a.old.x == a.current.x && a.old.y == a.current.y &&
a.old.w == a.current.w && a.old.h == a.current.h
)) {
return;
}
this.commit( this.currentAction );
this.currentAction = null;
},
commitEntityCreate: function( entity ) {
this.commit({
type: wm.Undo.ENTITY_CREATE,
time: Date.now(),
entity: entity
});
},
commitEntityDelete: function( entity ) {
this.commit({
type: wm.Undo.ENTITY_DELETE,
time: Date.now(),
entity: entity
});
}
});
wm.Undo.MAP_DRAW = 1;
wm.Undo.ENTITY_EDIT = 2;
wm.Undo.ENTITY_CREATE = 3;
wm.Undo.ENTITY_DELETE = 4;
});
+486
View File
@@ -0,0 +1,486 @@
body {
background-color: #000;
color: #fff;
font-family: sans-serif;
font-size: 10pt;
margin: 0px;
overflow: hidden;
text-shadow: 0px 1px 1px rgba(0,0,0,0.5);
-webkit-font-smoothing: antialiased;
-webkit-user-select: none;
}
h2 {
margin: 0 0 4px 0;
padding: 4px 0 4px 6px;
background-color: #000;
font-size: 100%;
color: #555;
xtext-transform: uppercase;
xborder-bottom: 1px solid #555;
}
h3 {
margin: 0;
font-size: 100%;
display: block;
}
dt {
margin: 0;
padding: 4px 0 0 6px;
display:inline;
float:left;
margin-right:5px;
}
dd {
margin: 0;
padding: 2px 0 8px 6px;
}
dl {
margin:0;
}
div.clear {
clear: both;
}
label {
cursor: pointer;
}
/* --- Input ------------------------------------------------------------------ */
input {
background-color: rgba(0,0,0,0.5);
border: 1px solid rgb(50,50,50);
color: #fff;
margin: 0;
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 10pt;
outline: none;
text-shadow: 0px 1px 1px rgba(0,0,0,0.5);
}
input:focus{
border: 1px solid rgb(200,200,200);
}
input.text {
padding: 1px;
margin: 0;
}
input.number {
width: 30px;
text-align: right;
}
input.button {
font-size: 90%;
padding-left: 13px;
padding-right: 13px;
padding-top: 5px;
padding-bottom: 5px;
color: #fff;
font-weight: bold;
background-color: rgba(255,255,255,0.1);
border:none;
border-top: 1px solid rgba(255,255,255,0.1);
border-bottom: 1px solid rgba(0,0,0,0.1);
cursor: pointer;
-webkit-transition: 0.1s linear;
}
input.button:hover {
background-color: rgba(255,255,255,0.2);
}
input.button:active {
background-color: rgba(255,255,255,0.3);
}
input.text#layerName {
width:140px;
}
input.text#layerTileset {
width:138px;
}
input#levelSaveAs { margin-right: 10px; }
input#levelLoad { margin-right: 10px; }
input#reloadImages {margin-right: 10px;}
input:disabled {
background-color: #555;
color: #888;
}
/* --- Layout ------------------------------------------------------------------ */
#editor {
margin: 0px;
position: relative;
}
#canvas {
image-rendering: optimizeSpeed;
-webkit-interpolation-mode: nearest-neighbor;
}
#menu {
width: 200px;
float: right;
position:absolute;
top:0px;
right:0px;
}
/* --- Layers ------------------------------------------------------------------ */
#layerContainer {
background-color: rgba(0,0,0,0.95);
padding-right:2px;
}
#layers {
max-height: 200px;
overflow: auto;
}
#layerButtons div.button#buttonAddLayer {
position:absolute;
right: 0px;
top:-5px;
cursor: pointer;
padding: 10px;
color:rgba(255,255,255,0.5);
font-weight: bold;
font-size:110%;
margin-left:1px;
-webkit-transition: 0.1s linear;
-webkit-font-smoothing: none;
z-index:10;
}
#layerButtons div.button#buttonAddLayer:hover { color:rgba(255,255,255,1);}
#layerButtons div.button#buttonAddLayer:active { color:rgba(255,255,255,1); text-shadow:none;}
.layer {
padding: 6px 4px;
cursor: pointer;
-webkit-transition: background-color 0.1s linear;
border-top: 1px solid rgba(255,255,255,0);
border-bottom: 1px solid rgba(255,255,255,0);
}
.layer:hover {
background-color: rgba(255,255,255,0.1);
border-top: 1px solid rgba(255,255,255,0.1);
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.layer:active {
background-color: rgba(255,255,255,0.2);
border-top: 1px solid rgba(255,255,255,0.2);
border-bottom: 1px solid rgba(255,255,255,0.2);
}
.layerActive {
background-color: rgba(255,255,255,0.1);
border-top: 1px solid rgba(255,255,255,0.2);
border-bottom: 1px solid rgba(255,255,255,0.2) !important;
}
#layerEntities { border-bottom: 1px solid #000; }
.layer .visible {
background-color: rgba(255,255,255,0.2);
text-indent: -99999px;
display: inline-block;
width: 10px;
height: 10px;
margin-right: 7px;
margin-left: 4px;
-webkit-transition: 0.1s linear;
}
.layer .visible.specialVis{
margin-right: 2px;
}
.layer .checkedVis{ background-color: rgba(255,255,255,1); }
.layer span.size { font-size: 75%; color: rgba(255,255,255,0.7); }
#layerSettings {
background-color: rgba(0,0,0,0.95);
padding-top: 5px;
margin-top: 1px;
display: none;
}
/* --- Entities ------------------------------------------------------------------ */
h3#entityClass {
border-bottom: 1px solid rgba(255,255,255,0.2);
padding: 5px;
padding-left: 10px;
}
#entitySettings {
background-color: rgba(0,0,0,0.95);
margin-top: 1px;
display: none;
}
#entityDefinitions {
max-height: 220px;
overflow: auto;
}
div.entityDefinition {
color: #aaa;
padding: 2px 0;
border-bottom: 1px solid rgba(255,255,255,0.2);
cursor: pointer;
}
div.entityDefinition:hover {
background-color: rgba(255,255,255,0.1);
}
div.entityDefinition .key {
width: 50%;
display: block;
float: left;
margin: 0 0px 0 0;
padding: 0;
text-align: right;
color: #fff;
overflow: hidden;
}
div.entityDefinition .value {
padding: 0 0 0 2px;
color: #fff;
}
dl#entityDefinitionInput {
padding: 8px 0;
}
dl#entityDefinitionInput dt {
width: 40px;
display: block;
float: left;
margin: 0 4px 0 0;
padding: 4px 0 0 0;
text-align: right;
}
dl#entityDefinitionInput dd {
display: block;
margin: 0;
padding: 2px 0;
}
#entityKey, #entityValue {
}
#entityMenu {
background-color: rgba(0,0,0,0.9);
display: none;
position: absolute;
min-width: 100px;
max-height:300px;
overflow-y: scroll;
z-index: 1000;
}
#entityMenu div {
padding: 3px;
padding-left: 8px;
color: #fff;
cursor: pointer;
border-top: 1px solid rgba(255,255,255,0);
border-bottom: 1px solid rgba(255,255,255,0);
-webkit-transition: 0.1s linear;
}
#entityMenu div:hover {
background-color: rgba(255,255,255,0.2);
border-top: 1px solid rgba(255,255,255,0.2);
border-bottom: 1px solid rgba(255,255,255,0.2);
}
/* --- Dialogs ------------------------------------------------------------------ */
.selectFileDialog {
background-color: rgba(0,0,0,0.9);
border: 1px solid white;
border-top: 1px solid rgba(255,255,255,0.4);
display: none;
position: absolute;
overflow: hidden;
-webkit-box-shadow: 0px 0px 10px rgba(0,0,0,1);
max-height: 300px;
overflow-y: scroll;
}
.selectFileDialog a {
padding: 4px;
color: #fff;
display: block;
text-decoration: none;
border-top: 1px solid rgba(255,255,255,0);
border-bottom: 1px solid rgba(255,255,255,0);
}
.selectFileDialog a:hover {
background-color: rgba(255,255,255,0.2);
border-top: 1px solid rgba(255,255,255,0.2);
border-bottom: 1px solid rgba(255,255,255,0.2);
}
div.modalDialogBackground {
background-color: rgba(0,0,0,0.7);
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: none;
z-index: 100;
}
div.modalDialogBox {
width: 300px;
margin-left: -170px;
background-color: rgba(0,0,0,0.9);
border: 1px solid rgb(100,100,100);
-webkit-box-shadow: 0px 0px 10px rgba(0,0,0,1);
position: absolute;
top: 20%;
left: 50%;
padding: 20px;
}
div.modalDialogText {
font-size: 180%;
font-weight: bold;
}
div.modalDialogButtons {
margin-top: 20px;
text-align: right;
}
div.modalDialogButtons input.button {
min-width: 100px;
text-align: center;
margin-left: 10px;
}
input.modalDialogPath {
margin-top: 20px;
width: 100%;
outline: none;
}
input.modalDialogPath:focus {
outline: none;
border: 1px solid rgb(100,100,100);
}
#headerMenu {
position:relative;
z-index:10;
height:47px;
width:100%;
background: #131314;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0,#000000), color-stop(1,#2e3033));
background: -moz-linear-gradient(center bottom, #000000 0%, #2e3033 100%);
background: -o-linear-gradient(#2e3033, #000000);
}
#headerMenu span.headerTitle {
display:inline-block;
font-weight:bold;
font-size:200%;
padding-left:20px;
padding-top:7px;
color:rgba(0,0,0,0.1);
text-shadow:0px -1px 0px rgba(255,255,255,0.4);
}
#headerMenu span.unsavedTitle {
display:inline-block;
font-weight:bold;
font-size:240%;
padding-left:0px;
color:#cc0000;
text-shadow:0px 1px 1px rgba(0,0,0,0.1);
}
#headerMenu span.headerFloat {
float: right;
}
div#zoomIndicator {
font-weight: bold;
font-size: 300%;
position: absolute;
left: 50px;
top: 30px;
color: #fff;
display: none;
}
input#toggleSidebar {
width: 200px;
height: 47px;
text-indent: -99999px;
background: url(arrow.png) 50% -37px no-repeat;
-webkit-transition: 0s linear;
opacity: 0.25;
padding: 0px;
}
input#toggleSidebar.active{
background-position: 50% 10px;
}
input[type="checkbox"] {
position: relative;
margin: 0;
border: 0;
width: 10px;
height: 10px;
display: inline-block;
-webkit-appearance: none;
-webkit-transition: 0.1s linear;
}
input[type="checkbox"] {
background-color:rgba(255,255,255,0.2);
}
input[type="checkbox"]:checked {
background-color: rgba(255,255,255,1);
}
input[type="checkbox"]:hover {
cursor: pointer;
}
input[type="checkbox"]:disabled {
background-color: rgba(255,255,255,0.1);
}
::-webkit-scrollbar { width: 2px; }
::-webkit-scrollbar-button:start:decrement,
::-webkit-scrollbar-button:end:increment { display: block; height: 2px; }
::-webkit-scrollbar-button:vertical:increment { background-color: transparent; }
::-webkit-scrollbar-track-piece { background-color: rgba(0,0,0,0); }
::-webkit-scrollbar-thumb:vertical { background-color: rgba(255,255,255,1); }
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

+235
View File
@@ -0,0 +1,235 @@
#!/usr/bin/env python
import BaseHTTPServer
import cgi
import glob
import json
import mimetypes
import os
import os.path
import urlparse
# Various config settings for the python server
SETTINGS = {
'port': 8080,
'logging': False,
'api-save': '/lib/weltmeister/api/save.php',
'api-browse': '/lib/weltmeister/api/browse.php',
'api-glob': '/lib/weltmeister/api/glob.php',
'image-types': ['.png', '.jpg', '.gif', '.jpeg'],
'mimetypes': {
'ogg': 'audio/ogg'
}
}
# Override port if we are on a Heroku server
if os.environ.get('PORT'):
SETTINGS['port'] = int(os.environ.get('PORT'))
# Get the current directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
if BASE_DIR[-1] != '/':
BASE_DIR += '/'
# Blank favicon - prevents silly 404s from occuring if no favicon is supplied
FAVICON_GIF = 'GIF89a\x01\x00\x01\x00\xf0\x00\x00\xff\xff\xff\x00\x00\x00!\xff\x0bXMP DataXMP\x02?x\x00!\xf9\x04\x05\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00@\x02\x02D\x01\x00;'
class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def send_json(self, obj, code=200, headers=None):
'Send response as JSON'
if not headers:
headers = {}
headers['Content-Type'] = 'application/json'
self.send_response(json.dumps(obj), code, headers)
def send_response(self, mesg, code=200, headers=None):
'Wraps sending a response down'
if not headers:
headers = {}
if 'Content-Type' not in headers:
headers['Content-Type'] = 'text/html'
BaseHTTPServer.BaseHTTPRequestHandler.send_response(self, code)
self.send_header('Content-Length', len(mesg))
if headers:
for k, v in headers.iteritems():
self.send_header(k, v)
self.end_headers()
self.wfile.write(mesg)
def log_request(self, *args, **kwargs):
'If logging is disabled '
if SETTINGS['logging']:
BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, *args, **kwargs)
def init_request(self):
parts = self.path.split('?', 1)
self.post_params = {}
if len(parts) == 1:
self.file_path = parts[0]
self.query_params = {}
else:
self.file_path = parts[0]
self.query_params = urlparse.parse_qs(parts[1])
def do_GET(self):
self.init_request()
self.route_request('GET')
def do_HEAD(self):
self.init_request()
self.send_response('')
def do_POST(self):
self.init_request()
# From http://stackoverflow.com/questions/4233218/python-basehttprequesthandler-post-variables
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
if ctype == 'multipart/form-data':
self.post_params = cgi.parse_multipart(self.rfile, pdict)
elif ctype == 'application/x-www-form-urlencoded':
length = int(self.headers.getheader('content-length'))
self.post_params = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)
self.route_request('POST')
def route_request(self, method='GET'):
if self.file_path == SETTINGS['api-save']:
self.save()
elif self.file_path == SETTINGS['api-browse']:
self.browse()
elif self.file_path == SETTINGS['api-glob']:
self.glob()
elif method == 'GET':
self.serve_file()
else:
self.barf()
def save(self):
resp = {'error': 0}
if 'path' in self.post_params and 'data' in self.post_params:
path = self.post_params['path'][0]
path = os.path.join(BASE_DIR, path.replace('..', ''))
data = self.post_params['data'][0]
if path.endswith('.js'):
try:
open(path, 'w').write(data)
except:
resp['error'] = 2
resp['msg'] = 'Couldn\'t write to file %d' % path
else:
resp['error'] = 3
resp['msg'] = 'File must have a .js suffix'
else:
resp['error'] = 1
resp['msg'] = 'No Data or Path specified'
return self.send_json(resp)
def browse(self):
# Get the directory to scan
dir = ''
if 'dir' in self.query_params:
dir = self.query_params['dir'][0].replace('..', '')
if dir[-1] != '/':
dir += '/'
# Get the dir and files
dirs = [os.path.join(dir, d) for d in os.listdir(os.path.join(BASE_DIR, dir))
if os.path.isdir(os.path.join(dir, d))]
files = glob.glob(dir + '*.*')
# Filter on file types
if 'type' in self.query_params:
types = self.query_params['type']
if 'images' in types:
files = [f for f in files if os.path.splitext(f)[1] in SETTINGS['image-types']]
elif 'scripts' in types:
files = [f for f in files if os.path.splitext(f)[1] == '.js']
if os.name == 'nt':
files = [f.replace('\\', '/') for f in files]
dirs = [d.replace('\\', '/') for d in dirs]
response = {
'files': files,
'dirs': dirs,
'parent': False if dir == './' else os.path.dirname(os.path.dirname(dir))
}
return self.send_json(response)
def glob(self):
globs = self.query_params['glob[]']
files = []
for g in globs:
g = g.replace('..', '')
more = glob.glob(g)
files.extend(more)
if os.name == 'nt':
files = [f.replace('\\', '/') for f in files]
return self.send_json(files)
def guess_type(self, path):
type, _ = mimetypes.guess_type(path)
if not type:
ext = path.split('.')[-1]
if ext in SETTINGS['mimetypes'].keys():
type = SETTINGS['mimetypes'][ext]
# Winblows hack
if os.name == "nt" and type.startswith("image"):
type = type.replace("x-", "")
return type
def serve_file(self):
path = self.file_path
if path == '/':
path = 'index.html'
elif path == '/editor':
path = 'weltmeister.html'
# Remove the leading forward slash
if path[0] == '/':
path = path[1:]
# Security, remove the ..
path = path.replace('..', '')
# Determine the fullpath
path = os.path.join(BASE_DIR, path)
try:
data = open(path, 'rb').read()
type = self.guess_type(path)
self.send_response(data, 200, headers={'Content-Type': type})
except:
if '/favicon.ico' in path:
self.send_response(FAVICON_GIF, 200, headers={'Content-Type': 'image/gif'})
else:
self.send_response('', 404)
def barf(self):
self.send_response('barf', 405)
def main():
addr = ('', SETTINGS['port'])
server = BaseHTTPServer.HTTPServer(addr, HTTPHandler)
print 'Running ImpactJS Server\nGame: http://localhost:%d\nEditor: http://localhost:%d/editor' % (addr[1], addr[1])
server.serve_forever()
if __name__ == '__main__':
main()
+23
View File
@@ -0,0 +1,23 @@
@echo off
:: Path to impact.js and your game's main .js
SET IMPACT_LIBRARY=lib/impact/impact.js
SET GAME=lib/game/main.js
:: Output file
SET OUTPUT_FILE=game.min.js
:: Change CWD to Impact's base dir
cd ../
:: Bake!
php tools/bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
:: If you dont have the php.exe in your PATH uncomment the
:: following line and point it to your php.exe
::c:/php/php.exe tools/bake.php %IMPACT_LIBRARY% %GAME% %OUTPUT_FILE%
pause
+157
View File
@@ -0,0 +1,157 @@
<?php
if( count($argv) < 3 ) {
echo "Usage: bake.php <in...> <out>\n";
echo "e.g. bake.php lib/impact/impact.js lib/game/game.js mygame-baked.js\n";
die;
}
$inFiles = array_slice( $argv, 1, -1 );
$outFile = $argv[ count($argv)-1 ];
$baker = new Baker( Baker::MINIFIED );
$baker->bake( $inFiles, $outFile );
class Baker {
const PLAIN = 0;
const MINIFIED = 1;
const GZIPPED = 2;
protected $base = 'lib/';
protected $format = 0;
protected $loaded = array();
protected $currentInput = 'Command Line';
protected $fileCount = 0, $bytesIn = 0, $bytesOut = 0;
public function __construct( $format = 0 ) {
$this->format = $format;
if( $this->format & self::MINIFIED ) {
require_once( 'jsmin.php' );
}
}
public function bake( $inFiles, $outFile ) {
$this->fileCount = 0;
$this->bytesIn = 0;
$out = "/*! Built with IMPACT - impactjs.com */\n\n";
foreach( $inFiles as $f ) {
$out .= $this->load( $f );
}
$bytesOut = strlen($out);
$bytesOutZipped = 0;
echo "writing $outFile\n";
@file_put_contents( $outFile, $out ) or
die("ERROR: Couldn't write to $outFile\n");
if( $this->format & self::GZIPPED ) {
$gzFile = "$outFile.gz";
echo "writing $gzFile\n";
$fh = gzopen( $gzFile, 'w9' ) or
die("ERROR: Couldn't write to $gzFile\n");
gzwrite( $fh, $out );
gzclose( $fh );
$bytesOutZipped = filesize( $gzFile );
}
echo
"\nbaked {$this->fileCount} files: ".
round($this->bytesIn/1024,1)."kb -> ".round($bytesOut/1024,1)."kb" .
( $this->format & self::GZIPPED
? " (".round($bytesOutZipped/1024,1)."kb gzipped)\n"
: "\n"
);
}
protected function load( $path ) {
if( isset($this->loaded[$path]) ) {
return '';
}
if( !file_exists($path) ) {
die("ERROR: Couldn't load $path required from {$this->currentInput}\n");
}
echo "loading $path \n";
$this->loaded[$path] = true;
$this->currentInput = $path;
$code = file_get_contents( $path );
$this->bytesIn += strlen($code);
$this->fileCount++;
if( $this->format & self::MINIFIED ) {
$code = trim(JSMin::minify($code));
}
// Naively probe the file for 'ig.module().requires().defines()' code;
// the 'requries()' part will be handled by the regexp callback
$this->definesModule = false;
$code = preg_replace_callback(
'/ig\s*
\.\s*module\s*\((.*?)\)\s*
(\.\s*requires\s*\((.*?)\)\s*)?
\.\s*defines\s*\(
/smx',
array($this,'loadCallback'),
$code
);
// All files should define a module; maybe we just missed it? Print a
// friendly reminder :)
if( !$this->definesModule ) {
echo "WARNING: file $path seems to define no module!\n";
}
return $code;
}
protected function loadCallback( $matches ) {
$currentInput = $this->currentInput;
$this->definesModule = true;
$moduleName = $matches[1];
$requiredFiles = isset($matches[3]) ? $matches[3] : '';
$requiredCode = '';
if( $requiredFiles ) {
// Explode the module names and map them to file names. Ignore the
// dom.ready module if present
$moduleFiles = array_diff(
explode(
',',
preg_replace(
'/[\s\'"]|\/\/.*|\/\*.*\*\//', // strip quotes and spaces
'',
str_replace('.', '/', $requiredFiles ) // . to /
)
),
array('dom/ready')
);
foreach( $moduleFiles as $f ) {
$requiredCode .= $this->load( $this->base . $f.'.js' );
}
}
return
$requiredCode .
"\n\n// $currentInput\n" .
'ig.baked=true;' .
'ig.module('.$moduleName.')' .
( $requiredFiles
? '.requires('.$requiredFiles.')'
: ''
) .
'.defines(';
}
}
?>
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# Path to impact.js and your game's main .js
IMPACT_LIBRARY=lib/impact/impact.js
GAME=lib/game/main.js
# Output file
OUTPUT_FILE=game.min.js
# Change CWD to Impact's base dir and bake!
cd ..
php tools/bake.php $IMPACT_LIBRARY $GAME $OUTPUT_FILE
+291
View File
@@ -0,0 +1,291 @@
<?php
/**
* jsmin.php - PHP implementation of Douglas Crockford's JSMin.
*
* This is pretty much a direct port of jsmin.c to PHP with just a few
* PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and
* outputs to stdout, this library accepts a string as input and returns another
* string as output.
*
* PHP 5 or higher is required.
*
* Permission is hereby granted to use this version of the library under the
* same terms as jsmin.c, which has the following license:
*
* --
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
*
* 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 shall be used for Good, not Evil.
*
* 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.
* --
*
* @package JSMin
* @author Ryan Grove <ryan@wonko.com>
* @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
* @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
* @license http://opensource.org/licenses/mit-license.php MIT License
* @version 1.1.1 (2008-03-02)
* @link http://code.google.com/p/jsmin-php/
*/
class JSMin {
const ORD_LF = 10;
const ORD_SPACE = 32;
protected $a = '';
protected $b = '';
protected $input = '';
protected $inputIndex = 0;
protected $inputLength = 0;
protected $lookAhead = null;
protected $output = '';
// -- Public Static Methods --------------------------------------------------
public static function minify($js) {
$jsmin = new JSMin($js);
return $jsmin->min();
}
// -- Public Instance Methods ------------------------------------------------
public function __construct($input) {
$this->input = str_replace("\r\n", "\n", $input);
$this->inputLength = strlen($this->input);
}
// -- Protected Instance Methods ---------------------------------------------
protected function action($d) {
switch($d) {
case 1:
$this->output .= $this->a;
case 2:
$this->a = $this->b;
if ($this->a === "'" || $this->a === '"') {
for (;;) {
$this->output .= $this->a;
$this->a = $this->get();
if ($this->a === $this->b) {
break;
}
if (ord($this->a) <= self::ORD_LF) {
throw new JSMinException('Unterminated string literal.');
}
if ($this->a === '\\') {
$this->output .= $this->a;
$this->a = $this->get();
}
}
}
case 3:
$this->b = $this->next();
if ($this->b === '/' && (
$this->a === '(' || $this->a === ',' || $this->a === '=' ||
$this->a === ':' || $this->a === '[' || $this->a === '!' ||
$this->a === '&' || $this->a === '|' || $this->a === '?')) {
$this->output .= $this->a . $this->b;
for (;;) {
$this->a = $this->get();
if ($this->a === '/') {
break;
} elseif ($this->a === '\\') {
$this->output .= $this->a;
$this->a = $this->get();
} elseif (ord($this->a) <= self::ORD_LF) {
throw new JSMinException('Unterminated regular expression '.
'literal.');
}
$this->output .= $this->a;
}
$this->b = $this->next();
}
}
}
protected function get() {
$c = $this->lookAhead;
$this->lookAhead = null;
if ($c === null) {
if ($this->inputIndex < $this->inputLength) {
$c = $this->input[$this->inputIndex];
$this->inputIndex += 1;
} else {
$c = null;
}
}
if ($c === "\r") {
return "\n";
}
if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {
return $c;
}
return ' ';
}
protected function isAlphaNum($c) {
return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
}
protected function min() {
$this->a = "\n";
$this->action(3);
while ($this->a !== null) {
switch ($this->a) {
case ' ':
if ($this->isAlphaNum($this->b)) {
$this->action(1);
} else {
$this->action(2);
}
break;
case "\n":
switch ($this->b) {
case '{':
case '[':
case '(':
case '+':
case '-':
$this->action(1);
break;
case ' ':
$this->action(3);
break;
default:
if ($this->isAlphaNum($this->b)) {
$this->action(1);
}
else {
$this->action(2);
}
}
break;
default:
switch ($this->b) {
case ' ':
if ($this->isAlphaNum($this->a)) {
$this->action(1);
break;
}
$this->action(3);
break;
case "\n":
switch ($this->a) {
case '}':
case ']':
case ')':
case '+':
case '-':
case '"':
case "'":
$this->action(1);
break;
default:
if ($this->isAlphaNum($this->a)) {
$this->action(1);
}
else {
$this->action(3);
}
}
break;
default:
$this->action(1);
break;
}
}
}
return $this->output;
}
protected function next() {
$c = $this->get();
if ($c === '/') {
switch($this->peek()) {
case '/':
for (;;) {
$c = $this->get();
if (ord($c) <= self::ORD_LF) {
return $c;
}
}
case '*':
$this->get();
for (;;) {
switch($this->get()) {
case '*':
if ($this->peek() === '/') {
$this->get();
return ' ';
}
break;
case null:
throw new JSMinException('Unterminated comment.');
}
}
default:
return $c;
}
}
return $c;
}
protected function peek() {
$this->lookAhead = $this->get();
return $this->lookAhead;
}
}
// -- Exceptions ---------------------------------------------------------------
class JSMinException extends Exception {}
?>
+98
View File
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Weltmeister</title>
<link rel="stylesheet" type="text/css" href="lib/weltmeister/weltmeister.css"/>
<script src="lib/weltmeister/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="lib/weltmeister/jquery-ui-1.8.1.custom.min.js" type="text/javascript" charset="utf-8"></script>
<script src="lib/impact/impact.js" type="text/javascript" charset="utf-8"></script>
<script src="lib/weltmeister/weltmeister.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="headerMenu">
<span class="headerTitle"></span>
<span class="unsavedTitle"></span>
<span class="headerFloat">
<input type="button" id="levelSave" value="Save" class="button"/>
<input type="button" id="levelSaveAs" value="Save As" class="button"/>
<input type="button" id="levelNew" value="New" class="button"/>
<input type="button" id="levelLoad" value="Load" class="button"/>
<input type="button" id="reloadImages" value="Reload Images" title="Reload Images" class="button"/>
<input type="button" id="toggleSidebar" value="Toggle Sidebar" title="Toggle Sidebar" class="button"/>
</span>
</div>
<div id="editor">
<div id="entityMenu"></div>
<canvas id="canvas"></canvas>
<div id="menu">
<div id="layerContainer">
<h2>Layers</h2>
<div id="layerButtons">
<div class="button" id="buttonAddLayer" title="Add Layer">+</div>
</div>
<div id="layers">
<div id="layerEntities" class="layer">
<span class="visible specialVis checkedVis" title="Toggle Visibility (Shift+0)"></span>
<span class="name">entities</span>
</div>
</div>
</div>
<div id="layerSettings">
<h2>Layer Settings</h2>
<dl>
<dt>Name:</dt><dd><input type="text" class="text" id="layerName"/></dd>
<dt>Tileset:</dt><dd><input type="text" class="text" id="layerTileset"/></dd>
<dt>Tilesize:</dt><dd><input type="text" class="number" id="layerTilesize"/></dd>
<dt>Dimensions:</dt>
<dd>
<input type="text" class="number" id="layerWidth"/> &times; <input type="text" class="number" id="layerHeight"/>
</dd>
<dt>Distance:</dt><dd><input type="text" class="number" id="layerDistance"/></dd>
<dd>
<input type="checkbox" id="layerIsCollision"/>
<label for="layerIsCollision">Is Collision Layer</label>
</dd>
<dd>
<input type="checkbox" id="layerPreRender"/>
<label for="layerPreRender">Pre-Render in Game</label>
</dd>
<dd>
<input type="checkbox" id="layerRepeat"/>
<label for="layerRepeat">Repeat</label>
</dd>
<dd>
<input type="checkbox" id="layerLinkWithCollision"/>
<label for="layerLinkWithCollision">Link with Collision</label>
</dd>
<dd>
<input type="button" id="buttonSaveLayerSettings" value="Apply Changes" class="button"/>
<input type="button" id="buttonRemoveLayer" value="Delete" class="button"/>
</dd>
</dl>
</div>
<div id="entitySettings">
<h2>Entity Settings</h2>
<h3 id="entityClass">EntityClassName</h3>
<div id="entityDefinitions">
<div class="entityDefinition"><span class="key">x</span>:<span class="value">188</span></div>
<div class="entityDefinition"><span class="key">y</span>:<span class="value">269</span></div>
</div>
<dl id="entityDefinitionInput">
<dt>Key:</dt><dd><input type="text" class="text" id="entityKey"/></dd>
<dt>Value:</dt><dd><input type="text" class="text" id="entityValue"/></dd>
</dl>
</div>
</div>
<div id="zoomIndicator">1x</div>
</div>
</body>
</html>