Permalink
Browse files

css animations support

  • Loading branch information...
1 parent cb76643 commit efcdd6dbc3e2e99f89875464439ba38cc62d4f1b @michalbe committed May 22, 2011
Showing with 895 additions and 779 deletions.
  1. BIN .DS_Store
  2. +8 −3 README.md
  3. BIN example/.DS_Store
  4. BIN example/img/.DS_Store
  5. +133 −129 example/index-minifiedLib.html
  6. +5 −1 example/index.html
  7. +1 −1 mibbu-min.js
  8. +748 −645 mibbu.js
View
BIN .DS_Store
Binary file not shown.
View
11 README.md
@@ -3,21 +3,26 @@ Mibbu
#### First Javascript Game MicroFramework ####
-Mibbu gives you everything you need for fast prototyping your Javascript game in just 4.35KB of code. Games created with Mibbu can be displayed using Canvas or DOM mode (you can change it with one single function, or use feature detection to use DOM where it is n canvas, like in IE family).
-
+Mibbu gives you everything you need for fast prototyping your Javascript game in less than 2.5KB of gzipped code. Games created with Mibbu can be displayed using Canvas or DOM mode (you can change it with one single function, or use feature detection to use DOM where it is no canvas, like in IE family). Since **v0.2/suiko** Mibbu supports also CSS animations in Webkit.
[Documentation](http://mibbu.eu)
### Features of Mibbu ###
* Rendering game using both - Canvas or DOM
-* Animation of the sprites
+* Animation of the sprites (using Canvas, DOM or CSS Aniation in Webkit)
* Collisions detection with collision zones
* Simple background manager
* Callbacks after given number of frames
* Check [example](https://github.com/michalbe/mibbu/tree/master/example) for more
### Change Log ###
+2011 05 23 - **v0.2/suiko** (5.54 KB, gzip 2.12 KB)
+
+* CSS3 Animations support in Webkit browsers (tested on Chrome 11 & Safari 5.03)
+* .cssAnimationOff() function added (works the same as .canvasOff() but for CSS Animations)
+* some major & minor bug fixes
+
2011 05 19 - **v0.1.2/guanabhadra** (4.36 KB, gzip: 1.81 KB)
* Changes in Array#indexOf implementation - we don't need full spec implementation here.
View
BIN example/.DS_Store
Binary file not shown.
View
BIN example/img/.DS_Store
Binary file not shown.
View
262 example/index-minifiedLib.html
@@ -1,129 +1,133 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Mibbu test</title>
-
- </head>
- <body style="margin:0">
-
-
- <script src="../mibbu-min.js"></script>
-
- <script>
- //create new game with 500x500 canvas size
- var Game = new mibbu(500, 500);
-
- //uncomment line below for disabling
- //canvas and swiching to DOM rendering
- Game.canvasOff();
-
- //show FPS counter
- Game.fps();
-
- //now init all the elements - before calling
- //init funciton Mibbu didn't know if you want
- //to render it on canvas or using DOM
- Game.init();
-
- //create two sprites using reptile.png image, with
- //width & height of single frame equals to 200,
- //reptile.png has 8 frames ('7' if we count from '0') and
- //only 1 ('0') animation inside
- var sprite = new Game.spr('img/reptile.png', 200, 200, 7, 0),
- sprite2 = new Game.spr('img/reptile.png', 200, 200, 7, 0),
- //create new background using bg.jpg file and set it's speed
- //to 6, direction to SOUTH, and initial position to (0,0)
- background = new Game.bg('img/bg.jpg', 6, "S", {x:0,y:0});
-
- //set position of 1st sprite to (100, 100) and
- //it's x-index to 2
- sprite.position(100, 100, 2);
-
- //set speed of redrwing the sprite frames
- sprite.speed(4);
-
- //extend sprite object with some additional
- //variables fr control movement etc.
- //it is up to you how you will achieve this -
- //- it is not part of Mibbu
- sprite.y = 100;
- sprite.d = 1;
- sprite.type = 0;
-
- //the same here
- //but we create variable for the speed of the animation
- //we will use it later
- var speed = sprite2.speed(4);
-
- sprite2.position(100, 300, 2);
- sprite2.y = 300;
- sprite2.d = -1;
-
- //resize second sprite and remember
- //it's size in the file (functions like
- //size(), frames(), etc. always return
- //their values, even if you call them
- //without parameters, like sprite2.size();
- var size = sprite2.size(100, 100);
-
- //start moving background
- background.on();
-
- //start main game loop
- Game.on();
-
- //now we will create additional function
- //to be called on each frame of main game loop
- var additionalLoop = function(){
- if (sprite.y < 0) sprite.d*=-1;
-
- if (sprite2.y > 500-size.height) sprite2.d*=-1;
-
- sprite.y+=sprite.d*4;
- sprite2.y+=sprite2.d*2;
-
- //we move the sprites by changing it's
- //positions
- sprite.position(100, sprite.y);
- sprite2.position(100, sprite2.y);
-
- }
-
- //now add that function to the loop
- Game.hook(additionalLoop);
-
- //lets check for the collisions
- Game.hitsOn();
-
- //if 'sprite' will collide with 'sprite2' then:
- sprite.hit(sprite2, function(){
- //change it's type
- if (sprite.type === 0) {
- sprite.type = 1;
- sprite.change('img/reptile.png', 200, 200, 7, 0);
-
- } else {
- sprite.type = 0;
- sprite.change('img/reptile2.png', 200, 200, 7, 0);
- }
- //resize it
- sprite.size(150, 150);
-
- //and change direction of it's movement
- //also - it is not the part of Mibbu
- sprite.d*=-1;
- sprite2.d*=-1;
- });
-
- //create callback for the second sprite
- //it will change the speed of animation
- //after every second full animation
- //hope I explained it clearly:)
- sprite2.callback(function(){
- speed++;
- sprite2.speed(speed);
- }, 2);
- </script>
- </body>
-</html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Mibbu test</title>
+
+ </head>
+ <body style="margin:0">
+
+
+ <script src="../mibbu-min.js"></script>
+
+ <script>
+ //create new game with 500x500 canvas size
+ var Game = new mibbu(500, 500);
+
+ //uncomment line below for disabling
+ //canvas and swiching to DOM rendering
+ Game.canvasOff();
+
+ //comment line below (only in DOM mode) to enable CSS3 Animations
+ //(only in webkit browsers)
+ //Game.cssAnimationOff();
+
+ //show FPS counter
+ Game.fps();
+
+ //now init all the elements - before calling
+ //init funciton Mibbu didn't know if you want
+ //to render it on canvas or using DOM
+ Game.init();
+
+ //create two sprites using reptile.png image, with
+ //width & height of single frame equals to 200,
+ //reptile.png has 8 frames ('7' if we count from '0') and
+ //only 1 ('0') animation inside
+ var sprite = new Game.spr('img/reptile.png', 200, 200, 7, 0),
+ sprite2 = new Game.spr('img/reptile.png', 200, 200, 7, 0),
+ //create new background using bg.jpg file and set it's speed
+ //to 6, direction to SOUTH, and initial position to (0,0)
+ background = new Game.bg('img/bg.jpg', 6, "S", {x:0,y:0});
+
+ //set position of 1st sprite to (100, 100) and
+ //it's x-index to 2
+ sprite.position(100, 100, 2);
+
+ //set speed of redrwing the sprite frames
+ sprite.speed(4);
+
+ //extend sprite object with some additional
+ //variables fr control movement etc.
+ //it is up to you how you will achieve this -
+ //- it is not part of Mibbu
+ sprite.y = 100;
+ sprite.d = 1;
+ sprite.type = 0;
+
+ //the same here
+ //but we create variable for the speed of the animation
+ //we will use it later
+ var speed = sprite2.speed(4);
+
+ sprite2.position(100, 300, 2);
+ sprite2.y = 300;
+ sprite2.d = -1;
+
+ //resize second sprite and remember
+ //it's size in the file (functions like
+ //size(), frames(), etc. always return
+ //their values, even if you call them
+ //without parameters, like sprite2.size();
+ var size = sprite2.size(100, 100);
+
+ //start moving background
+ background.on();
+
+ //start main game loop
+ Game.on();
+
+ //now we will create additional function
+ //to be called on each frame of main game loop
+ var additionalLoop = function(){
+ if (sprite.y < 0) sprite.d*=-1;
+
+ if (sprite2.y > 500-size.height) sprite2.d*=-1;
+
+ sprite.y+=sprite.d*4;
+ sprite2.y+=sprite2.d*2;
+
+ //we move the sprites by changing it's
+ //positions
+ sprite.position(100, sprite.y);
+ sprite2.position(100, sprite2.y);
+
+ }
+
+ //now add that function to the loop
+ Game.hook(additionalLoop);
+
+ //lets check for the collisions
+ Game.hitsOn();
+
+ //if 'sprite' will collide with 'sprite2' then:
+ sprite.hit(sprite2, function(){
+ //change it's type
+ if (sprite.type === 0) {
+ sprite.type = 1;
+ sprite.change('img/reptile.png', 200, 200, 7, 0);
+
+ } else {
+ sprite.type = 0;
+ sprite.change('img/reptile2.png', 200, 200, 7, 0);
+ }
+ //resize it
+ sprite.size(150, 150);
+
+ //and change direction of it's movement
+ //also - it is not the part of Mibbu
+ sprite.d*=-1;
+ sprite2.d*=-1;
+ });
+
+ //create callback for the second sprite
+ //it will change the speed of animation
+ //after every second full animation
+ //hope I explained it clearly:)
+ sprite2.callback(function(){
+ speed++;
+ sprite2.speed(speed);
+ }, 2);
+ </script>
+ </body>
+</html>
View
6 example/index.html
@@ -17,7 +17,11 @@
//uncomment line below for disabling
//canvas and swiching to DOM rendering
Game.canvasOff();
-
+
+ //comment line below (only in DOM mode) to enable CSS3 Animations
+ //(only in webkit browsers)
+ //Game.cssAnimationOff();
+
//show FPS counter
Game.fps();
View
2 mibbu-min.js
@@ -1 +1 @@
-var n=void 0,mibbu=function(H,I,x){function o(){for(var b=i.length,r,d,e,c,h,a,g,y,z;b--;)for(r in d=i[b],c=d.c+d.d.t,h=d.c+d.height-d.d.n,a=d.b+d.d.q,d=d.b+d.width-d.d.s,i[b].o)if(e=A[r],g=e.c+e.d.t,y=e.c+e.height-e.d.n,z=e.b+e.d.q,e=e.b+e.width-e.d.s,!(c>y||h<g||a>e||d<z))i[b].o[r]()}function B(){C();for(var b=l.length;b--;)l[b].F();for(b=f.length;b--;)f[b]();if(p){b=new Date;~~(b.getTime()-s.getTime())>=1E3&&(D=t,t=0,s=b);b="FPS: "+D;if(h)j.fillText(b,4,15);else if(q)q.innerHTML=b;t++}u&&(E=F(B,c))}function J(){c=k.createElement("canvas");G();j=c.getContext("2d");j.p=j.drawImage;l.sort(function(b,c){return b.g-c.g})}function G(){C=h?function(){j.clearRect(0,0,v,w)}:function(){};p&&(s=new Date);F=function(){return window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(b){setTimeout(b,1E3/60)}}();m=c.style;c.width=v;c.height=w;m.width=v+"px";m.height=w+"px";m.position="absolute";m.overflow="hidden";K.appendChild(c)}var h=!0,k=window.document,l=[],K=x?k.getElementById(x):k.body,c,j,v=H||400,w=I||300,f=[],E,C,s=new Date,p=!1,q,i=[],A=[],F,m;Array.prototype.indexOf=Array.prototype.indexOf||function(b){for(var c=this.length;c--&&this[c]!==b;);return c};var t=0,D=0,u=!0;k.createElement("canvas").getContext||(h=!1);return{fps:function(){p=!0},init:function(){h?J():(c=k.createElement("div"),G(),p&&(q=k.createElement("div"),c.appendChild(q)))},on:function(){u=!0;B()},off:function(){clearTimeout(E);u=!1},canvas:function(){return c},ctx:function(){return j},canvasOff:function(){h=!1},hitsOn:function(){f.indexOf(o)===-1&&f.push(o)},hitsOff:function(){f.indexOf(o)!==-1&&f.splice(f.indexOf(o),1)},spr:function(b,f,d,e,m){var o=h?function(){try{j.p(a.a,a.C*a.m,a.B*a.j,a.C,a.B,a.b,a.c,a.width,a.height)}catch(g){}}:function(){a.a.style.top=a.height*a.j*-1+"px";a.a.style.left=a.width*a.m*-1+"px"},a={};a.id=l.length;a.a=new Image;a.a.src=b;a.f=1;a.width=f;a.C=f;a.height=d;a.B=d;a.k=e;a.u=m;a.G=!1;a.o={};a.j=0;a.m=0;a.f=1;a.l=0;a.b=0;a.c=0;a.g=1;a.w=null;a.v=0;a.D=0;a.d={t:0,q:0,n:0,s:0};if(!h)a.A=k.createElement("div"),a.e=a.A.style,a.e.overflow="hidden",a.e.width=f+"px",a.e.height=d+"px",a.e.position="absolute",a.e.zIndex=a.g,a.a.style.position="absolute",a.A.appendChild(a.a),c.appendChild(a.A);a.id=l.push(a)-1;A.push(a);a.F=function(){if(a.k>0){if(a.l==a.f&&a.f!==0){if(a.j==a.k){if(a.j=0,typeof a.w==="function"&&(a.v++,a.v===a.D))a.w(),a.v=0}else a.j++;a.l=0}a.f!==0&&a.l++;o()}};return{position:function(g,b,c){a.b=g||a.b;a.c=b||a.c;a.g=c||a.g;h?c&&l.sort(function(a,g){return g.g-a.g}):(a.e.left=g+"px",a.e.top=b+"px",a.e.zIndex=c||a.g);return{x:a.b,y:a.c,H:a.g}},hit:function(g,b){i.indexOf(a)===-1&&i.push(a);a.o[g.id()]=b;i.indexOf(a)===-1&&i.push(a)},zone:function(g,b,c,d){if(g!==n)a.d.q=d,a.d.t=g,a.d.s=b,a.d.n=c;return a.d},noHits:function(){a.o={}},callback:function(g,b){a.w=g;a.D=b},change:function(b,c,d,e,f){a.a.src=b;a.width=c;a.height=d;a.C=c;a.B=d;a.k=e;a.u=f;a.l=0;a.j=0;if(!h)a.a.style.width=c*(a.u+1)+"px",a.a.style.height=d*(a.k+1)+"px",a.e.width=c+"px",a.e.height=d+"px";a.d={t:0,q:0,n:0,s:0}},size:function(b,c){if(b!==n){if(!h)a.e.width=b+"px",a.e.height=c+"px",a.a.style.width=b*(a.u+1)+"px",a.a.style.height=c*(a.k+1)+"px";a.width=b;a.height=c}return{width:a.width,height:a.height}},speed:function(b){if(b!==n)a.f=b,a.l=0;return a.f},animation:function(b){if(b!==n)a.m=b;return a.m},frame:function(b){if(b!==n)a.j=b;return a.j},id:function(){return a.id}}},bg:function(b,f,d,e){function i(b){switch(b){case "N":a.h=0;a.i=-1;break;case "W":a.h=-1;a.i=0;break;case "S":a.h=0;a.i=1;break;case "E":a.h=1;a.i=0;break;default:a.h=0,a.i=0}}var k=h?function(){try{j.p(a.a,a.b,a.c),j.p(a.a,a.b+a.a.width*a.h,a.c+a.a.height*a.i),j.p(a.a,a.b-a.a.width*a.h,a.c-a.a.height*a.i)}catch(b){}if(a.h===-1){if(a.b<a.a.width*-1)a.b=0}else if(a.h===1){if(a.b>a.a.width)a.b=0}else if(a.i===-1){if(a.c<a.a.height*-1)a.c=0}else if(a.i===1&&a.c>a.a.height)a.c=0}:function(){c.style.backgroundPosition=a.b+"px "+a.c+"px"},a=this;h?(a.a=new Image,a.a.src=b):c.style.backgroundImage="url("+b+")";a.f=f||3;i(d);a.g=e.z||0;a.b=e.x||0;a.c=e.y||0;a.id=l.push(a);a.r=0;a.F=function(){a.b+=a.f*a.h*a.r;a.c+=a.f*a.i*a.r;k()};return{on:function(){a.r=1},off:function(){a.r=0},dir:function(b){a.b=a.c=0;i(b)},speed:function(b){if(b!==n)a.f=b;return a.f},position:function(b,c){a.b=b||a.b;a.c=c||a.c;return{x:a.b,y:a.c}}}},hook:function(b){f.push(b)},unhook:function(b){f.indexOf(b)!==-1&&f.splice(f.indexOf(b),1)}}};
+var o=void 0,mibbu=function(I,J,y){function p(){for(var c=m.length,d,e,f,h,i,b,a,z,A;c--;)for(d in e=m[c],h=e.c+e.d.w,i=e.c+e.height-e.d.o,b=e.b+e.d.t,e=e.b+e.width-e.d.v,m[c].r)if(f=B[d],a=f.c+f.d.w,z=f.c+f.height-f.d.o,A=f.b+f.d.t,f=f.b+f.width-f.d.v,!(h>z||i<a||b>f||e<A))m[c].r[d]()}function C(){D();for(var c=d.length;c--;)d[c].F();for(c=g.length;c--;)g[c]();if(r){c=new Date;~~(c.getTime()-t.getTime())>=1E3&&(E=u,u=0,t=c);c="FPS: "+E;if(i)l.fillText(c,4,15);else if(s)s.innerHTML=c;u++}v&&(F=G(C,h))}function K(){h=k.createElement("canvas");l=h.getContext("2d");l.s=l.drawImage;d.sort(function(c,d){return c.h-d.h})}function L(){D=i?function(){l.clearRect(0,0,w,x)}:function(){};r&&(t=new Date);G=function(){return window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(c){setTimeout(c,1E3/60)}}();n=h.style;h.width=w;h.height=x;n.width=w+"px";n.height=x+"px";n.position="absolute";n.overflow="hidden";H.appendChild(h)}var i=!0,j=!1,k=document,d=[],H=y?k.getElementById(y):k.body,h,l,w=I||400,x=J||300,g=[],F,D,t=new Date,r=!1,s,m=[],B=[],G,n;Array.prototype.indexOf=Array.prototype.indexOf||function(c){for(var d=this.length;d--&&this[d]!==c;);return d};var u=0,E=0,v=!0;k.createElement("canvas").getContext||(i=!1);return{fps:function(){r=!0},init:function(){i?K():(h=k.createElement("div"),r&&(s=k.createElement("div"),h.appendChild(s)));L()},on:function(){v=!0;C();if(j)for(var c=d.length;c--;)if(d[c].a)d[c].a.style.webkitAnimationDuration=~~(1/(60/d[c].e)*100)/100*(d[c].g+1)+"s"},off:function(){clearTimeout(F);v=!1;if(j)for(var c=d.length;c--;)if(d[c].a)d[c].a.style.webkitAnimationDuration=0},canvas:function(){return h},ctx:function(){return l},canvasOff:function(){i=!1;typeof H.style.webkitAnimation!=="undefined"&&(j=!0)},cssAnimationOff:function(){j=!1},hitsOn:function(){g.indexOf(p)===-1&&g.push(p)},hitsOff:function(){g.indexOf(p)!==-1&&g.splice(g.indexOf(p),1)},spr:function(c,g,e,f,n){function q(){for(var b="@-webkit-keyframes 'sprite"+a.id+"' {\n",c=100/(a.g+1),s="% { -webkit-transform: translate3d(", d=0;d<a.g+1;d++)b+=~~(c*d*100)/100+s+a.i*a.width*-1+"px,"+d*a.height*-1+"px, 0); }\n",b+=~~((c*(d+1)-0.01)*100)/100+s+a.i*a.width*-1+"px,"+d*a.height*-1+"px, 0); }\n";return b+("100"+s+a.i*a.width+"px, 0px, 0); }\n}")}var b=i?function(){try{l.s(a.a,a.D*a.i,a.C*a.l,a.D,a.C,a.b,a.c,a.width,a.height)}catch(b){}}:j?function(){}:function(){a.a.style.top=a.height*a.l*-1+"px";a.a.style.left=a.width*a.i*-1+"px"},a={};a.id=d.length;a.a=new Image;a.a.src=c;a.e=1;a.width=g;a.D=g;a.height=e;a.C=e;a.g=f;a.G=n;a.H=!1;a.r={};a.l=0;a.i=0;a.e=1;a.n=0;a.b=0;a.c=0;a.h=1;a.q=null;a.p=0;a.A=0;a.d={w:0,t:0,o:0,v:0};if(!i){a.B=k.createElement("div");a.f=a.B.style;a.f.overflow="hidden";a.f.width=g+"px";a.f.height=e+"px";a.f.position="absolute";a.f.zIndex=a.h;a.a.style.position="absolute";if(j)a.m=k.createElement("style"),a.m.innerHTML=q(),k.getElementsByTagName("head")[0].appendChild(a.m),a.a.style.webkitAnimation="'sprite"+a.id+"' "+~~(1/(60/a.e)*100)/100*(a.g+1)+"s linear 0 infinite";a.B.appendChild(a.a);h.appendChild(a.B)}a.id=d.push(a)-1;B.push(a);a.F=function(){if(a.g>0){if(a.n==a.e&&a.e!==0){if(a.l==a.g){if(a.l=0,typeof a.q==="function"&&(a.p++,a.p===a.A))a.q(),a.p=0}else a.l++;a.n=0}a.e!==0&&a.n++;b()}};return{position:function(b,c,e){a.b=b||a.b;a.c=c||a.c;a.h=e||a.h;i?e&&d.sort(function(a,b){return b.h-a.h}):(a.f.left=b+"px",a.f.top=c+"px",a.f.zIndex=e||a.h);return{x:a.b,y:a.c,I:a.h}},hit:function(b,c){m.indexOf(a)===-1&&m.push(a);a.r[b.id()]=c;m.indexOf(a)===-1&&m.push(a)},zone:function(b,c,d,e){if(b!==o)a.d.t=e,a.d.w=b,a.d.v=c,a.d.o=d;return a.d},noHits:function(){a.r={}},callback:function(b,c){a.q=b;a.A=c},change:function(b,c,d,e,f){a.a.src=b;a.width=c;a.height=d;a.D=c;a.C=d;a.g=e;a.i=f;a.n=0;a.l=0;a.q=null;a.p=0;a.A=0;if(!i&&(a.a.style.width=c*(a.i+1)+"px",a.a.style.height=d*(a.g+1)+"px",a.f.width=c+"px",a.f.height=d+"px",j))a.a.style.webkitAnimationName="",a.m.innerHTML=q(),a.a.style.webkitAnimationName="sprite"+a.id;a.d={w:0,t:0,o:0,v:0}},size:function(b,c){if(b!==o){if(!i)a.f.width=b+"px",a.f.height=c+"px",a.a.style.width=b*(a.G+1)+"px",a.a.style.height=c*(a.g+1)+"px";a.width=b;a.height=c;if(j)a.a.style.webkitAnimationName="",a.m.innerHTML=q(),a.a.style.webkitAnimationName="sprite"+a.id}return{width:a.width,height:a.height}},speed:function(b){if(b!==o&&(a.e=b,a.n=0,j))a.a.style.webkitAnimationDuration=~~(1/(60/b)*100)/100*(a.g+1)+"s";return a.e},animation:function(b){if(b!==o&&(a.i=b,j))a.a.style.webkitAnimationName="",a.m.innerHTML=q(),a.a.style.webkitAnimationName="sprite"+a.id;return a.i},frame:function(b){if(b!==o)a.l=b;return a.l},id:function(){return a.id}}},bg:function(c,g,e,f){function j(a){switch(a){case "N":b.j=0;b.k=-1;break;case "W":b.j=-1;b.k=0;break;case "S":b.j=0;b.k=1;break;case "E":b.j=1;b.k=0;break;default:b.j=0,b.k=0}}var k=i?function(){try{l.s(b.a,b.b,b.c),l.s(b.a,b.b+b.a.width*b.j,b.c+b.a.height*b.k),l.s(b.a,b.b-b.a.width*b.j,b.c-b.a.height*b.k)}catch(a){}if(b.j===-1){if(b.b<b.a.width*-1)b.b=0}else if(b.j===1){if(b.b>b.a.width)b.b=0}else if(b.k===-1){if(b.c<b.a.height*-1)b.c=0}else if(b.k===1&&b.c>b.a.height)b.c=0}:function(){h.style.backgroundPosition=b.b+"px "+b.c+"px"},b=this;i?(b.a=new Image,b.a.src=c):h.style.backgroundImage="url("+c+")";b.e=g||3;j(e);b.h=f.z||0;b.b=f.x||0;b.c=f.y||0;b.id=d.push(b);b.u=0;b.F=function(){b.b+=b.e*b.j*b.u;b.c+=b.e*b.k*b.u;k()};return{on:function(){b.u=1},off:function(){b.u=0},dir:function(a){b.b=b.c=0;j(a)},speed:function(a){if(a!==o)b.e=a;return b.e},position:function(a,c){b.b=a||b.b;b.c=c||b.c;return{x:b.b,y:b.c}}}},hook:function(c){g.push(c)},unhook:function(c){g.indexOf(c)!==-1&&g.splice(g.indexOf(c),1)}}};
View
1,393 mibbu.js 100644 → 100755
@@ -1,645 +1,748 @@
-/*global document, setInterval, setTimeout, Image, clearTimeout*/
-
-/**
- *
- * mibbu - javascript canvas/DOM game framework
- * by Michal Budzynski
- * http://michalbe.blogspot.com
- * http://twitter.com/michalbe
- * http://mibbu.eu
- * http://onGameStart.com
- *
- */
-
-var mibbu = function(Cwidth, Cheight, _parent){
- var MB_usingCanvas = true, //use canvas or DOM?
- document = window['document'], //document declaration for Closure Compiler
- MB_elements = [], //all drawable elements
- MB_parentElement = _parent ? document.getElementById(_parent) : document.body, //parent element the canvas will be appended to
- MB_mainCanvas,
- MB_mainContext,
- MB_mainCanvasWidth = Cwidth || 400,
- MB_mainCanvasHeight = Cheight || 300,
- MB_addedLoops=[], //functions added to each loop frame
- MB_drawLoop, //main loop
- MB_preClear,
- MB_lastTime = new Date(), //time for FPS counter
- MB_fpsMeasure=false,
- MB_ftpsDiv,
- MB_collides=[], //array with references to objects with enabled collisions
- MB_fixedIndexColl = [], //workaround for collisions
- MB_Animate,
- MB_mainCanvasStyle;
- /**
- * Older browser's fixes
- */
- // Fallback for Array#indexOf, where the implementation does not support it
- // natively
- //
- // Follows the algorithm described in ES-262 15.4.4.14
- //
- /*
- //MDC spec-like implementation
- Array.prototype.indexOf = Array.prototype.indexOf
- || function (value, start) {
- var key;
- var obj = Object(this);
- var len = obj.length >>> 0;
-
- start = +start || 0;
- if (!len || start >= len){
- return -1;
- }
- if (start < 0){
- start = Math.max(0, len - Math.abs(start));
- }
-
- for (key = start; key < len; ++key){
- if (key in obj && obj[key] === value){
- return key;
- }
- }
- return -1;
- }
- */
- // lastIndexOf implementation by Andrea Giammarchi
- // form Falsy Values conference
- // http://webreflection.blogspot.com
- Array.prototype.indexOf = Array.prototype.indexOf ||
- function(value){
- for (var i = this.length; i-- && this[i]!== value;) {}
- return i;
- }
-
- //and custom remove() method
- var rm = function(value, array) {
- if (array.indexOf(value)!==-1) {
- array.splice(array.indexOf(value), 1);
- return true;
- } else {
- return false;
- };
- }
-
-
- /**
- * DEBUG FUNCTIONS
- **/
-
- var frameCount=0;
- var fps = 0;
- var MeasureFPS = function(){
- var newTime = new Date();
- var diffTime = ~~((newTime.getTime() - MB_lastTime.getTime()));
-
- if (diffTime >= 1000) {
- fps = frameCount;
- frameCount = 0;
- MB_lastTime = newTime;
- }
- var stringFps = 'FPS: ' + fps;
- if (MB_usingCanvas) {
- //MB_mainContext.fillStyle = "#fff";
- //MB_mainContext.font = "12px Arial";
- MB_mainContext.fillText(stringFps, 4, 15);
- } else {
- if (MB_ftpsDiv) {
- MB_ftpsDiv.innerHTML = stringFps;
- }
- }
- frameCount++;
- };
-
- /**
- * end of debug functions
- *
- * Start/Stop functions
- **/
-
- //main drawing function
- var DrawAll = function(){
-
- MB_preClear();
-
- //draw all element
- var loopIndex = MB_elements.length;
- while (loopIndex--) {
- MB_elements[loopIndex].draw();
- }
-
- //run other functions
- loopIndex = MB_addedLoops.length;
- while (loopIndex--) {
- MB_addedLoops[loopIndex]();
- }
-
- if (MB_fpsMeasure) {
- MeasureFPS();
- }
-
- };
- //check if it is possible to use canvas
- var MB_detectCanvas = function() {
- if(!document.createElement('canvas').getContext) {
- MB_usingCanvas = false;
- }
- };
-
- var MB_InitCore = function() {
- //common part of both modes
-
- MB_preClear = MB_usingCanvas ? function(){MB_mainContext.clearRect(0, 0, MB_mainCanvasWidth, MB_mainCanvasHeight);} : function(){};
-
- if (MB_fpsMeasure) {
- MB_lastTime = new Date();
- }
-
- //use requestAnimationFrame() if possible
- //inspired by Paul Irish Blog
- //http://paulirish.com/2011/requestanimationframe-for-smart-animating/
- //support only for moz & webkit now - Opera or IE are no
- //interested in it so far.
- MB_Animate = (function(){
- return window['webkitRequestAnimationFrame'] ||
- window['mozRequestAnimationFrame'] ||
- function(/* function */ callback, /* DOMElement */ element){
- setTimeout(callback, 1000 / 60);
- };
- })();
-
- //inline styling, not using setAttribute()
- //because of IE7 & IE8 bugs
- MB_mainCanvasStyle = MB_mainCanvas.style;
- MB_mainCanvas.width = MB_mainCanvasWidth;
- MB_mainCanvas.height = MB_mainCanvasHeight;
- MB_mainCanvasStyle.width = MB_mainCanvasWidth+'px';
- MB_mainCanvasStyle.height =MB_mainCanvasHeight+'px';
- MB_mainCanvasStyle.position ='absolute'
- MB_mainCanvasStyle.overflow = 'hidden';
-
- MB_parentElement.appendChild(MB_mainCanvas);
-
- };
-
- var MB_InitCanvas = function() {
- MB_mainCanvas = document.createElement('canvas');
-
- MB_InitCore();
- MB_mainContext = MB_mainCanvas.getContext('2d');
- MB_mainContext.i = MB_mainContext.drawImage;
-
- //sorting all elements is like Z-Index for canvas
- MB_elements.sort(function(a,b){return a.zOrder - b.zOrder;});
-
- };
-
- var MB_InitDOM = function() {
-
- MB_mainCanvas = document.createElement('div');
-
- //MB_mainCanvas.style.overflow = 'hidden';
- MB_InitCore();
-
- if (MB_fpsMeasure) {
-
- MB_ftpsDiv = document.createElement('div');
- MB_mainCanvas.appendChild(MB_ftpsDiv);
-
- }
-
- };
-
- //initiation of main loop
- var running = true,
- MB_Start = function() {
- DrawAll();
-
- if(running)
- MB_drawLoop = MB_Animate(MB_Start, MB_mainCanvas);
- };
-
- var MB_Stop = function() {
- clearTimeout(MB_drawLoop);
- running=false;
- };
-
- /**
- * End of Start/Stop functions
- **/
- //collisions
- var MB_checkCollides = function() {
- var loopIndex = MB_collides.length,
- element,
- p1, p2,
- p1Top, p1Bottom, p1Left, p1Right,
- p2Top, p2Bottom, p2Left, p2Right;
-
- while(loopIndex--) {
- p1 = MB_collides[loopIndex];
- p1Top = p1.posY + p1.cZ.t;
- p1Bottom = p1.posY + p1.height - p1.cZ.b;
- p1Left = p1.posX + p1.cZ.l;
- p1Right = p1.posX + p1.width - p1.cZ.r;
-
- //UNCOMMENT THSE TWO BLOCKS FOR COLLISION BOXES.
- //IN CANVAS MODE ONLY!
- /*
- MB_mainContext.moveTo(p1Right, p1Top);
-
- MB_mainContext.lineTo(p1Right, p1Bottom);
- MB_mainContext.lineTo(p1Left, p1Bottom);
- MB_mainContext.lineTo(p1Left, p1Top);
- MB_mainContext.lineTo(p1Right, p1Top);
- */
- for(element in MB_collides[loopIndex].hits){
- p2 = MB_fixedIndexColl[element];
- p2Top = p2.posY + p2.cZ.t;
- p2Bottom = p2.posY + p2.height - p2.cZ.b;
- p2Left = p2.posX + p2.cZ.l;
- p2Right = p2.posX + p2.width - p2.cZ.r;
- /*
- MB_mainContext.moveTo(p2Right, p2Top);
-
- MB_mainContext.lineTo(p2Right, p2Bottom);
- MB_mainContext.lineTo(p2Left, p2Bottom);
- MB_mainContext.lineTo(p2Left, p2Top);
- MB_mainContext.lineTo(p2Right, p2Top);
- MB_mainContext.stroke();
- */
- if (!(
- (p1Top > p2Bottom) ||
- (p1Bottom < p2Top) ||
- (p1Left > p2Right) ||
- (p1Right < p2Left)
- )){
- //console.dir(MB_collides[loopIndex].hits)
- MB_collides[loopIndex].hits[element]();
- }
- }
-
- }
- };
-
- /**
- * SPRITES
- **/
-
- var MB_Sprite = function(_image, _width, _height, _frames, _animations) {
-
- var draw = MB_usingCanvas ? function(){
- //draw canvas
- try {
- MB_mainContext.i(t.image,
- t.iWidth * t.animation,
- t.iHeight * t.f,
- t.iWidth,
- t.iHeight,
- t.posX,
- t.posY,
- t.width,
- t.height);
- } catch(e) {
- //if image is not ready yet try to display it on another frame
- //delete this and build preLoader
- }
- } : function(){
- //draw DOM
- t.image.style.top = t.height * t.f*-1+'px';
- t.image.style.left = t.width * t.animation*-1+'px';
- },
- t = {};
- t.id = MB_elements.length;
-
- t.image = new Image();
- t.image.src = _image;
-
- t.speed = 1;
- t.width = _width;
- t.iWidth = _width;
- t.height = _height;
- t.iHeight = _height;
- t.fs = _frames;
- t.animations = _animations;
- t.colllides = false;
- t.hits = {};
-
- t.f = 0;
- t.animation = 0;
- t.speed = 1;
- t.interval = 0;
-
- t.posX = 0;
- t.posY = 0;
-
- t.zOrder = 1;
-
- t.callback = null;
- t.callIters=0;
- t.callMaxIters=0;
-
- //collision zones
- t.cZ = {
- t: 0,
- l: 0,
- b:0,
- r: 0
- }
-
- if (!MB_usingCanvas) {
- //document.createElement('img') not allowed in IE6
- t.div = document.createElement('div');
- t.s = t.div.style;
-
- t.s.overflow = 'hidden';
- t.s.width = _width+'px';
- t.s.height = _height+'px';
- t.s.position = 'absolute';
- t.s.zIndex = t.zOrder;
-
- t.image.style.position="absolute";
- t.div.appendChild(t.image);
-
-
-
- MB_mainCanvas.appendChild(t.div);
- }
-
- t.id = MB_elements.push(t)-1;
- MB_fixedIndexColl.push(t); //for collisions, temporary
-
- var setPosition = function(x, y, z) {
- t.posX = x || t.posX;
- t.posY = y || t.posY;
- t.zOrder = z || t.zOrder;
-
- if (MB_usingCanvas) {
- if (z) {
- MB_elements.sort(function(a, b){
- //return a.zOrder - b.zOrder;}
- return b.zOrder - a.zOrder;
- } //reversed becaouse of 'while' loop in DrawAll();
- );
-
- }
- } else {
- t.s.left = x+'px';
- t.s.top = y+'px';
- t.s.zIndex = z || t.zOrder;
- }
- return {x:t.posX, y:t.posY, z:t.zOrder}
- },
-
- setCollide = function(e) {
- if (e && MB_collides.indexOf(t) === -1) {
- MB_collides.push(t);
- } else if (!e && MB_collides.indexOf(t) !== -1){
- rm(t, MB_collides);
- }
- },
-
- onHit = function (object, callback) {
- setCollide(true);
- t.hits[object.id()] = callback;
- if (MB_collides.indexOf(t) === -1) {
- MB_collides.push(t);
- }
- };
-
- t.draw = function() {
-
- if (t.fs > 0) {
- if (t.interval == t.speed && t.speed !== 0) {
- if (t.f == t.fs) {
- t.f = 0;
-
- if (typeof t.callback === "function") {
- t.callIters++;
- if (t.callIters === t.callMaxIters) {
- t.callback();
- t.callIters = 0;
- }
-
- }
-
- }
- else {
- t.f++;
- }
- t.interval = 0;
- }
- if (t.speed !== 0) {
- t.interval++;
- }
-
- draw();
-
- }
- };
- var reSize = function(w, h){
- if (w !== undefined) {
- if (!MB_usingCanvas){
-
- t.s.width = w+'px';
- t.s.height = h+'px';
-
- t.image.style.width = w*(t.animations+1)+'px';
- t.image.style.height = h*(t.fs+1)+'px';
-
- }
- t.width = w;
- t.height = h;
- }
- return {width:t.width,height:t.height};
- };
-
- return {
- 'position':setPosition,
- 'hit':onHit,
- 'zone': function(top, right, bottom, left) {
- if (top !== undefined) {
- t.cZ.l = left;
- t.cZ.t = top;
- t.cZ.r = right;
- t.cZ.b = bottom;
- }
- return t.cZ;
- },
- 'noHits':function() {
- t.hits = {};
- },
- 'callback':function(fn, iteration) {
- t.callback = fn;
- t.callMaxIters = iteration;
- },
- 'change': function(image, width, height, frames, animations) {
- t.image.src = image;
- t.width = width;
- t.height = height;
- t.iWidth = width;
- t.iHeight = height;
- t.fs = frames;
- t.animations = animations;
- t.interval = 0;
- t.f = 0;
- if (!MB_usingCanvas) {
- t.image.style.width = width*(t.animations+1)+'px';
- t.image.style.height = height*(t.fs+1)+'px';
- t.s.width = width+'px';
- t.s.height = height+'px';
- }
-
- t.cZ = {
- t: 0,
- l: 0,
- b: 0,
- r: 0
- }
- },
-
- 'size':reSize,
- 'speed':function(e) { if (e !== undefined) { t.speed=e; t.interval=0;} return t.speed;},
- 'animation':function(e) { if (e !== undefined) t.animation=e; return t.animation;},
- 'frame':function(e) { if (e !== undefined) t.f=e; return t.f;},
- 'id': function() { return t.id; }
- };
- };
-
- /**
- * SPRITES END
- **/
-
- /**
- * START BACKGROUNDS
- **/
- var MB_Background = function(image, speed, direction, options) {
-
- var draw = MB_usingCanvas ? function(){
- //draw Canvas
- try {
- MB_mainContext.i(t.image, t.posX, t.posY);
- MB_mainContext.i(t.image, t.posX + t.image.width * t.dX, t.posY + t.image.height * t.dY);
- MB_mainContext.i(t.image, t.posX - t.image.width * t.dX, t.posY - t.image.height * t.dY);
- } catch(e) {};
-
- if (t.dX === -1) {
- if (t.posX < (t.image.width*-1)) {
- t.posX = 0;
- }
- } else if (t.dX === 1) {
- if (t.posX > (t.image.width)) {
- t.posX = 0;
- }
- } else if (t.dY === -1) {
- if (t.posY < (t.image.height*-1)) {
- t.posY = 0;
- }
- } else if (t.dY === 1) {
- if (t.posY > (t.image.height)) {
- t.posY = 0;
- }
- }
- } : function(){
- //draw DOM
- MB_mainCanvas.style.backgroundPosition = t.posX +"px "+t.posY+"px";
- },
- t = this;
-
- if (MB_usingCanvas) {
- t.image = new Image();
- t.image.src = image;
- } else {
- MB_mainCanvas.style.backgroundImage = 'url('+image+')';
- }
-
- t.speed = speed || 3;
-
- var direcionFromString = function(dirString){
- switch (dirString) {
- case 'N':
- t.dX = 0;
- t.dY = -1;
- break;
- case 'W':
- t.dX = -1;
- t.dY = 0;
- break;
- case 'S':
- t.dX = 0;
- t.dY = 1;
- break;
- case 'E':
- t.dX = 1;
- t.dY = 0;
- break;
- default:
- t.dX = 0;
- t.dY = 0;
- break;
- }
- }
-
- direcionFromString(direction);
-
- t.zOrder = options['z'] || 0;
- t.posX = options['x'] || 0;
- t.posY = options['y'] || 0;
-
- t.id = MB_elements.push(t);
-
- t.moving = 0;
-
- var setPosition = function(x, y) {
- t.posX = x || t.posX;
- t.posY = y || t.posY;
-
- return {x:t.posX, y:t.posY}
- };
-
- t.draw = function() {
- t.posX += t.speed*t.dX*t.moving;
- t.posY += t.speed*t.dY*t.moving;
-
- draw();
- }
-
- return {
- 'on': function() { t.moving = 1; },
- 'off': function() { t.moving = 0; },
- 'dir': function(direction) { t.posX = t.posY = 0; direcionFromString(direction); },
- 'speed':function(e) { if (e !== undefined) { t.speed=e; } return t.speed;},
- 'position':setPosition
- }
-
- }
-
-
- /**
- * Constructor functions
- */
- MB_detectCanvas();
-
-
- return {
- //config
- 'fps': function() {MB_fpsMeasure=true;},
- 'init': function() { MB_usingCanvas ? MB_InitCanvas() : MB_InitDOM(); },
- 'on': function() { running=true; MB_Start()},
- 'off': MB_Stop,
- 'canvas': function(){ return MB_mainCanvas; },
- 'ctx': function() {return MB_mainContext; },
- 'canvasOff': function() {MB_usingCanvas=false;},
- 'hitsOn': function() { if(MB_addedLoops.indexOf(MB_checkCollides) === -1) MB_addedLoops.push(MB_checkCollides); },
- 'hitsOff': function() { rm(MB_checkCollides, MB_addedLoops); },
-
- //elements
- 'spr':MB_Sprite,
- 'bg': MB_Background,
-
- //loops
- 'hook': function(e){MB_addedLoops.push(e);},
- 'unhook': function(e){rm(e, MB_addedLoops);}
-
- };
-};
-//declaration of mibbu object for Closure Compiler
-window['mibbu'] = mibbu;
+/*global document, setInterval, setTimeout, Image, clearTimeout*/
+
+/**
+*
+* mibbu - javascript canvas/DOM game framework
+* by Michal Budzynski
+* http://michalbe.blogspot.com
+* http://twitter.com/michalbe
+* http://mibbu.eu
+* http://onGameStart.com
+*
+*/
+
+var mibbu = function(Cwidth, Cheight, _parent){
+ var MB_usingCanvas = true, //use canvas or DOM?
+ MB_usingCSSAnimations = false,
+ document = window['document'], //document declaration for Closure Compiler
+ MB_elements = [], //all drawable elements
+ MB_parentElement = _parent ? document.getElementById(_parent) : document.body, //parent element the canvas will be appended to
+ MB_mainCanvas,
+ MB_mainContext,
+ MB_mainCanvasWidth = Cwidth || 400,
+ MB_mainCanvasHeight = Cheight || 300,
+ MB_addedLoops=[], //functions added to each loop frame
+ MB_drawLoop, //main loop
+ MB_preClear,
+ MB_lastTime = new Date(), //time for FPS counter
+ MB_fpsMeasure=false,
+ MB_ftpsDiv,
+ MB_collides=[], //array with references to objects with enabled collisions
+ MB_fixedIndexColl = [], //workaround for collisions
+ MB_Animate,
+ MB_mainCanvasStyle;
+ /**
+ * Older browser's fixes
+ */
+ // Fallback for Array#indexOf, where the implementation does not support it
+ // natively
+ //
+ // Follows the algorithm described in ES-262 15.4.4.14
+ //
+ /*
+ //MDC spec-like implementation
+ Array.prototype.indexOf = Array.prototype.indexOf
+ || function (value, start) {
+ var key;
+ var obj = Object(this);
+ var len = obj.length >>> 0;
+
+ start = +start || 0;
+ if (!len || start >= len){
+ return -1;
+ }
+ if (start < 0){
+ start = Math.max(0, len - Math.abs(start));
+ }
+
+ for (key = start; key < len; ++key){
+ if (key in obj && obj[key] === value){
+ return key;
+ }
+ }
+ return -1;
+ }
+ */
+ // lastIndexOf implementation by Andrea Giammarchi
+ // form Falsy Values conference
+ // http://webreflection.blogspot.com
+ Array.prototype.indexOf = Array.prototype.indexOf ||
+ function(value){
+ for (var i = this.length; i-- && this[i]!== value;) {}
+ return i;
+ }
+
+ //and custom remove() method
+ var rm = function(value, array) {
+ if (array.indexOf(value)!==-1) {
+ array.splice(array.indexOf(value), 1);
+ return true;
+ } else {
+ return false;
+ };
+ }
+
+
+ /**
+ * DEBUG FUNCTIONS
+ **/
+
+ var frameCount=0;
+ var fps = 0;
+ var MeasureFPS = function(){
+ var newTime = new Date();
+ var diffTime = ~~((newTime.getTime() - MB_lastTime.getTime()));
+
+ if (diffTime >= 1000) {
+ fps = frameCount;
+ frameCount = 0;
+ MB_lastTime = newTime;
+ }
+ var stringFps = 'FPS: ' + fps;
+ if (MB_usingCanvas) {
+ //MB_mainContext.fillStyle = "#fff";
+ //MB_mainContext.font = "12px Arial";
+ MB_mainContext.fillText(stringFps, 4, 15);
+ } else {
+ if (MB_ftpsDiv) {
+ MB_ftpsDiv.innerHTML = stringFps;
+ }
+ }
+ frameCount++;
+ };
+
+ /**
+ * end of debug functions
+ *
+ * Start/Stop functions
+ **/
+
+ var calculateSpeed = function(speed, frames) {
+ return (~~((1/(60/speed))*100)/100)*(frames+1);
+ };
+ //main drawing function
+ var DrawAll = function(){
+
+ MB_preClear();
+
+ //draw all element
+ var loopIndex = MB_elements.length;
+ while (loopIndex--) {
+ MB_elements[loopIndex].draw();
+ }
+
+ //run other functions
+ loopIndex = MB_addedLoops.length;
+ while (loopIndex--) {
+ MB_addedLoops[loopIndex]();
+ }
+
+ if (MB_fpsMeasure) {
+ MeasureFPS();
+ }
+
+ };
+ //check if it is possible to use canvas
+ var MB_detectCanvas = function() {
+ if(!document.createElement('canvas').getContext) {
+ MB_usingCanvas = false;
+ }
+ };
+
+ var MB_InitCore = function() {
+ //common part of both modes
+
+ MB_preClear = MB_usingCanvas ? function(){MB_mainContext.clearRect(0, 0, MB_mainCanvasWidth, MB_mainCanvasHeight);} : function(){};
+
+ if (MB_fpsMeasure) {
+ MB_lastTime = new Date();
+ }
+
+ //use requestAnimationFrame() if possible
+ //inspired by Paul Irish Blog
+ //http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+ //support only for moz & webkit now - Opera or IE are no
+ //interested in it so far.
+ MB_Animate = (function(){
+ return window['webkitRequestAnimationFrame'] ||
+ window['mozRequestAnimationFrame'] ||
+ function(/* function */ callback, /* DOMElement */ element){
+ setTimeout(callback, 1000 / 60);
+ };
+ })();
+
+ //inline styling, not using setAttribute()
+ //because of IE7 & IE8 bugs
+ MB_mainCanvasStyle = MB_mainCanvas.style;
+ MB_mainCanvas.width = MB_mainCanvasWidth;
+ MB_mainCanvas.height = MB_mainCanvasHeight;
+ MB_mainCanvasStyle.width = MB_mainCanvasWidth+'px';
+ MB_mainCanvasStyle.height =MB_mainCanvasHeight+'px';
+ MB_mainCanvasStyle.position ='absolute'
+ MB_mainCanvasStyle.overflow = 'hidden';
+
+ MB_parentElement.appendChild(MB_mainCanvas);
+
+ };
+
+ var MB_InitCanvas = function() {
+ MB_mainCanvas = document.createElement('canvas');
+
+ MB_mainContext = MB_mainCanvas.getContext('2d');
+ MB_mainContext.i = MB_mainContext.drawImage;
+
+ //sorting all elements is like Z-Index for canvas
+ MB_elements.sort(function(a,b){return a.zOrder - b.zOrder;});
+
+ };
+
+ var MB_InitDOM = function() {
+
+ MB_mainCanvas = document.createElement('div');
+
+ //MB_mainCanvas.style.overflow = 'hidden';
+
+ if (MB_fpsMeasure) {
+
+ MB_ftpsDiv = document.createElement('div');
+ MB_mainCanvas.appendChild(MB_ftpsDiv);
+
+ }
+
+ };
+
+ //initiation of main loop
+ var running = true,
+ MB_Start = function() {
+ DrawAll();
+
+ if(running)
+ MB_drawLoop = MB_Animate(MB_Start, MB_mainCanvas);
+ };
+
+ var MB_Stop = function() {
+ clearTimeout(MB_drawLoop);
+ running=false;
+ };
+
+ /**
+ * End of Start/Stop functions
+ **/
+ //collisions
+ var MB_checkCollides = function() {
+ var loopIndex = MB_collides.length,
+ element,
+ p1, p2,
+ p1Top, p1Bottom, p1Left, p1Right,
+ p2Top, p2Bottom, p2Left, p2Right;
+
+ while(loopIndex--) {
+ p1 = MB_collides[loopIndex];
+ p1Top = p1.posY + p1.cZ.t;
+ p1Bottom = p1.posY + p1.height - p1.cZ.b;
+ p1Left = p1.posX + p1.cZ.l;
+ p1Right = p1.posX + p1.width - p1.cZ.r;
+
+ //UNCOMMENT THSE TWO BLOCKS FOR COLLISION BOXES.
+ //IN CANVAS MODE ONLY!
+ /*
+ MB_mainContext.moveTo(p1Right, p1Top);
+
+ MB_mainContext.lineTo(p1Right, p1Bottom);
+ MB_mainContext.lineTo(p1Left, p1Bottom);
+ MB_mainContext.lineTo(p1Left, p1Top);
+ MB_mainContext.lineTo(p1Right, p1Top);
+ */
+ for(element in MB_collides[loopIndex].hits){
+ p2 = MB_fixedIndexColl[element];
+ p2Top = p2.posY + p2.cZ.t;
+ p2Bottom = p2.posY + p2.height - p2.cZ.b;
+ p2Left = p2.posX + p2.cZ.l;
+ p2Right = p2.posX + p2.width - p2.cZ.r;
+ /*
+ MB_mainContext.moveTo(p2Right, p2Top);
+
+ MB_mainContext.lineTo(p2Right, p2Bottom);
+ MB_mainContext.lineTo(p2Left, p2Bottom);
+ MB_mainContext.lineTo(p2Left, p2Top);
+ MB_mainContext.lineTo(p2Right, p2Top);
+ MB_mainContext.stroke();
+ */
+ if (!(
+ (p1Top > p2Bottom) ||
+ (p1Bottom < p2Top) ||
+ (p1Left > p2Right) ||
+ (p1Right < p2Left)
+ )){
+ //console.dir(MB_collides[loopIndex].hits)
+ MB_collides[loopIndex].hits[element]();
+ }
+ }
+
+ }
+ };
+
+ /**
+ * SPRITES
+ **/
+
+ var MB_Sprite = function(_image, _width, _height, _frames, _animations) {
+
+ var draw = MB_usingCanvas ? function(){
+ //draw canvas
+ try {
+ MB_mainContext.i(t.image,
+ t.iWidth * t.animation,
+ t.iHeight * t.f,
+ t.iWidth,
+ t.iHeight,
+ t.posX,
+ t.posY,
+ t.width,
+ t.height);
+ } catch(e) {
+ //if image is not ready yet try to display it on another frame
+ //delete this and build preLoader
+ }
+ } : MB_usingCSSAnimations ? function(){ /*css animations*/ } : function(){
+ //draw DOM
+ t.si.top = t.height * t.f*-1+'px';
+ t.si.left = t.width * t.animation*-1+'px';
+ },
+ t = {},
+ //prepare class for CSS animation
+ constructAnimationClass = function(){
+ var animationClass = "@-webkit-keyframes 's"+t.id+"' {\n",
+ step = 100/(t.fs+1),
+ str = '% { -webkit-transform: translate(';
+ for (var q = 0; q < t.fs+1; q++) {
+ animationClass += ~~((step*q)*100)/100+ str +t.animation*t.width*-1+'px,'+q*t.height*-1+'px); }\n';
+ animationClass += ~~((step*(q+1)-0.01)*100)/100+ str +t.animation*t.width*-1+'px,'+q*t.height*-1+'px); }\n';
+ }
+
+ return animationClass += '100'+ str +t.animation*t.width+'px, 0px); }\n}';
+
+ };
+
+
+ t.id = MB_elements.length;
+
+ t.image = new Image();
+ t.image.src = _image;
+
+ t.speed = 1;
+ t.width = _width;
+ t.iWidth = _width;
+ t.height = _height;
+ t.iHeight = _height;
+ t.fs = _frames;
+ t.animations = _animations;
+ t.colllides = false;
+ t.hits = {};
+
+ t.f = 0;
+ t.animation = 0;
+ t.speed = 1;
+ t.interval = 0;
+
+ t.posX = 0;
+ t.posY = 0;
+
+ t.zOrder = 1;
+
+ t.callback = null;
+ t.callIters=0;
+ t.callMaxIters=0;
+
+ //collision zones
+ t.cZ = {
+ t: 0,
+ l: 0,
+ b:0,
+ r: 0
+ }
+
+ if (!MB_usingCanvas) {
+ //document.createElement('img') not allowed in IE6
+ t.div = document.createElement('div');
+ t.s = t.div.style;
+
+ t.s.overflow = 'hidden';
+ t.s.width = _width+'px';
+ t.s.height = _height+'px';
+ t.s.position = 'absolute';
+ t.s.zIndex = t.zOrder;
+
+ t.si = t.image.style;
+
+ t.si.position="absolute";
+
+ if (MB_usingCSSAnimations) {
+ //calculate keyframes for CSS animation
+
+
+ //append keyframe class to the document
+ t.animStyle = document.createElement('style');
+ t.animStyle.innerHTML = constructAnimationClass();
+ //document.getElementsByTagName('head')[0]
+ document.body.appendChild(t.animStyle);
+
+ //additional style attribute for the image
+ t.si.webkitAnimation = "'s"+t.id+"' "+calculateSpeed(t.speed, t.fs)+"s linear 0 infinite";
+
+ }
+
+ t.div.appendChild(t.image);
+
+ MB_mainCanvas.appendChild(t.div);
+ }
+
+ t.id = MB_elements.push(t)-1;
+ MB_fixedIndexColl.push(t); //for collisions, temporary
+
+ var setPosition = function(x, y, z) {
+ t.posX = x || t.posX;
+ t.posY = y || t.posY;
+ t.zOrder = z || t.zOrder;
+
+ if (MB_usingCanvas) {
+ if (z) {
+ MB_elements.sort(function(a, b){
+ //return a.zOrder - b.zOrder;}
+ return b.zOrder - a.zOrder;
+ } //reversed becaouse of 'while' loop in DrawAll();
+ );
+
+ }
+ } else {
+ t.s.left = x+'px';
+ t.s.top = y+'px';
+ t.s.zIndex = z || t.zOrder;
+ }
+ return {x:t.posX, y:t.posY, z:t.zOrder}
+ },
+
+ setCollide = function(e) {
+ if (e && MB_collides.indexOf(t) === -1) {
+ MB_collides.push(t);
+ } else if (!e && MB_collides.indexOf(t) !== -1){
+ rm(t, MB_collides);
+ }
+ },
+
+ onHit = function (object, callback) {
+ setCollide(true);
+ t.hits[object.id()] = callback;
+ if (MB_collides.indexOf(t) === -1) {
+ MB_collides.push(t);
+ }
+ };
+
+ t.draw = function() {
+
+ if (t.fs > 0) {
+ if (t.interval == t.speed && t.speed !== 0) {
+ if (t.f == t.fs) {
+ t.f = 0;
+
+ if (typeof t.callback === "function") {
+ t.callIters++;
+ if (t.callIters === t.callMaxIters) {
+ t.callback();
+ t.callIters = 0;
+ }
+
+ }
+
+ }
+ else {
+ t.f++;
+ }
+ t.interval = 0;
+ }
+ if (t.speed !== 0) {
+ t.interval++;
+ }
+
+ draw();
+
+ }
+ };
+ var reSize = function(w, h){
+ if (w !== undefined) {
+ if (!MB_usingCanvas){
+
+ t.s.width = w+'px';
+ t.s.height = h+'px';
+
+ t.si.width = w*(t.animations+1)+'px';
+ t.si.height = h*(t.fs+1)+'px';
+
+ }
+ t.width = w;
+ t.height = h;
+ if (MB_usingCSSAnimations) {
+ //any smarter way to refresh cssAnimation than clearing the name of it?
+ t.si.webkitAnimationName = '';
+ t.animStyle.innerHTML = constructAnimationClass();
+ t.si.webkitAnimationName = 's'+t.id;
+ //t.si.webkitAnimationDuration = calculateSpeed(t.speed, t.fs)+'s';
+ };
+ }
+ return {width:t.width,height:t.height};
+ };
+
+ return {
+ 'position':setPosition,
+ 'hit':onHit,
+ 'zone': function(top, right, bottom, left) {
+ if (top !== undefined) {
+ t.cZ.l = left;
+ t.cZ.t = top;
+ t.cZ.r = right;
+ t.cZ.b = bottom;
+ }
+ return t.cZ;
+ },
+ 'noHits':function() {
+ t.hits = {};
+ },
+ 'callback':function(fn, iteration) {
+ t.callback = fn;
+ t.callMaxIters = iteration;
+ },
+ 'change': function(image, width, height, frames, animation) {
+ t.image.src = image;
+ t.width = width;
+ t.height = height;
+ t.iWidth = width;
+ t.iHeight = height;
+ t.fs = frames;
+ t.animation = animation;
+ t.interval = 0;
+ t.f = 0;
+ t.callback = null;
+ t.callIters=0;
+ t.callMaxIters=0;
+
+ if (!MB_usingCanvas) {
+ t.si.width = width*(t.animation+1)+'px';
+ t.si.height = height*(t.fs+1)+'px';
+ t.s.width = width+'px';
+ t.s.height = height+'px';
+ if (MB_usingCSSAnimations) {
+ //any smarter way to refresh cssAnimation than clearing it's name?
+ t.si.webkitAnimationName = '';
+ t.animStyle.innerHTML = constructAnimationClass();
+ t.si.webkitAnimationName = 's'+t.id;
+ }
+ }
+
+ t.cZ = {
+ t: 0,
+ l: 0,
+ b: 0,
+ r: 0
+ }
+ },
+
+ 'size':reSize,
+ 'speed':function(e) {
+ if (e !== undefined) {
+ t.speed=e;
+ t.interval=0;
+ if (MB_usingCSSAnimations){
+ t.si.webkitAnimationDuration = calculateSpeed(e, t.fs)+'s';
+ }
+ }
+ return t.speed;
+ },
+ 'animation':function(e) {
+ if (e !== undefined) {
+
+ t.animation=e;
+
+ if (MB_usingCSSAnimations) {
+ //any smarter way to refresh cssAnimation than clearing the name of it?
+ t.si.webkitAnimationName = '';
+ t.animStyle.innerHTML = constructAnimationClass();
+ t.si.webkitAnimationName = 's'+t.id;
+ }
+ }
+ return t.animation;
+ },
+ 'frame':function(e) { if (e !== undefined) t.f=e; return t.f;},
+ 'id': function() { return t.id; }
+ };
+ };
+
+ /**
+ * SPRITES END
+ **/
+
+ /**
+ * START BACKGROUNDS
+ **/
+ var MB_Background = function(image, speed, direction, options) {
+
+ var draw = MB_usingCanvas ? function(){
+ //draw Canvas
+ try {
+ MB_mainContext.i(t.image, t.posX, t.posY);
+ MB_mainContext.i(t.image, t.posX + t.image.width * t.dX, t.posY + t.image.height * t.dY);
+ MB_mainContext.i(t.image, t.posX - t.image.width * t.dX, t.posY - t.image.height * t.dY);
+ } catch(e) {};
+
+ if (t.dX === -1) {
+ if (t.posX < (t.image.width*-1)) {
+ t.posX = 0;
+ }
+ } else if (t.dX === 1) {
+ if (t.posX > (t.image.width)) {
+ t.posX = 0;
+ }
+ } else if (t.dY === -1) {
+ if (t.posY < (t.image.height*-1)) {
+ t.posY = 0;
+ }
+ } else if (t.dY === 1) {
+ if (t.posY > (t.image.height)) {
+ t.posY = 0;
+ }
+ }
+ } : function(){
+ //draw DOM
+ MB_mainCanvas.style.backgroundPosition = t.posX +"px "+t.posY+"px";
+ },
+ t = this;
+
+ if (MB_usingCanvas) {
+ t.image = new Image();
+ t.image.src = image;
+ } else {
+ MB_mainCanvas.style.backgroundImage = 'url('+image+')';
+ }
+
+ t.speed = speed || 3;
+
+ var direcionFromString = function(dirString){
+ switch (dirString) {
+ case 'N':
+ t.dX = 0;
+ t.dY = -1;
+ break;
+ case 'W':
+ t.dX = -1;
+ t.dY = 0;
+ break;
+ case 'S':
+ t.dX = 0;
+ t.dY = 1;
+ break;
+ case 'E':
+ t.dX = 1;
+ t.dY = 0;
+ break;
+ default:
+ t.dX = 0;
+ t.dY = 0;
+ break;
+ }
+ }
+
+ direcionFromString(direction);
+
+ t.zOrder = options['z'] || 0;
+ t.posX = options['x'] || 0;
+ t.posY = options['y'] || 0;
+
+ t.id = MB_elements.push(t);
+
+ t.moving = 0;
+
+ var setPosition = function(x, y) {
+ t.posX = x || t.posX;
+ t.posY = y || t.posY;
+
+ return {x:t.posX, y:t.posY}
+ };
+
+ t.draw = function() {
+ t.posX += t.speed*t.dX*t.moving;
+ t.posY += t.speed*t.dY*t.moving;
+
+ draw();
+ }
+
+ return {
+ 'on': function() { t.moving = 1; },
+ 'off': function() { t.moving = 0; },
+ 'dir': function(direction) { t.posX = t.posY = 0; direcionFromString(direction); },
+ 'speed':function(e) { if (e !== undefined) { t.speed=e; } return t.speed;},
+ 'position':setPosition
+ }
+
+ }
+
+
+ /**
+ * Constructor functions
+ */
+ MB_detectCanvas();
+
+
+ return {
+ //config
+ 'fps': function() {MB_fpsMeasure=true;},
+ 'init': function() { MB_usingCanvas ? MB_InitCanvas() : MB_InitDOM(); MB_InitCore();},
+ 'on': function() {
+ running=true;
+ MB_Start();
+ if (MB_usingCSSAnimations){
+ //this solution is really stupid and temporary ( I hope )
+ //unfortunatelly any other didn't really work
+ var i = MB_elements.length;
+ for (;i--;){
+ if (MB_elements[i].image)
+ MB_elements[i].image.style.webkitAnimationDuration = calculateSpeed(MB_elements[i].speed, MB_elements[i].fs)+'s';
+ }
+ }
+ },
+ 'off': function(){
+ MB_Stop();
+ if (MB_usingCSSAnimations){
+ //this solution is really stupid and temporary ( I hope )
+ //unfortunatelly any other didn't really work
+ var i = MB_elements.length;
+ for (;i--;){
+ if (MB_elements[i].image)
+ MB_elements[i].image.style.webkitAnimationDuration = 0;
+ }
+ }
+ },
+ 'canvas': function(){ return MB_mainCanvas; },
+ 'ctx': function() {return MB_mainContext; },
+ 'canvasOff': function() {
+ MB_usingCanvas=false;
+ if (typeof MB_parentElement.style.webkitAnimation !== "undefined") {
+ //we have webkit CSS3 animation support
+ //for now just in webkit, sorry Aurora users.
+ MB_usingCSSAnimations = true;
+ }
+ },
+ 'cssAnimationOff': function() {MB_usingCSSAnimations=false;},
+ 'hitsOn': function() { if(MB_addedLoops.indexOf(MB_checkCollides) === -1) MB_addedLoops.push(MB_checkCollides); },
+ 'hitsOff': function() { rm(MB_checkCollides, MB_addedLoops); },
+
+ //elements
+ 'spr':MB_Sprite,
+ 'bg': MB_Background,
+
+ //loops
+ 'hook': function(e){MB_addedLoops.push(e);},
+ 'unhook': function(e){rm(e, MB_addedLoops);}
+
+ };
+};
+//declaration of mibbu object for Closure Compiler
+window['mibbu'] = mibbu;

0 comments on commit efcdd6d

Please sign in to comment.