entityjs 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +49 -0
  4. data/Rakefile +1 -0
  5. data/bin/entityjs +14 -0
  6. data/build/build_debug.bat +1 -0
  7. data/build/build_min.bat +1 -0
  8. data/build/config.php +64 -0
  9. data/build/debug.php +48 -0
  10. data/build/files.php +74 -0
  11. data/build/jsmin.php +376 -0
  12. data/build/min.php +50 -0
  13. data/changelog.txt +53 -0
  14. data/entityjs.gemspec +25 -0
  15. data/examples/keys/arrow.png +0 -0
  16. data/examples/keys/keys.html +59 -0
  17. data/examples/keys/keys.js +148 -0
  18. data/examples/mouse/mouse.html +58 -0
  19. data/examples/mouse/mouse.js +60 -0
  20. data/examples/scenes/home.png +0 -0
  21. data/examples/scenes/scenes.html +55 -0
  22. data/examples/scenes/scenes.js +134 -0
  23. data/examples/scenes/win.png +0 -0
  24. data/examples/sounds/sound1.mp3 +0 -0
  25. data/examples/sounds/sound1.ogg +0 -0
  26. data/examples/sounds/sounds.html +56 -0
  27. data/examples/sounds/sounds.js +44 -0
  28. data/examples/style/background.png +0 -0
  29. data/examples/style/sheet.css +762 -0
  30. data/examples/tiles/tiles.html +56 -0
  31. data/examples/tiles/tiles.js +85 -0
  32. data/examples/tiles/tiles.png +0 -0
  33. data/lib/blank/config.js +4 -0
  34. data/lib/blank/config.yml +21 -0
  35. data/lib/blank/home.js +11 -0
  36. data/lib/blank/init.js +7 -0
  37. data/lib/blank/load.js +21 -0
  38. data/lib/blank/play.html +29 -0
  39. data/lib/entity.debug.js +52 -0
  40. data/lib/entity.min.js +184 -0
  41. data/lib/entityjs/command.rb +37 -0
  42. data/lib/entityjs/comp.rb +11 -0
  43. data/lib/entityjs/game.rb +93 -0
  44. data/lib/entityjs/min.rb +11 -0
  45. data/lib/entityjs/refresh.rb +14 -0
  46. data/lib/entityjs/version.rb +3 -0
  47. data/lib/entityjs.rb +6 -0
  48. data/license.txt +1 -0
  49. data/spec/lib/entityjs/game_spec.rb +11 -0
  50. data/spec/spec_helper.rb +3 -0
  51. data/src/entityjs/core/component.js +306 -0
  52. data/src/entityjs/core/entity.js +516 -0
  53. data/src/entityjs/core/load.js +224 -0
  54. data/src/entityjs/core/query.js +410 -0
  55. data/src/entityjs/core/re.js +70 -0
  56. data/src/entityjs/core/system.js +125 -0
  57. data/src/entityjs/cycle/draw.js +185 -0
  58. data/src/entityjs/cycle/ticker.js +27 -0
  59. data/src/entityjs/cycle/tween.js +61 -0
  60. data/src/entityjs/cycle/update.js +86 -0
  61. data/src/entityjs/cycle/wait.js +22 -0
  62. data/src/entityjs/cycle/worker.js +9 -0
  63. data/src/entityjs/display/anchor.js +53 -0
  64. data/src/entityjs/display/bitfont.js +93 -0
  65. data/src/entityjs/display/bitmap.js +37 -0
  66. data/src/entityjs/display/circle.js +30 -0
  67. data/src/entityjs/display/font.js +41 -0
  68. data/src/entityjs/display/group.js +63 -0
  69. data/src/entityjs/display/rect.js +19 -0
  70. data/src/entityjs/display/screen.js +46 -0
  71. data/src/entityjs/display/sprite.js +37 -0
  72. data/src/entityjs/input/keyboard.js +150 -0
  73. data/src/entityjs/input/mouse.js +123 -0
  74. data/src/entityjs/input/pressed.js +81 -0
  75. data/src/entityjs/input/touch.js +28 -0
  76. data/src/entityjs/math/bind.js +76 -0
  77. data/src/entityjs/math/bisect.js +69 -0
  78. data/src/entityjs/math/body.js +39 -0
  79. data/src/entityjs/math/drag.js +39 -0
  80. data/src/entityjs/math/hitmap.js +165 -0
  81. data/src/entityjs/math/hittest.js +26 -0
  82. data/src/entityjs/math/physics.js +142 -0
  83. data/src/entityjs/math/point.js +57 -0
  84. data/src/entityjs/math/tile.js +91 -0
  85. data/src/entityjs/media/channel.js +93 -0
  86. data/src/entityjs/media/playlist.js +5 -0
  87. data/src/entityjs/media/sound.js +110 -0
  88. data/src/entityjs/net/socket.js +52 -0
  89. data/src/entityjs/pattern/arraymap.js +89 -0
  90. data/src/entityjs/pattern/flicker.js +214 -0
  91. data/src/entityjs/pattern/timestep.js +34 -0
  92. data/src/entityjs/save/database.js +7 -0
  93. data/src/entityjs/save/storage.js +57 -0
  94. data/src/entityjs/util/log.js +25 -0
  95. data/src/entityjs/util/polyfill.js +25 -0
  96. data/src/entityjs/util/random.js +38 -0
  97. data/src/entityjs/util/scene.js +101 -0
  98. data/src/entityjs/util/sheet.js +51 -0
  99. data/src/entityjs/util/support.js +132 -0
  100. metadata +156 -0
@@ -0,0 +1,52 @@
1
+ /*
2
+ The socket component is an interface for the new HTML5 websockets.
3
+
4
+ Its safe to use this abstraction incase specs change in the future.
5
+
6
+ */
7
+ re.c('socket')
8
+ .extend({
9
+
10
+ connect:function(address){
11
+
12
+ this.socket = new WebSocket(address);
13
+
14
+ },
15
+
16
+ close:function(){
17
+ if(!this.socket) return this;
18
+
19
+ this.socket.close();
20
+
21
+ return this;
22
+ },
23
+
24
+ open:function(callback){
25
+ if(!this.socket) return this;
26
+
27
+ this.socket.onopen = callback;
28
+
29
+ },
30
+
31
+ error:function(callback){
32
+ if(!this.socket) return this;
33
+
34
+ this.socket.onerror = callback;
35
+
36
+ },
37
+
38
+ message:function(callback){
39
+ if(!this.socket) return this;
40
+
41
+ this.socket.onmessage = callback;
42
+
43
+ },
44
+
45
+ send:function(){
46
+ if(!this.socket) return this;
47
+
48
+ this.socket.send.apply(this.socket, arguments);
49
+
50
+ }
51
+
52
+ });
@@ -0,0 +1,89 @@
1
+ /*
2
+ The arraymap component creates an auto expandable two-dimensional array.
3
+ */
4
+ re.c('arraymap')
5
+ .inherit({
6
+ lengthX:0,
7
+ lengthY:0
8
+ })
9
+ .extend({
10
+ /*map:null,
11
+ size:null,*/
12
+ value:0,
13
+
14
+ set:function(x, y, value){
15
+
16
+ //increate y length
17
+ while(y >= this.map.length){
18
+ var m = new Array(this.map[0]);
19
+
20
+ for(var l in m){
21
+ m[l] = this.value;
22
+ }
23
+
24
+ this.map.push(m);
25
+
26
+ }
27
+
28
+ //increase x length
29
+ while(x >= this.map[this.map.length-1].length){
30
+
31
+ for(var k=0; k<this.map.length; k++){
32
+ this.map[k].push(this.value);
33
+ }
34
+
35
+ }
36
+
37
+ this.lengthX = this.map[y].length;
38
+ this.lengthY = this.map.length;
39
+
40
+ this.map[y][x] = value;
41
+
42
+ return this;
43
+ },
44
+
45
+ within:function(x, y){
46
+
47
+ if(y < 0 || y >= this.lengthY || x < 0 || x >= this.lengthX){
48
+ return false;
49
+ }
50
+ return true;
51
+ },
52
+
53
+ get:function(x, y){
54
+ if(this.within(x,y)){
55
+ return this.map[y][x];
56
+ }
57
+ return null;
58
+ },
59
+
60
+ copy:function(a){
61
+
62
+ for(var y=0; y<a.length; y++){
63
+ for(var x=0; x<a[0].length; x++){
64
+ this.set(x, y, a[y][x]);
65
+ }
66
+ }
67
+
68
+ return this;
69
+ },
70
+
71
+ copyByRef:function(m){
72
+
73
+ this.map = m;
74
+
75
+ if(m.length > 0){
76
+ this.lengthX = m[0].length;
77
+ } else {
78
+ this.lengthX = 0;
79
+ }
80
+
81
+ this.lengthY = m.length;
82
+
83
+ return this;
84
+ }
85
+
86
+ })
87
+ .init(function(){
88
+ this.map = [];
89
+ });
@@ -0,0 +1,214 @@
1
+ /*
2
+ The flicker component calls the implemented method and sends the given information over a period of time.
3
+
4
+ This is most popular for sprite animation.
5
+
6
+ It can also be used for graduatly writing text or flashing a drawing object.
7
+ */
8
+ re.c('flicker')
9
+ .require('update timestep')
10
+ .implement('flick')
11
+ .init(function(){
12
+
13
+ this.flicker_reels = {};
14
+ this.flicker_old = {};
15
+ this.flicker_reel = {};
16
+
17
+ this.flicker_flickering = '';
18
+
19
+ })
20
+ .extend({
21
+
22
+ flicker_stop:function(){
23
+ if(this.flickering()){
24
+
25
+ this.signal('animated', this.flicker_flickering);
26
+
27
+ this.flicker_flickering = '';
28
+
29
+ this.stepProgress = 0;
30
+ this.frameX = this.flicker_oldX;
31
+ this.frameY = this.flicker_oldY;
32
+
33
+ this.removeSignal('update', this.flicker_update);
34
+ }
35
+ return this;
36
+ },
37
+
38
+ flicker_update:function(t){
39
+
40
+ this.timestep(t, function(){
41
+ var c = this.flicker_reel;
42
+
43
+ //check if over
44
+ if(this.flicker_frame == this.flicker_reel.frames.length){
45
+
46
+ if(c.loops == -1 || --this.flicker_loops >= 1){
47
+ //loop again
48
+
49
+ this.flicker_frame = 0;
50
+
51
+ } else {
52
+ //done flickering
53
+
54
+ this.flicker_stop();
55
+
56
+ return;
57
+ }
58
+ }
59
+
60
+ //flick
61
+ this.flick(c.frames[this.flicker_frame]);
62
+
63
+ this.flicker_frame++;
64
+
65
+ });
66
+
67
+ },
68
+
69
+ addFlicker:function(id, loops, duration, frames){
70
+
71
+ if(typeof id == 'object'){
72
+
73
+ for(var i in id){
74
+ if(!id.hasOwnProperty(i)) continue;
75
+
76
+ //copy formed array and insert
77
+ var c = id[i].slice();
78
+ //add key into array
79
+ c.unshift(i);
80
+
81
+ this.addFlicker.apply(this, c);
82
+
83
+ }
84
+
85
+ return this;
86
+ }
87
+
88
+ if(typeof frames == 'string') frames = frames.split(' ');
89
+
90
+ //add
91
+ this.flicker_reels[id] =
92
+ {
93
+ frames:frames,
94
+ duration:duration,
95
+ loops:loops
96
+ };
97
+
98
+ return this;
99
+ },
100
+
101
+ removeFlicker:function(id){
102
+
103
+ if(typeof id == 'object'){
104
+
105
+ for(var i in id){
106
+ if(!id.hasOwnProperty(i)) continue;
107
+
108
+ this.removeFlicker.call(this, id[i]);
109
+ }
110
+
111
+ return this;
112
+ }
113
+
114
+ //assuming this flicker isn't running
115
+ delete this.flicker_reels[id];
116
+
117
+ return this;
118
+ },
119
+
120
+ /*
121
+ The animate method either creates or plays an animation.
122
+ Time is in milliseconds.
123
+
124
+ //create sequence animation
125
+ re('#player').flicker('die', 1, 200, [0, 1, 3, 3, 4, 3, 2, 1]);
126
+
127
+ //play animation
128
+ //can customize the animation for this call.
129
+ re('#player').flicker('die', 0, 200);
130
+
131
+ //stop flickering
132
+ re('#player').flicker();
133
+
134
+ //add multiple animations
135
+ flicker({
136
+ idle:[loops, duration, frames],
137
+ ..
138
+
139
+
140
+ });
141
+
142
+ FUTURE:
143
+ -allow backward animations
144
+ -allow entry of an array of frames. So each counter will go to the next frame in the array
145
+ */
146
+ flicker:function(id, loops, duration, frames){
147
+
148
+ if(arguments.length == 0){
149
+ //stop flickering
150
+ return this.flicker_stop();
151
+ }
152
+
153
+ if(id == this.flicker_flickering) return;
154
+
155
+ if(!this.flicker_reels[id]){
156
+ return this;
157
+ }
158
+
159
+ //defaults
160
+
161
+ //startX = loops, endX = duration in seconds
162
+ //if startX equals 0, animation loops forever
163
+
164
+ var r = this.flicker_reels[id];
165
+
166
+ //create new reel based on custom attributes
167
+ var c = this.flicker_reel;
168
+ //copy from saved animation or newly given
169
+ c.loops = (isNaN(loops))? r.loops : loops;
170
+ c.duration = (isNaN(duration))? r.duration : duration;
171
+ c.frames = (typeof frames == 'object')? frames : r.frames;
172
+
173
+ //setup counter for loops
174
+ this.flicker_loops = c.loops;
175
+
176
+ this.stepProgress = 0;
177
+ this.stepSize = c.duration / c.frames.length;
178
+
179
+ //save old frames for upon completion
180
+
181
+ this.flicker_oldX = this.frameX;
182
+ this.flicker_oldY = this.frameY;
183
+
184
+ this.flicker_frame = 0;
185
+
186
+ //update frame then run
187
+ this.flick(c.frames[this.flicker_frame++]);
188
+
189
+ if(!this.flickering()){
190
+ this.addSignal('update', this.flicker_update);
191
+ }
192
+
193
+ this.flicker_flickering = id;
194
+
195
+
196
+
197
+ return this;
198
+ },
199
+
200
+ /*
201
+ Check if flicker is running / compare current.
202
+
203
+ this.flickering(); // false
204
+ this.flickering('idle'); // false
205
+ */
206
+ flickering:function(id){
207
+ if(id){
208
+ return this.flicker_flickering == id;
209
+ }
210
+
211
+ return this.flicker_flickering != '';
212
+ }
213
+
214
+ });
@@ -0,0 +1,34 @@
1
+ /*
2
+
3
+
4
+ re.e('timestep')
5
+ .timestep(progress, function(){
6
+
7
+
8
+
9
+ });
10
+ */
11
+
12
+ re.c('timestep')
13
+ .inherit({
14
+
15
+ stepProgress:0,
16
+ stepSize:0.3
17
+
18
+ })
19
+ .extend({
20
+
21
+ timestep:function(progress, callback, context){
22
+
23
+ this.stepProgress += progress;
24
+
25
+ while(this.stepProgress >= this.stepSize){
26
+
27
+ callback.call((context)?context:this);
28
+
29
+ this.stepProgress -= this.stepSize;
30
+ }
31
+
32
+ }
33
+
34
+ })
@@ -0,0 +1,7 @@
1
+ /*
2
+ The database component adds functions for creating and dealing with databases.
3
+ This will reference only one database.
4
+
5
+ Because of the current stance of firefox. I'm not sure if its safe implementing this yet.
6
+ *//*
7
+ re.c('database');*/
@@ -0,0 +1,57 @@
1
+ /*
2
+ The storage component contains methods for storing locally or session values.
3
+ This utilizes the new HTML5 localstorage and sessionstorage.
4
+
5
+ //create new local storage
6
+ re.e('storage:local');
7
+
8
+ //create new session storage
9
+ re.e('storage:session');
10
+
11
+ */
12
+ re.c('storage')
13
+ .init(function(c, type){
14
+ this.storage = (type == 'session')? sessionStorage : localStorage;
15
+ })
16
+ .extend({
17
+
18
+ length:function(){
19
+ return this.storage.length;
20
+ },
21
+
22
+ key:function(index){
23
+ return this.storage.key(index);
24
+ },
25
+
26
+ getItem:function(key){
27
+ return this.storage.getItem(key);
28
+ },
29
+
30
+ getJson:function(key){
31
+ return JSON.parse(this.getItem(key));
32
+ },
33
+
34
+ setItem:function(key, data){
35
+
36
+ if(typeof data != 'number' || typeof data != 'string'){
37
+ data = JSON.stringify(data);
38
+ }
39
+
40
+ this.storage.setItem(key, data);
41
+
42
+ return this;
43
+ },
44
+
45
+ removeItem:function(key){
46
+ this.storage.removeItem(key);
47
+
48
+ return this;
49
+ },
50
+
51
+ clear:function(){
52
+ this.storage.clear();
53
+
54
+ return this;
55
+ }
56
+
57
+ })
@@ -0,0 +1,25 @@
1
+ /*
2
+ The log component extends a cross browser console.log command.
3
+
4
+ //example usage
5
+ re.e('log')
6
+ .log('example log');
7
+
8
+ //global usage
9
+ re.log('example log');
10
+
11
+ */
12
+ re.log = function(){
13
+ try{
14
+ console.log.apply(console, arguments);
15
+ } catch(e){
16
+ try {
17
+ opera.postError.apply(opera, arguments);
18
+ } catch(e){
19
+ alert(Array.prototype.join.call(arguments, " "));
20
+ }
21
+ }
22
+ };
23
+
24
+ re.c('log')
25
+ .extend('log', re.log);
@@ -0,0 +1,25 @@
1
+ /*
2
+ The polyfill component polyfills unsupported HTML5 functions when possible.
3
+ */
4
+ re.c('polyfill')
5
+ .extend({
6
+
7
+ requestAnimationFrame:function(callback, canvas){
8
+ return requestAnimFrame(callback, canvas);
9
+ }
10
+
11
+ })
12
+ .run(function(){
13
+
14
+ //setup requestanimationframe on support
15
+ window.requestAnimFrame =
16
+ window.requestAnimationFrame ||
17
+ window.webkitRequestAnimationFrame ||
18
+ window.mozRequestAnimationFrame ||
19
+ window.oRequestAnimationFrame ||
20
+ window.msRequestAnimationFrame ||
21
+ function(callback){
22
+ window.setTimeout(callback, 1000 / 60);
23
+ };
24
+
25
+ });
@@ -0,0 +1,38 @@
1
+ /*
2
+ The random component implements two helper methods for calculating random numbers.
3
+
4
+ r = re.e('random');
5
+
6
+ r.random() // 0 - 1
7
+ r.random(10) // 0 - 9
8
+ r.random(10, 30) // 10 - 30
9
+
10
+ randomInt rounds numbers to whole
11
+ */
12
+ re.c('random')
13
+ .extend({
14
+
15
+ random:function(max, min){
16
+ switch(arguments.length){
17
+ case 0:
18
+ return Math.random();
19
+ case 1:
20
+ return Math.random() * max;
21
+ case 2:
22
+ return Math.random() * (max - min + 1) + min;
23
+ }
24
+ },
25
+
26
+ randomInt:function(max, min){
27
+ return Math.floor(this.random.apply(this, arguments));
28
+ }
29
+
30
+ })
31
+ .run(function(){
32
+ var b = re.e('random');
33
+
34
+ re.random = b.random;
35
+ re.randomInt = b.randomInt;
36
+
37
+ b.dispose();
38
+ });
@@ -0,0 +1,101 @@
1
+
2
+ /*
3
+ Goes to an other scene in the game. This calls the scene method with a possible object argument.
4
+
5
+ Scenes are a helpful way to organize stages of a game.
6
+
7
+ //create scene
8
+ re.scene('game')
9
+ .enter(function(data){
10
+
11
+ //remove all 2d elements
12
+ re('2d').dispose();
13
+
14
+ loadLevel(data.level);
15
+
16
+ });
17
+
18
+ //go to scene
19
+ re.scene('game', {tiles:[]} );
20
+
21
+ //delete a scene
22
+ re.scene('-home');
23
+
24
+ //combine delete home goto title sceen
25
+ re.scene('-home title');
26
+ */
27
+ re.scene = function(title){
28
+ var s = re.c('scene');
29
+
30
+ //delete scene
31
+ if(title.charAt(0) == '-'){
32
+
33
+ delete s._scenes[title.substr(1)];
34
+
35
+ return s;
36
+
37
+ } else if(s._scenes[title]){
38
+ //go to scene
39
+
40
+ var current = arguments.callee.current;
41
+
42
+ //call exit
43
+ var t = s._scenes[current];
44
+ if(t && typeof t.scene_exit == 'function'){
45
+ t.scene_exit.call(t, title);
46
+ }
47
+
48
+ arguments.callee.current = title;
49
+ s.curent = title;
50
+
51
+ t = s._scenes[title];
52
+
53
+ if(typeof t.scene_enter == 'function'){
54
+ t.scene_enter.apply(t, Array.prototype.slice.call(arguments, 1));
55
+ }
56
+
57
+
58
+ } else {
59
+
60
+ //add scene
61
+ re.e('scene:'+title);
62
+ }
63
+
64
+ return s._scenes[title];
65
+ };
66
+
67
+ re.c('scene')
68
+ .global({
69
+
70
+ _scenes:{}
71
+
72
+ })
73
+ .init(function(c, title){
74
+
75
+ c._scenes[title] = this;
76
+ this.sceneName = title;
77
+
78
+ })
79
+ .dispose(function(c){
80
+
81
+ delete c._scenes[this.sceneName];
82
+
83
+ })
84
+ .extend({
85
+
86
+ enter:function(m){
87
+ this.scene_enter = m;
88
+
89
+ return this;
90
+ },
91
+
92
+ exit:function(m){
93
+ this.scene_exit = m;
94
+
95
+ return this;
96
+ },
97
+
98
+ scene:function(){
99
+ return re.scene.apply(this, arguments);
100
+ }
101
+ });
@@ -0,0 +1,51 @@
1
+ /*
2
+ The sheet component converts a each frame of a sprite sheet into their own components.
3
+ */
4
+ re.c('sheet')
5
+ .global({
6
+
7
+ sheet:function(map, padX, padY, sizeX, sizeY){
8
+
9
+ var frameWidth = sizeX || re.tile.sizeX;
10
+ var frameHeight = sizeY || re.tile.sizeY;
11
+
12
+ if(padX){
13
+ frameWidth += padX;
14
+ }
15
+
16
+ if(padY){
17
+ frameHeight += padY;
18
+ }
19
+
20
+ //create new sprites for sheet
21
+
22
+ //save frame positions from map
23
+ var x;
24
+ var y;
25
+
26
+ for(var p in map){
27
+ x = map[p][0] || 0;
28
+ y = map[p][1] || 0;
29
+
30
+ re.c(p)
31
+ .require('sprite')
32
+ .extend({
33
+ frame:{x:x, y:y},
34
+ size:{x:frameWidth, y:frameHeight},
35
+ bitmap:this.bitmap
36
+ });
37
+
38
+ }
39
+
40
+ return this;
41
+ }
42
+
43
+ })
44
+ .require('tile')
45
+ .extend({
46
+
47
+ sheet:re.sheet
48
+
49
+ });
50
+
51
+ re.sheet = re.c('sheet').sheet;