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
+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