entityjs 0.3.2 → 0.4.0

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 (66) hide show
  1. data/.gitignore +1 -1
  2. data/lib/entityjs/config.rb +4 -4
  3. data/lib/entityjs/dirc.rb +2 -2
  4. data/lib/entityjs/page.rb +7 -1
  5. data/lib/entityjs/version.rb +1 -1
  6. data/public/qunit/qunit.entity.js +27 -12
  7. data/spec/javascripts/src/core/comp_spec.js +11 -0
  8. data/spec/javascripts/src/core/entity_spec.js +88 -5
  9. data/spec/javascripts/src/core/query_spec.js +196 -15
  10. data/spec/javascripts/src/cycle/drawlist_spec.js +36 -0
  11. data/spec/javascripts/src/cycle/tween_spec.js +1 -1
  12. data/spec/javascripts/src/cycle/wait_spec.js +31 -0
  13. data/spec/javascripts/src/{cycle → display}/draw_spec.js +25 -9
  14. data/spec/javascripts/src/display/sprite_spec.js +18 -0
  15. data/spec/javascripts/src/display/text_spec.js +8 -0
  16. data/spec/javascripts/src/input/mouse_spec.js +24 -36
  17. data/spec/javascripts/src/math/bisect_spec.js +4 -4
  18. data/spec/javascripts/src/math/distance_spec.js +11 -0
  19. data/spec/javascripts/src/math/iso_spec.js +131 -0
  20. data/spec/javascripts/src/math/point_spec.js +3 -3
  21. data/spec/javascripts/src/{util → math}/random_spec.js +0 -0
  22. data/spec/javascripts/src/math/range_spec.js +9 -0
  23. data/spec/javascripts/src/math/tile_spec.js +22 -7
  24. data/spec/javascripts/src/pattern/automap_spec.js +2 -2
  25. data/spec/javascripts/src/pattern/flicker_spec.js +34 -22
  26. data/spec/javascripts/src/pattern/pathfind_spec.js +55 -0
  27. data/src/core/comp.js +16 -16
  28. data/src/core/entity.js +52 -51
  29. data/src/core/load.js +5 -5
  30. data/src/core/query.js +214 -74
  31. data/src/core/system.js +16 -6
  32. data/src/cycle/drawlist.js +79 -0
  33. data/src/cycle/tween.js +7 -20
  34. data/src/cycle/wait.js +10 -19
  35. data/src/{cycle → display}/draw.js +24 -34
  36. data/src/display/image.js +1 -1
  37. data/src/display/screen.js +3 -3
  38. data/src/display/sprite.js +3 -3
  39. data/src/display/text.js +3 -1
  40. data/src/input/mouse.js +35 -12
  41. data/src/math/bisect.js +11 -10
  42. data/src/math/distance.js +7 -0
  43. data/src/math/iso.js +147 -0
  44. data/src/math/point.js +1 -5
  45. data/src/math/random.js +21 -0
  46. data/src/math/range.js +14 -0
  47. data/src/math/tile.js +40 -27
  48. data/src/pattern/automap.js +12 -11
  49. data/src/pattern/flicker.js +87 -135
  50. data/src/pattern/pathfind.js +168 -0
  51. data/src/pattern/timestep.js +4 -1
  52. data/src/util/polyfill.js +1 -1
  53. data/templates/isometric/assets/images/isotiles.png +0 -0
  54. data/templates/isometric/config.yml +22 -0
  55. data/templates/isometric/readme.txt +79 -0
  56. data/templates/isometric/scripts/displays/cursor.js +34 -0
  57. data/templates/isometric/scripts/displays/isoimage.js +32 -0
  58. data/templates/isometric/scripts/init.js +7 -0
  59. data/templates/isometric/scripts/levels/level.js +55 -0
  60. data/templates/isometric/scripts/levels/level1.js +11 -0
  61. data/templates/isometric/scripts/scenes/home.js +10 -0
  62. data/templates/isometric/scripts/scenes/load.js +11 -0
  63. data/templates/isometric/tests/scenes/load_test.js +15 -0
  64. metadata +42 -21
  65. data/src/net/socket.js +0 -52
  66. data/src/util/random.js +0 -24
@@ -0,0 +1,7 @@
1
+ re.distance = function(x1, y1, x2, y2) {
2
+ var kx, ky;
3
+ kx = x2 - x1;
4
+ ky = y2 - y1;
5
+
6
+ return Math.sqrt(kx*kx + ky*ky);
7
+ };
data/src/math/iso.js ADDED
@@ -0,0 +1,147 @@
1
+ re.iso = re.c('iso')
2
+ .statics({
3
+ sizeX:30,
4
+ sizeY:30,
5
+ sizeZ:30,
6
+
7
+ /*
8
+ Converts an x position into the closest iso x position.
9
+ */
10
+ toPosX:function(x, y){
11
+ var isox = this.toIsoX(x, y);
12
+ var isoy = this.toIsoY(x, y);
13
+
14
+ return (isox - isoy) * this.sizeX;
15
+ },
16
+
17
+ toPosY:function(x, y){
18
+ var isox = this.toIsoX(x, y);
19
+ var isoy = this.toIsoY(x, y);
20
+
21
+ return (isox + isoy) * this.sizeY * 0.5;
22
+ },
23
+
24
+ toPos:function(x, y){
25
+ if(re.is(x,'object')){
26
+ y = x.posY || x.y;
27
+ x = x.posX || x.x;
28
+ }
29
+
30
+ return {posX:this.toPosX(x, y), posY:this.toPosY(x, y)};
31
+ },
32
+
33
+ toIsoX:function(x, y){
34
+ var ym = (2*y - x) * 0.5;
35
+ var xm = x + ym;
36
+
37
+ return Math.round(xm / this.sizeX)-1;
38
+ },
39
+
40
+ toIsoY:function(x, y){
41
+ var ym = (2*y - x) * 0.5;
42
+
43
+ return Math.round(ym / this.sizeY);
44
+ },
45
+
46
+ toIso:function(x, y){
47
+ if(re.is(x, 'object')){
48
+ y = x.posY || x.y;
49
+ x = x.posX || x.x;
50
+ }
51
+ return {isoX:this.toIsoX(x,y), isoY:this.toIsoY(x, y)};
52
+ }
53
+
54
+ })
55
+ .defaults({
56
+ posX:0,
57
+ posY:0,
58
+ posZ:0
59
+ })
60
+ .defines({
61
+
62
+ /*
63
+ Moves the iso entity to the given isometric position.
64
+
65
+ examples:
66
+
67
+ e.iso(1, 0, 0);
68
+
69
+ e.iso(otherIso);
70
+
71
+ e.iso({x:1, y:1, z:2});
72
+ */
73
+ iso:function(x, y, z){
74
+ if(re.is(x,'object')){
75
+ z = x.z
76
+ if(re.is(x.posZ)){
77
+ z = x.posZ / re.iso.sizeZ;
78
+ }
79
+ y = x.y;
80
+
81
+ //copy attributes
82
+ if(re.is(x.posX) && re.is(x.posY)){
83
+ this.posX = x.posX;
84
+ this.posY = x.posY;
85
+ if(x.posZ){
86
+ this.posZ = x.posZ;
87
+ }
88
+ return this;
89
+ }
90
+
91
+ x = x.x;
92
+
93
+ }
94
+
95
+ //convert to screen space
96
+ x = (re.is(x)) ? x : this.isoX();
97
+ x *= re.iso.sizeX;
98
+
99
+ //posY handles a lot of transformations, its safest to recalculate it
100
+ y = (re.is(y)) ? y : this.isoY();
101
+ y *= re.iso.sizeY;
102
+
103
+ z = (re.is(z)) ? z : this.isoZ();
104
+ z *= re.iso.sizeZ;
105
+
106
+ //all values should be in screen space from here
107
+ this.posX = x - y;
108
+ this.posY = (x + y) * 0.5 - z;
109
+ this.posZ = z;
110
+
111
+ return this;
112
+ },
113
+
114
+ isoX:function(value){
115
+ if(re.is(value)){
116
+
117
+ return this.iso(value);
118
+ }
119
+
120
+ return (this.posX + (2*(this.posY+this.posZ) - this.posX) * 0.5) / re.iso.sizeX;
121
+ },
122
+
123
+ isoY:function(value){
124
+ if(re.is(value)){
125
+
126
+ return this.iso({y:value});
127
+ }
128
+
129
+ return ((2*(this.posY+this.posZ) - this.posX) * 0.5) / re.iso.sizeY;
130
+ },
131
+
132
+ isoZ:function(value){
133
+ if(re.is(value)){
134
+
135
+ return this.iso({z:value});
136
+ }
137
+
138
+ return this.posZ / re.iso.sizeZ;
139
+ },
140
+
141
+ //returns true if the current iso position is directly on top of a tile.
142
+ onIso:function(){
143
+ var total = this.isoX() + this.isoY() + this.isoZ();
144
+ return (total|0) == total;
145
+ }
146
+
147
+ });
data/src/math/point.js CHANGED
@@ -30,11 +30,7 @@ re.c('point')
30
30
  y = x.posY || x.y;
31
31
  x = x.posX || x.x;
32
32
  }
33
- var kx, ky;
34
- kx = x - this.posX;
35
- ky = y - this.posY;
36
-
37
- return Math.sqrt(kx*kx + ky*ky) + 0.5 | 0;
33
+ return re.distance(this.posX, this.posY, x, y);
38
34
  }
39
35
 
40
36
  });
@@ -0,0 +1,21 @@
1
+ /*
2
+ re.random() // 0 - 1 floats
3
+ re.random(10) // 0 - 9 integer
4
+ re.random(10, 30) // 10 - 30 integer
5
+ re.random([1, 10, 40]) // 1 or 10 or 40
6
+
7
+ */
8
+ re.random = function(max, min){
9
+ var r = Math.random();
10
+ if(re.is(max, 'array')){
11
+ return max[r * max.length | 0];
12
+ }
13
+ switch(arguments.length){
14
+ case 0:
15
+ return r;
16
+ case 1:
17
+ return r * max | 0;
18
+ case 2:
19
+ return r * (max - min + 1) + min | 0;
20
+ }
21
+ };
data/src/math/range.js ADDED
@@ -0,0 +1,14 @@
1
+ /*
2
+ Returns an array of integers within the given range.
3
+
4
+ re.range(0, 2); //[0, 1]
5
+ re.range(2, 10, 2); //[2, 4, 6, 8]
6
+
7
+ */
8
+ re.range = function(start, finish, step){
9
+ var a = [];
10
+ for(var i=start||0; i<finish; i+=step||1){
11
+ a.push(i);
12
+ }
13
+ return a;
14
+ };
data/src/math/tile.js CHANGED
@@ -39,44 +39,56 @@ re.e('tile sprite tiles.png', map.length * map[0].length)
39
39
  @warning moving to negative tiles will cause rounding issues.
40
40
  Its recommended you avoid negative tile values
41
41
 
42
+ TODO: remove size vars from entity. Use global size instead
42
43
  */
43
44
  re.tile = re.c('tile')
44
45
  .statics({
45
46
  sizeX:40,
46
47
  sizeY:40,
47
48
 
48
- toX:function(x, size){
49
- size = size || this.sizeX;
50
- return this.toTileX(x, size) * size;
49
+ toPosX:function(x){
50
+ return this.toTileX(x) * this.sizeX;
51
51
  },
52
52
 
53
- toY:function(y, size){
54
- size = size || this.sizeY;
55
- return this.toTileY(y, size) * size;
53
+ toPosY:function(y){
54
+ return this.toTileY(y) * this.sizeY;
55
+ },
56
+
57
+ toPos:function(x, y){
58
+ if(re.is(x,'object')){
59
+ y = x.posY || x.y;
60
+ x = x.posX || x.x;
61
+ }
62
+
63
+ return {posX:this.toPosX(x), posY:this.toPosY(y)};
56
64
  },
57
65
 
58
66
  //converts the given coordinate to a tile position
59
- toTileX:function(x, size){
60
- size = size || this.sizeX;
61
- return (x - size * 0.5) / size + 0.5 | 0
67
+ toTileX:function(x){
68
+ return (x - this.sizeX * 0.5) / this.sizeX + 0.5 | 0
62
69
  },
63
70
 
64
- toTileY:function(y, size){
65
- size = size || this.sizeY;
66
- return (y - size * 0.5) / size + 0.5 | 0
71
+ toTileY:function(y){
72
+ return (y - this.sizeY * 0.5) / this.sizeY + 0.5 | 0
73
+ },
74
+
75
+ toTile:function(x, y){
76
+ if(re.is(x,'object')){
77
+ y = x.posY || x.y;
78
+ x = x.posX || x.x;
79
+ }
80
+
81
+ return {tileX:this.toTileX(x), tileY:this.toTileY(y)};
67
82
  }
68
83
 
69
84
  })
70
85
  .defaults({
71
86
 
72
87
  posX:0,
73
- posY:0
88
+ posY:0,
89
+ regX:0,
90
+ regY:0
74
91
 
75
- })
76
- .init(function(){
77
- this.sizeX = re.tile.sizeX;
78
- this.sizeY = re.tile.sizeY;
79
-
80
92
  })
81
93
  .defines({
82
94
 
@@ -92,25 +104,26 @@ re.tile = re.c('tile')
92
104
  },
93
105
 
94
106
  tileX:function(v){
95
- var s = this.sizeX || re.tile.sizeX;
96
- var r = this.regX || 0;
97
107
  if(re.is(v)){
98
- this.posX = (v - r) * s;
108
+ this.posX = v * this.sizeX + 0.5 | 0;
99
109
  return this;
100
110
  }
101
111
 
102
- return (this.posX - r) / s + 0.5 | 0;
112
+ return this.posX / this.sizeX + 0.5 | 0;
103
113
  },
104
114
 
105
115
  tileY:function(v){
106
- var s = this.sizeX || re.tile.sizeY;
107
- var r = this.regY || 0;
108
116
  if(re.is(v)){
109
- this.posY = (v - r)* s;
117
+ this.posY = v* this.sizeY + 0.5 | 0;
110
118
  return this;
111
119
  }
112
120
 
113
- return (this.posY - r) / s + 0.5 | 0;
121
+ return this.posY / this.sizeY + 0.5 | 0;
114
122
  }
115
123
 
116
- });
124
+ })
125
+ .init(function(){
126
+ this.sizeX = re.tile.sizeX;
127
+ this.sizeY = re.tile.sizeY;
128
+
129
+ })
@@ -18,12 +18,12 @@ var level =
18
18
  [2,3,4,5,6,4]
19
19
  ]
20
20
 
21
- //value copy
21
+ //reference copy
22
22
  map.automap(level)
23
23
 
24
24
  map.automap(0, 1) // 1
25
25
 
26
- //reference copy
26
+ //value copy
27
27
  map.automap(level, true)
28
28
 
29
29
  map.map == level //true
@@ -45,6 +45,16 @@ re.c('automap')
45
45
  if(re.is(x, 'array')){
46
46
 
47
47
  if(y){
48
+
49
+ //deep copy
50
+ for(var y=0; y<x.length; y++){
51
+ for(var k=0; k<x[0].length; k++){
52
+ this.automap(k, y, x[y][k]);
53
+ }
54
+ }
55
+
56
+ } else {
57
+
48
58
  //non-deep copy
49
59
 
50
60
  this._automap = x;
@@ -56,15 +66,6 @@ re.c('automap')
56
66
  }
57
67
 
58
68
  this.lenY = x.length;
59
-
60
- } else {
61
-
62
- //deep copy
63
- for(var y=0; y<x.length; y++){
64
- for(var k=0; k<x[0].length; k++){
65
- this.automap(k, y, x[y][k]);
66
- }
67
- }
68
69
  }
69
70
 
70
71
  return this;
@@ -1,27 +1,45 @@
1
1
  /*
2
- The flicker component calls the implemented method and sends the given information over a period of time.
2
+ The flicker component calls the implemented flick method with the given array data over a period of time.
3
3
 
4
4
  This is most popular for sprite animation.
5
5
 
6
6
  It can also be used for graduatly writing text or flashing a drawing object.
7
+
8
+ re.c('health')
9
+ .requires('flicker')
10
+ .defines({
11
+
12
+ health:100,
13
+ flick:function(health){
14
+ this.health += health;
15
+ if(this.health >= 100){
16
+ //stops flicker
17
+ return false;
18
+ }
19
+ },
20
+
21
+ regen:function(){
22
+ //adds health over a duration of 30 seconds
23
+ this.flicker(30, [5, 5, 5, 5, 5, 5]);
24
+ }
25
+
26
+ });
27
+
28
+ var e = re.e('health').attr('health', 40);
29
+
30
+ //low on health, regenerate
31
+ e.regen();
32
+
7
33
  */
8
34
  re.c('flicker')
9
35
  .requires('update timestep')
10
36
  .interfaces('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
- .defines({
21
-
22
- flicker_stop:function(){
23
- var o = this.flicker_flickering;
24
- this.flicker_flickering = '';
37
+ .namespaces({
38
+ flickering:'',
39
+
40
+ stop:function(){
41
+ var o = this.flicker_id;
42
+ this.flicker_id = '';
25
43
 
26
44
  this.stepProgress = 0;
27
45
 
@@ -30,15 +48,12 @@ re.c('flicker')
30
48
  return this.trigger('flicker:finish', o);
31
49
  },
32
50
 
33
- flicker_update:function(t){
34
-
35
- this.timestep(t, function(){
36
- var c = this.flicker_reel;
37
-
51
+ change:function(){
52
+
38
53
  //check if over
39
- if(this.flicker_frame == this.flicker_reel.frames.length){
54
+ if(this.flicker_frame == this.flicker_frames.length){
40
55
 
41
- if(c.loops == -1 || --this.flicker_loops >= 1){
56
+ if(this.flicker_loops == -1 || --this.flicker_loops >= 1){
42
57
  //loop again
43
58
 
44
59
  this.flicker_frame = 0;
@@ -47,151 +62,88 @@ re.c('flicker')
47
62
  //done flickering
48
63
 
49
64
  this.flicker_stop();
50
-
51
- return;
65
+ return;
52
66
  }
53
67
  }
54
68
 
69
+ this.flicker_run();
70
+ },
71
+
72
+ run:function(){
73
+
74
+ var f = this.flicker_frame,
75
+ fs = this.flicker_frames,
76
+ l = this.flicker_loops,
77
+ val = fs[f];
78
+
79
+ var quit = this.flick(val, f, fs, l);
80
+
81
+ this.trigger('flicker:update', val, f, fs, l);
82
+
55
83
  //flick
56
- if(this.flick(c.frames[this.flicker_frame], this.flicker_flickering, this.flicker_loops) === false){
84
+ if(quit === false){
57
85
  //stop
58
86
  this.flicker();
59
87
  }
60
-
88
+
61
89
  this.flicker_frame++;
62
-
63
- });
64
-
65
- },
66
-
67
- addFlicker:function(id, loops, duration, frames){
68
-
69
- if(re.is(id, 'object')){
70
-
71
- for(var i in id){
72
-
73
- //copy formed array and insert
74
- var c = id[i].slice();
75
- //add key into array
76
- c.unshift(i);
77
-
78
- this.addFlicker.apply(this, c);
79
-
80
- }
81
-
82
- return this;
83
- }
84
-
85
- if(re.is(frames, 'string')) frames = frames.split(' ');
86
-
87
- //add
88
- this.flicker_reels[id] =
89
- {
90
- frames:frames,
91
- duration:duration,
92
- loops:loops
93
- };
94
-
95
- return this;
96
- },
97
-
98
- removeFlicker:function(id){
99
-
100
- if(re.is(id,'object')){
101
-
102
- for(var i in id){
103
-
104
- this.removeFlicker.call(this, id[i]);
105
- }
106
-
107
- return this;
108
- }
109
-
110
- //assuming this flicker isn't running
111
- delete this.flicker_reels[id];
112
-
113
- return this;
90
+ },
91
+
92
+ update:function(t){
93
+ this.timestep(t, this.flicker_change);
114
94
  },
115
95
 
96
+ })
97
+ .defines({
98
+
116
99
  /*
117
- The animate method either creates or plays an animation.
118
- Time is in milliseconds.
119
-
120
- //create sequence animation
121
- re('#player').flicker('die', 1, 200, [0, 1, 3, 3, 4, 3, 2, 1]);
122
-
123
- //play animation
124
- //can customize the animation for this call.
125
- re('#player').flicker('die', 0, 200);
126
-
127
- //stop flickering
128
- re('#player').flicker();
129
-
130
- //add multiple animations
131
- flicker({
132
- idle:[loops, duration, frames],
133
- ..
134
-
135
-
136
- });
137
-
100
+
101
+ loops defaults to 1
102
+ id default to true
103
+
138
104
  FUTURE:
139
105
  -allow backward animations
140
106
  -allow entry of an array of frames. So each counter will go to the next frame in the array
141
107
  */
142
- flicker:function(id, loops, duration, frames){
108
+ flicker:function(duration, frames, loops, id){
143
109
 
144
- if(!re.is(id) && this.flickering()){
110
+ //stop
111
+ if(!re.is(loops) && this.flickering()){
145
112
  //stop flickering
146
113
  return this.flicker_stop();
147
114
  }
148
115
 
149
- if(id == this.flicker_flickering) return;
150
-
151
- if(!this.flicker_reels[id]){
152
- return this;
153
- }
154
-
155
- //defaults
156
-
157
- //startX = loops, endX = duration in seconds
158
- //if startX equals 0, animation loops forever
159
-
160
- var r = this.flicker_reels[id];
161
-
162
- //create new reel based on custom attributes
163
- var c = this.flicker_reel;
164
- //copy from saved animation or newly given
165
- c.loops = (isNaN(loops))? r.loops : loops;
166
- c.duration = (isNaN(duration))? r.duration : duration;
167
-
168
116
  //convert to seconds
169
- if(c.duration >= 30){
170
- c.duration /= 1000;
117
+ if(duration >= 100){
118
+ duration /= 1000;
171
119
  }
172
120
 
173
- c.frames = (re.is(frames,'object'))? frames : r.frames;
174
-
121
+ this.flicker_duration = duration || 1;
122
+
123
+ frames = (re.is(frames,'array')) ? frames : [frames];
124
+
175
125
  //setup counter for loops
176
- this.flicker_loops = c.loops;
126
+ this.flicker_loops = loops || 1;
177
127
 
178
128
  this.stepProgress = 0;
179
- this.stepSize = c.duration / c.frames.length;
129
+ this.stepSize = (duration / frames.length) / re.sys.second;
180
130
 
181
- //save old frames for upon completion
182
-
131
+ this.flicker_frames = frames;
183
132
  this.flicker_frame = 0;
184
133
 
185
- //update frame then run
186
- this.flick(c.frames[this.flicker_frame++]);
187
-
188
134
  if(!this.flickering()){
189
135
  this.on('update', this.flicker_update);
190
136
  }
191
137
 
192
- this.flicker_flickering = id;
138
+ //sets flicker status
139
+ this.flicker_id = id || true;
140
+
141
+ this.trigger('flicker:start');
142
+
143
+ //update frame then run
144
+ this.flicker_run();
193
145
 
194
- return this.trigger('flicker:start');
146
+ return this;
195
147
  },
196
148
 
197
149
  /*
@@ -202,10 +154,10 @@ re.c('flicker')
202
154
  */
203
155
  flickering:function(id){
204
156
  if(id){
205
- return this.flicker_flickering == id;
157
+ return this.flicker_id == id;
206
158
  }
207
159
 
208
- return this.flicker_flickering;
160
+ return this.flicker_id;
209
161
  }
210
162
 
211
163
  });