entityjs 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,185 @@
1
+ re.c('draw')
2
+ .global({
3
+ listeners:[],
4
+
5
+ draw:function(s){
6
+ var l = this.listeners;
7
+
8
+ for(var k=0, le = l.length, b; k < le; ++k){
9
+ b = l[k];
10
+
11
+ if(b && b.sys == s && b.drawing && b.isVisible()){
12
+ /*if(!b.canvasCache){
13
+ b.draw_render(c);
14
+ } else {
15
+ b.signal('draw', c);
16
+ }*/
17
+ b.draw_render(s.context);
18
+
19
+ }
20
+ }
21
+
22
+ }
23
+
24
+ })
25
+ .implement('draw')
26
+ .init(function(c){
27
+
28
+ c.listeners.push(this);
29
+
30
+ //set default screen
31
+ this.screen = re.screen;
32
+
33
+ })
34
+ .dispose(function(c){
35
+
36
+ c.listeners.splice(c.listeners.indexOf(this), 1);
37
+
38
+ })
39
+ .inherit({
40
+
41
+ sys:re.sys,
42
+ drawing:true,
43
+ rotation:0,
44
+ alpha:1,
45
+
46
+ scaleX:1,
47
+ scaleY:1,
48
+
49
+ posX:0,
50
+ posY:0,
51
+
52
+ sizeX:1,
53
+ sizeY:1,
54
+
55
+ regX:0,
56
+ regY:0
57
+
58
+ })
59
+ .extend({
60
+
61
+ cache:function(){
62
+ if(!this.image) return this;
63
+
64
+ this.clearCache();
65
+
66
+ var c = re.$new('canvas');
67
+ var s = Math.max(this.image.width, this.image.height);
68
+ c.width = s;
69
+ c.height = s;
70
+
71
+ this.draw_render(c.getContext(re.sys.contextType));
72
+
73
+ this.canvasCache = c;
74
+
75
+ return this;
76
+ },
77
+
78
+ clearCache:function(){
79
+ this.canvasCache = null;
80
+ },
81
+
82
+ drawFirst:function(){
83
+ var l = re.c('draw').listeners;
84
+
85
+ l.splice(l.indexOf(this), 1);
86
+
87
+ l.unshift(this);
88
+ return this;
89
+ },
90
+
91
+ drawLast:function(){
92
+ var l = re.c('draw').listeners;
93
+
94
+ l.splice(l.indexOf(this), 1);
95
+
96
+ l.push(this);
97
+ return this;
98
+ },
99
+
100
+ drawAfter:function(en){
101
+ var l = re.c('draw').listeners;
102
+ var him = l.indexOf(en);
103
+ var me = l.indexOf(this);
104
+
105
+ if(him > me){
106
+ //swap
107
+ var t = l[him];
108
+ l[him] = l[me];
109
+ l[me] = t;
110
+ }
111
+
112
+ return this;
113
+ },
114
+
115
+ drawBefore:function(en){
116
+
117
+ var l = re.c('draw').listeners;
118
+ var him = l.indexOf(en);
119
+ var me = l.indexOf(this);
120
+
121
+ if(him < me){
122
+ //swap
123
+ var t = l[him];
124
+ l[him] = l[me];
125
+ l[me] = t;
126
+ }
127
+
128
+ return this;
129
+ },
130
+
131
+ getScreenX:function(){
132
+ var x = this.posX;
133
+ if(this.screen) x -= this.screen.posX;
134
+ return x;
135
+ },
136
+
137
+ getScreenY:function(){
138
+ var y = this.posY;
139
+ if(this.screen) y -= this.screen.posY;
140
+ return y;
141
+ },
142
+
143
+ /*
144
+ Returns true or false wether the object is visible on screen.
145
+ */
146
+ isVisible:function(){
147
+
148
+ return (!this.screen || this.screen.touches(this.posX - this.regX, this.posY - this.regY, this.sizeX, this.sizeY));
149
+
150
+ }
151
+
152
+ })
153
+ .namespace({
154
+
155
+ render:function(c){
156
+ if(!c) c = this.sys.context;
157
+
158
+ this.draw_before(c);
159
+ this.draw(c);
160
+ this.draw_after(c);
161
+ },
162
+
163
+ before:function(c){
164
+
165
+ c.save();
166
+
167
+ if(this.alpha != 1)
168
+ c.globalAlpha = this.alpha;
169
+
170
+ c.translate(this.getScreenX(), this.getScreenY());
171
+
172
+ if(this.rotation != 0)
173
+ c.rotate(this.rotation * Math.PI / 180);
174
+
175
+
176
+ if(this.scaleX != 1 || this.scaleY != 1)
177
+ c.scale(this.scaleX, this.scaleY);
178
+
179
+ },
180
+
181
+ after:function(c){
182
+ c.restore();
183
+ }
184
+
185
+ });
@@ -0,0 +1,27 @@
1
+ /*
2
+ The ticker component calculates time between steps for animation or special effects.
3
+ */
4
+ re.c('ticker')
5
+ .inherit({
6
+ time:0,
7
+ maxTick:0.05
8
+ })
9
+ .init(function(){
10
+ this.lastTime = Date.now();
11
+ })
12
+ .extend({
13
+
14
+ tick:function(){
15
+ var wall = Date.now();
16
+ var delta = (wall - this.lastTime) / 1000;
17
+
18
+ this.lastTime = wall;
19
+
20
+ var timeDelta = Math.min(delta, this.maxTick);
21
+
22
+ this.time += timeDelta;
23
+
24
+ return timeDelta;
25
+ }
26
+
27
+ });
@@ -0,0 +1,61 @@
1
+ /*
2
+ The tween component tweens properties of entities to the given value over a period of time.
3
+
4
+ This is useful for animations.
5
+
6
+ re.e('tween')
7
+ .tween(0.8, {x:10});
8
+
9
+ */
10
+ re.c('tween')
11
+ .require('update')
12
+ .global({
13
+
14
+ tween:function(obj, time, props){
15
+ return obj.comp('tween')
16
+ .tween(time, props);
17
+ }
18
+
19
+ })
20
+ .namespace({
21
+
22
+ update:function(t){
23
+
24
+
25
+
26
+ }
27
+
28
+ })
29
+ .inherit({
30
+
31
+ tweening:false
32
+
33
+ })
34
+ .extend({
35
+
36
+ tween:function(time, props){
37
+ this.time = time || 5;
38
+
39
+ if(this.tweening){
40
+ this.removeSignal('update', this.tween_update);
41
+ }
42
+
43
+ //collect properties
44
+ for(var i in props){
45
+
46
+ if(!props.hasOwnProperty(i)) continue;
47
+
48
+ this.tween_props[i] = {s:re.sys.stepSize, i:props[i]};
49
+
50
+ }
51
+
52
+ return this;
53
+ }
54
+
55
+ })
56
+ .init(function(){
57
+
58
+ this.tween_props = {};
59
+
60
+ });
61
+ re.tween = re.c('tween').tween;
@@ -0,0 +1,86 @@
1
+ /*
2
+ The update component calls update signals to all listening entities.
3
+ */
4
+ re.c('update')
5
+ .global({
6
+ listeners:[],
7
+ update:function(s,t){
8
+ var l = this.listeners;
9
+
10
+ for(var k=0, le = l.length, b; k < le; ++k){
11
+ b = l[k];
12
+
13
+ if(b && b.sys == s && b.updating){
14
+ b.signal('update', t, s.time);
15
+ }
16
+ }
17
+
18
+ }
19
+ })
20
+ .inherit({
21
+ updating:true,
22
+ sys:re.sys
23
+ })
24
+ .extend(function(){
25
+
26
+ var l = re.c('update').listeners;
27
+
28
+ return {
29
+ updateFirst:function(){
30
+
31
+ l.splice(l.indexOf(this), 1);
32
+
33
+ l.unshift(this);
34
+
35
+ return this;
36
+ },
37
+
38
+ updateLast:function(){
39
+
40
+ l.splice(l.indexOf(this), 1);
41
+
42
+ l.push(l);
43
+
44
+ return this;
45
+ },
46
+
47
+ updateAfter:function(e){
48
+
49
+ var him = l.indexOf(e);
50
+ var me = l.indexOf(this);
51
+
52
+ if(him > me){
53
+ //swap
54
+ var t = l[him];
55
+ l[him] = l[me];
56
+ l[me] = t;
57
+ }
58
+
59
+ return this;
60
+ },
61
+
62
+ updateBefore:function(e){
63
+
64
+ var him = l.indexOf(e);
65
+ var me = l.indexOf(this);
66
+
67
+ if(him < me){
68
+ //swap
69
+ var t = l[him];
70
+ l[him] = l[me];
71
+ l[me] = t;
72
+ }
73
+
74
+ return this;
75
+ }
76
+
77
+ };
78
+
79
+ }())
80
+ .init(function(c){
81
+ c.listeners.push(this);
82
+ })
83
+ .dispose(function(c){
84
+
85
+ c.listeners.splice(c.listeners.indexOf(this), 1);
86
+ });
@@ -0,0 +1,22 @@
1
+ /*
2
+ The wait component delays function calls.
3
+ */
4
+ re.c('wait')
5
+ .require('update')
6
+ .extend({
7
+
8
+ wait:function(time, callback){
9
+ var c = 0;
10
+
11
+ this.addSignal('update', function(t){
12
+ c += t;
13
+
14
+ if(c >= time){
15
+ this.callback.apply(this, Array.prototype.slice.call(arguments, 2));
16
+ return false;
17
+ }
18
+ });
19
+
20
+ }
21
+
22
+ });
@@ -0,0 +1,9 @@
1
+ /*
2
+ The worker component will contain an interface for the new HTML5 webworker.
3
+
4
+ TODO
5
+ *//*
6
+ re.c('worker')
7
+ .init(function(){
8
+ throw 'Not implemented';
9
+ });*/
@@ -0,0 +1,53 @@
1
+ /*
2
+ The anchor component contains helper methods for positioning entities relative to system size.
3
+ */
4
+ re.c('anchor')
5
+ .extend({
6
+
7
+ centerX:function(o){
8
+ o = o || 0;
9
+ this.posX = Math.floor(re.sys.sizeX * 0.5 - this.sizeX * 0.5 + o);
10
+
11
+ return this;
12
+ },
13
+
14
+ centerY:function(o){
15
+ o = o || 0;
16
+ this.posY = Math.floor(re.sys.sizeY * 0.5 - this.sizeY * 0.5 + o);
17
+ return this;
18
+ },
19
+
20
+ right:function(x){
21
+ x = x || 0;
22
+ this.posX = Math.floor(re.sys.sizeX - this.sizeX + x);
23
+ return this;
24
+ },
25
+
26
+ left:function(x){
27
+ x = x || 0;
28
+ this.posX = Math.floor(x);
29
+ return this;
30
+ },
31
+
32
+ top:function(y){
33
+ y = y || 0;
34
+ this.posY = Math.floor(y);
35
+ return this;
36
+ },
37
+
38
+ bottom:function(y){
39
+ y = y || 0;
40
+ this.posY = Math.floor(re.sys.sizeY - this.sizeY + y);
41
+ return this;
42
+ }
43
+
44
+ })
45
+ .inherit({
46
+
47
+ sizeX:0,
48
+ sizeY:0,
49
+
50
+ posX:0,
51
+ posY:0
52
+
53
+ });
@@ -0,0 +1,93 @@
1
+ /*
2
+ The bitfont component writes text on the screen using a sprite image.
3
+ This is a faster approach than using the text component for now.
4
+ Plus you don't have to worry about the user not supporting the
5
+ wanted font.
6
+
7
+ */
8
+
9
+ re.c('bitfont')
10
+ .require('draw')
11
+ .inherit({
12
+
13
+ text:'',
14
+ //default width if charwidths not extendd
15
+ charOffset:32
16
+
17
+ })
18
+ .extend({
19
+
20
+ isVisible:function(){
21
+ return this.text.length != 0 && this.bitmap && this.parent('draw', 'isVisible');
22
+ },
23
+
24
+ draw:function(c){
25
+
26
+ var slot = 0, charWidth, code, charPos;
27
+
28
+ for(var i=0, l = this.text.length; i<l; ++i){
29
+
30
+ //get char code
31
+ code = this.text.charCodeAt(i) - this.charOffset;
32
+
33
+ //find width of character
34
+ charWidth = this.charWidths[code];
35
+
36
+ //find source character position
37
+ if(!this.charCache[code]){
38
+ charPos = 0;
39
+ for(var p=0; p<code; ++p){
40
+ charPos += this.charWidths[p]+1;
41
+ }
42
+ this.charCache[code] = charPos;
43
+ }
44
+
45
+ c.drawImage(this.bitmap, this.charCache[code], 0, charWidth, this.bitmap.height, -this.regX + slot, -this.regY, charWidth, this.bitmap.height);
46
+
47
+ //append to next character slot
48
+ slot += charWidth;
49
+
50
+ }
51
+
52
+ this.sizeX = slot;
53
+ this.sizeY = this.bitmap.height;
54
+
55
+
56
+ },
57
+
58
+ updateSize:function(){
59
+
60
+ var t = 0;
61
+ //TODO size is slightly off
62
+ for(var p=0; p<this.text.length; p++){
63
+ t += this.charWidths[p];
64
+ }
65
+
66
+ this.sizeX = t;
67
+
68
+ if(this.bitmap){
69
+ this.sizeY = this.bitmap.height;
70
+ } else {
71
+ this.sizeY = 0;
72
+ }
73
+ return this;
74
+ },
75
+
76
+ setText:function(text){
77
+
78
+ this.text = text;
79
+ this.updateSize();
80
+
81
+ return this;
82
+ }
83
+
84
+ })
85
+ .init(function(){
86
+
87
+ if(!this.charCache){
88
+ this.charCache = {};
89
+ }
90
+
91
+ this.updateSize();
92
+
93
+ });
@@ -0,0 +1,37 @@
1
+ /*
2
+ The bitmap component draws an image on screen.
3
+
4
+
5
+ FUTURE - add bitdata component for image manipulation.
6
+ */
7
+ re.c('bitmap')
8
+ .require('draw')
9
+ .extend({
10
+
11
+ setBitmap:function(b){
12
+ this.bitmap = b;
13
+ if(b){
14
+ this.sizeX = b.width;
15
+ this.sizeY = b.height;
16
+ }
17
+ return this;
18
+ },
19
+
20
+ isVisible:function(){
21
+ return this.bitmap && this.parent('draw', 'isVisible');
22
+ },
23
+
24
+ draw:function(c){
25
+
26
+ c.drawImage(this.bitmap, -this.regX, -this.regY, this.sizeX, this.sizeY);
27
+ return this;
28
+ }
29
+
30
+ })
31
+ .init(function(){
32
+
33
+ if(this.bitmap){
34
+ this.setBitmap(this.bitmap);
35
+ }
36
+
37
+ });
@@ -0,0 +1,30 @@
1
+ /*
2
+ The circle component draws a rectangle on screen.
3
+ */
4
+ re.c('circle')
5
+ .require('draw')
6
+ .inherit({
7
+ color:'#82d5f4'
8
+ })
9
+ .extend({
10
+
11
+ draw:function(c){
12
+
13
+ c.fillStyle = this.color;
14
+
15
+ c.beginPath();
16
+
17
+ c.arc(-this.regX, -this.regY, this.sizeX, 0, Math.PI*2, true);
18
+
19
+ c.closePath();
20
+
21
+ c.fill();
22
+
23
+ },
24
+
25
+ setRadius:function(r){
26
+ this.sizeX = this.sizeY = r;
27
+ return this;
28
+ }
29
+
30
+ });
@@ -0,0 +1,41 @@
1
+ /*
2
+ The font component displays font on screen using the canvas font api.
3
+
4
+ //create font
5
+ re.e('font')
6
+ .extend({
7
+ text:'Texting Message',
8
+ textColor:'#ff0000'
9
+ });
10
+
11
+ TODO implement size
12
+
13
+ */
14
+ re.c('font')
15
+ .require('draw')
16
+ .inherit({
17
+ font:"14px sans-serif",
18
+ textColor:'#000000',
19
+ textAlign:'',
20
+ text:''
21
+ })
22
+ .extend({
23
+
24
+ isVisible:function(){
25
+ return this.text.length != 0;
26
+ },
27
+
28
+ setText:function(t){
29
+ this.text = t;
30
+ return this;
31
+ },
32
+
33
+ draw:function(c){
34
+
35
+ c.font = this.font;
36
+ c.fillStyle = this.textColor;
37
+ c.fillText(this.text, -this.regX, -this.regY);
38
+
39
+ }
40
+
41
+ });
@@ -0,0 +1,63 @@
1
+ re.c('group')
2
+ .inherit({
3
+ posX:0,
4
+ posY:0
5
+ })
6
+ .extend({
7
+
8
+ group:function(){
9
+
10
+ for(var i=0; i<arguments.length; i++){
11
+ arguments[i].comp('group').group
12
+ }
13
+
14
+ },
15
+
16
+ ungroup:function(e){
17
+
18
+ },
19
+
20
+ /*
21
+ Overwrite old screen functions
22
+ */
23
+ getScreenX:function(){
24
+ var x = this.posX;
25
+ if(this.group) x += this.group.posX;
26
+ if(this.screen) x += this.screen.posX;
27
+ return x;
28
+ },
29
+
30
+ getScreenY:function(){
31
+ var y = this.posY;
32
+ if(this.group) y += this.group.posY;
33
+ if(this.screen) y += this.screen.posY;
34
+ return y;
35
+ },
36
+
37
+ /*group:null,*/
38
+
39
+ getGroupX:function(){
40
+ var x = this.posX;
41
+ if(this.group){
42
+ x += this.group.posX;
43
+ }
44
+ return x;
45
+ },
46
+
47
+ getGroupY:function(){
48
+ var y = this.posY;
49
+ if(this.group){
50
+ y += this.group.posY;
51
+ }
52
+ return y;
53
+ },
54
+
55
+ setGroupX:function(x){
56
+
57
+ },
58
+
59
+ setGroupY:function(y){
60
+
61
+ }
62
+
63
+ });