entityjs 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/lib/entityjs/config.rb +4 -4
- data/lib/entityjs/dirc.rb +2 -2
- data/lib/entityjs/page.rb +7 -1
- data/lib/entityjs/version.rb +1 -1
- data/public/qunit/qunit.entity.js +27 -12
- data/spec/javascripts/src/core/comp_spec.js +11 -0
- data/spec/javascripts/src/core/entity_spec.js +88 -5
- data/spec/javascripts/src/core/query_spec.js +196 -15
- data/spec/javascripts/src/cycle/drawlist_spec.js +36 -0
- data/spec/javascripts/src/cycle/tween_spec.js +1 -1
- data/spec/javascripts/src/cycle/wait_spec.js +31 -0
- data/spec/javascripts/src/{cycle → display}/draw_spec.js +25 -9
- data/spec/javascripts/src/display/sprite_spec.js +18 -0
- data/spec/javascripts/src/display/text_spec.js +8 -0
- data/spec/javascripts/src/input/mouse_spec.js +24 -36
- data/spec/javascripts/src/math/bisect_spec.js +4 -4
- data/spec/javascripts/src/math/distance_spec.js +11 -0
- data/spec/javascripts/src/math/iso_spec.js +131 -0
- data/spec/javascripts/src/math/point_spec.js +3 -3
- data/spec/javascripts/src/{util → math}/random_spec.js +0 -0
- data/spec/javascripts/src/math/range_spec.js +9 -0
- data/spec/javascripts/src/math/tile_spec.js +22 -7
- data/spec/javascripts/src/pattern/automap_spec.js +2 -2
- data/spec/javascripts/src/pattern/flicker_spec.js +34 -22
- data/spec/javascripts/src/pattern/pathfind_spec.js +55 -0
- data/src/core/comp.js +16 -16
- data/src/core/entity.js +52 -51
- data/src/core/load.js +5 -5
- data/src/core/query.js +214 -74
- data/src/core/system.js +16 -6
- data/src/cycle/drawlist.js +79 -0
- data/src/cycle/tween.js +7 -20
- data/src/cycle/wait.js +10 -19
- data/src/{cycle → display}/draw.js +24 -34
- data/src/display/image.js +1 -1
- data/src/display/screen.js +3 -3
- data/src/display/sprite.js +3 -3
- data/src/display/text.js +3 -1
- data/src/input/mouse.js +35 -12
- data/src/math/bisect.js +11 -10
- data/src/math/distance.js +7 -0
- data/src/math/iso.js +147 -0
- data/src/math/point.js +1 -5
- data/src/math/random.js +21 -0
- data/src/math/range.js +14 -0
- data/src/math/tile.js +40 -27
- data/src/pattern/automap.js +12 -11
- data/src/pattern/flicker.js +87 -135
- data/src/pattern/pathfind.js +168 -0
- data/src/pattern/timestep.js +4 -1
- data/src/util/polyfill.js +1 -1
- data/templates/isometric/assets/images/isotiles.png +0 -0
- data/templates/isometric/config.yml +22 -0
- data/templates/isometric/readme.txt +79 -0
- data/templates/isometric/scripts/displays/cursor.js +34 -0
- data/templates/isometric/scripts/displays/isoimage.js +32 -0
- data/templates/isometric/scripts/init.js +7 -0
- data/templates/isometric/scripts/levels/level.js +55 -0
- data/templates/isometric/scripts/levels/level1.js +11 -0
- data/templates/isometric/scripts/scenes/home.js +10 -0
- data/templates/isometric/scripts/scenes/load.js +11 -0
- data/templates/isometric/tests/scenes/load_test.js +15 -0
- metadata +42 -21
- data/src/net/socket.js +0 -52
- data/src/util/random.js +0 -24
@@ -0,0 +1,168 @@
|
|
1
|
+
/*
|
2
|
+
The pathfind comp finds a path towards a target position. The .search() method will return
|
3
|
+
an int array describing the movements to the target position.
|
4
|
+
|
5
|
+
searchNodes() and checkNode() can be overwritten.
|
6
|
+
|
7
|
+
//example
|
8
|
+
|
9
|
+
//1 is unwalkable
|
10
|
+
var map =
|
11
|
+
[
|
12
|
+
[0,0,0,1],
|
13
|
+
[0,1,0,0]
|
14
|
+
]
|
15
|
+
|
16
|
+
//automap is helpful for two-dim arrays
|
17
|
+
var level = re.e('automap').automap(map);
|
18
|
+
|
19
|
+
var path = re.e('pathfind')
|
20
|
+
.attr({
|
21
|
+
//this is checked for every tile. Returning false will skip it, making the tile unwalkable.
|
22
|
+
checkNode:function(x, y, parentX, parentY){
|
23
|
+
return level.within(x, y) && level.automap(x, y) == 0;
|
24
|
+
}
|
25
|
+
});
|
26
|
+
|
27
|
+
//search
|
28
|
+
var start = {x:0, y:0};
|
29
|
+
var end = {x:2, y:1};
|
30
|
+
|
31
|
+
//also called on every tile exactly like checkNode.
|
32
|
+
//this can be used for custom spcific pathfinds
|
33
|
+
var onCheck = function(x, y, parentX, parentY){
|
34
|
+
return true;
|
35
|
+
}
|
36
|
+
|
37
|
+
//called when a tile is accepted into path
|
38
|
+
var onTile = function(x, y, parentX, parentY, cost){
|
39
|
+
|
40
|
+
}
|
41
|
+
|
42
|
+
var ints = path.pathfind(start.x, start.y, end.x, end.y, onCheck, onTile);
|
43
|
+
|
44
|
+
//will return a path of ints like so..
|
45
|
+
// [x3, y3, x2, y2, x1, y1]
|
46
|
+
|
47
|
+
while(ints.length){
|
48
|
+
var y = ints.pop();
|
49
|
+
var x = ints.pop();
|
50
|
+
|
51
|
+
//move unit to x,y, etc..
|
52
|
+
|
53
|
+
}
|
54
|
+
|
55
|
+
*/
|
56
|
+
re.pathfind = re.c('pathfind')
|
57
|
+
.statics({
|
58
|
+
search:function(){
|
59
|
+
var p = re.e('pathfind');
|
60
|
+
var path = p.pathfind.apply(p, arguments);
|
61
|
+
p.dispose();
|
62
|
+
return path;
|
63
|
+
}
|
64
|
+
})
|
65
|
+
.defines({
|
66
|
+
|
67
|
+
pathfind_max:100,
|
68
|
+
|
69
|
+
pathfind:function(x, y, targetX, targetY, onCheck, onTile){
|
70
|
+
this.targetX = targetX;
|
71
|
+
this.targetY = targetY;
|
72
|
+
|
73
|
+
this.onCheck = onCheck;
|
74
|
+
this.onTile = onTile;
|
75
|
+
|
76
|
+
this.visit = {};
|
77
|
+
this.nodes = [];
|
78
|
+
|
79
|
+
this.addNode(x, y, -1, -1);
|
80
|
+
|
81
|
+
var n, count = 0;
|
82
|
+
|
83
|
+
while(this.nodes.length){
|
84
|
+
n = this.nodes.shift();
|
85
|
+
|
86
|
+
if(n.x == this.targetX && n.y == this.targetY){
|
87
|
+
return this.makePath(n);
|
88
|
+
} else {
|
89
|
+
|
90
|
+
this.searchNodes(n.x, n.y, n.px, n.py);
|
91
|
+
|
92
|
+
if(++count >= this.pathfind_max){
|
93
|
+
//limit reached
|
94
|
+
return null;
|
95
|
+
}
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
}
|
100
|
+
|
101
|
+
return null;
|
102
|
+
},
|
103
|
+
|
104
|
+
searchNodes:function(x, y){
|
105
|
+
this.addNode(x+1, y, x, y);
|
106
|
+
this.addNode(x-1, y, x, y);
|
107
|
+
this.addNode(x, y+1, x, y);
|
108
|
+
this.addNode(x, y-1, x, y);
|
109
|
+
},
|
110
|
+
|
111
|
+
checkNode:function(){
|
112
|
+
return true;
|
113
|
+
},
|
114
|
+
|
115
|
+
makePath:function(node){
|
116
|
+
var path = [], num=0;
|
117
|
+
|
118
|
+
do{
|
119
|
+
//starts at target and moves backwards to initial position
|
120
|
+
|
121
|
+
path[num++] = node.x;
|
122
|
+
path[num++] = node.y;
|
123
|
+
|
124
|
+
node = this.nodes[node.px+'_'+node.py];
|
125
|
+
|
126
|
+
} while(node && node.px != -1);
|
127
|
+
|
128
|
+
return path;
|
129
|
+
},
|
130
|
+
|
131
|
+
addNode:function(x, y, px, py){
|
132
|
+
|
133
|
+
if(!this.checkNode(x, y, px, py) || (this.onCheck && !this.onCheck(x, y, px, py))){
|
134
|
+
return false;
|
135
|
+
}
|
136
|
+
|
137
|
+
var name = x+'_'+y;
|
138
|
+
|
139
|
+
var cost = re.distance(x, y, this.targetX, this.targetY);
|
140
|
+
|
141
|
+
if(!this.nodes[name] || this.nodes[name].cost > cost){
|
142
|
+
|
143
|
+
var n = this.nodes[name] = {x:x, y:y, cost:cost, px:px, py:py};
|
144
|
+
|
145
|
+
var placed = false;
|
146
|
+
//enter in better cost nodes
|
147
|
+
for(var i=0, l = this.nodes.length; i<l; i++){
|
148
|
+
if(cost < this.nodes[i].cost){
|
149
|
+
this.nodes.splice(i, 0, n);
|
150
|
+
placed = true;
|
151
|
+
break;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
//just push it
|
156
|
+
if(!placed){
|
157
|
+
this.nodes.push(n);
|
158
|
+
}
|
159
|
+
|
160
|
+
//hook in methods
|
161
|
+
if(this.onTile) this.onTile(x, y, px, py, cost);
|
162
|
+
|
163
|
+
return true;
|
164
|
+
}
|
165
|
+
|
166
|
+
}
|
167
|
+
|
168
|
+
});
|
data/src/pattern/timestep.js
CHANGED
@@ -21,9 +21,12 @@ re.c('timestep')
|
|
21
21
|
|
22
22
|
while(this.stepProgress >= this.stepSize){
|
23
23
|
|
24
|
-
callback.call(
|
24
|
+
callback.call(context || this);
|
25
25
|
|
26
26
|
this.stepProgress -= this.stepSize;
|
27
|
+
|
28
|
+
//break if stepSize is zero
|
29
|
+
if(!this.stepSize) break;
|
27
30
|
}
|
28
31
|
|
29
32
|
}
|
data/src/util/polyfill.js
CHANGED
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Configure your game settings
|
2
|
+
|
3
|
+
width: 500
|
4
|
+
height: 400
|
5
|
+
canvas-id: game-canvas
|
6
|
+
|
7
|
+
#files to ignore in /scripts
|
8
|
+
scripts-ignore:
|
9
|
+
|
10
|
+
#specify files to be loaded first in /scripts
|
11
|
+
order:
|
12
|
+
|
13
|
+
#components to ignore in the entityjs source
|
14
|
+
#reduce file size by ignoring unused components
|
15
|
+
entity-ignore:
|
16
|
+
socket
|
17
|
+
wait
|
18
|
+
group
|
19
|
+
|
20
|
+
#ignore tests in /tests
|
21
|
+
tests-ignore:
|
22
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
------------- EntityJS Gem ----------------------
|
2
|
+
|
3
|
+
The EntityJS Gem lets you quickly create HTML5 javascript games.
|
4
|
+
|
5
|
+
# Directory Structure
|
6
|
+
|
7
|
+
## /assets
|
8
|
+
Contains all sounds, images and data files. Place all sounds in the sounds directory
|
9
|
+
and all the images in the images directory. These directories will be looked at
|
10
|
+
and an asset array will be created for easy asset loading (see scripts/scenes/load.js)
|
11
|
+
|
12
|
+
Creating any other directory or placing files in the levels directory will be seen
|
13
|
+
as data files and will be read and automatically put in js files.
|
14
|
+
|
15
|
+
For example, if I have a directory like /assets/animations/monster.json.
|
16
|
+
|
17
|
+
The file will automatically be read upon calling 'entityjs refresh' and will be turned into this:
|
18
|
+
|
19
|
+
re.e('monster.json animation')
|
20
|
+
.attr(**Animation JSON here**);
|
21
|
+
|
22
|
+
Which means you can edit files in different programs and not worry about copying and pasting
|
23
|
+
the contents. Just run entityjs refresh.
|
24
|
+
|
25
|
+
At the moment JSON, XML and TMX is supported but in the future, YAML, and CSV will be supported.
|
26
|
+
TMX is a special XML format for a tile map editor called tiled.
|
27
|
+
|
28
|
+
## /builds
|
29
|
+
|
30
|
+
Contains assets and minified code for the game.
|
31
|
+
|
32
|
+
## /scripts
|
33
|
+
|
34
|
+
Contains javascripts for the game.
|
35
|
+
|
36
|
+
## /tests
|
37
|
+
|
38
|
+
Contains tests for the game. It is good practice to keep this structured exactly the same as the scripts
|
39
|
+
directory.
|
40
|
+
|
41
|
+
## config.yml
|
42
|
+
|
43
|
+
A configuration file in yaml. This can be edited in any text editor.
|
44
|
+
|
45
|
+
## readme.txt
|
46
|
+
|
47
|
+
Good practice to make one for every game to help other people.
|
48
|
+
|
49
|
+
# Commands
|
50
|
+
|
51
|
+
## create a new entityjs game
|
52
|
+
entityjs new [project_name]
|
53
|
+
|
54
|
+
- example
|
55
|
+
entityjs new alien_shooter
|
56
|
+
|
57
|
+
- create game with arrow_keys template
|
58
|
+
entityjs new alien_shooter alien arrow_keys
|
59
|
+
|
60
|
+
## create a new component
|
61
|
+
entityjs comp [component_name]
|
62
|
+
|
63
|
+
- example
|
64
|
+
entityjs comp hero
|
65
|
+
|
66
|
+
## build game
|
67
|
+
entityjs build
|
68
|
+
|
69
|
+
Exports game in builds directory
|
70
|
+
|
71
|
+
## build game with custom name
|
72
|
+
entityjs build release1
|
73
|
+
|
74
|
+
## Run server
|
75
|
+
entityjs server
|
76
|
+
or
|
77
|
+
entityjs s
|
78
|
+
|
79
|
+
Navigate to localhost:2345 to play the game.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
re.c('cursor')
|
2
|
+
.requires('isoimage mouse')
|
3
|
+
.defines({
|
4
|
+
|
5
|
+
screenable:true,
|
6
|
+
frameX:2,
|
7
|
+
|
8
|
+
click:function(x, y){
|
9
|
+
var iso = re.iso.toIso(x, y);
|
10
|
+
|
11
|
+
console.log(iso.isoX, iso.isoY);
|
12
|
+
|
13
|
+
var box = re('#box')[0];
|
14
|
+
|
15
|
+
box.place(iso.isoX, iso.isoY);
|
16
|
+
|
17
|
+
re.draw.sort();
|
18
|
+
},
|
19
|
+
|
20
|
+
move:function(x, y){
|
21
|
+
var iso = re.iso.toIso(x, y);
|
22
|
+
|
23
|
+
this.place(iso.isoX, iso.isoY);
|
24
|
+
|
25
|
+
re.draw.sort();
|
26
|
+
}
|
27
|
+
|
28
|
+
})
|
29
|
+
.init(function(){
|
30
|
+
this.on({
|
31
|
+
'click':this.click,
|
32
|
+
'mousemove':this.move
|
33
|
+
});
|
34
|
+
});
|
@@ -0,0 +1,32 @@
|
|
1
|
+
re.c('isoimage')
|
2
|
+
.requires('iso sprite isotiles.png')
|
3
|
+
.defines({
|
4
|
+
|
5
|
+
sizeX:51,
|
6
|
+
layer:0,
|
7
|
+
|
8
|
+
isoHeight:function(){
|
9
|
+
//high tile
|
10
|
+
if(this.frameX == 1){
|
11
|
+
return 10;
|
12
|
+
}
|
13
|
+
return 0;
|
14
|
+
},
|
15
|
+
|
16
|
+
place:function(x, y){
|
17
|
+
//find the tile height
|
18
|
+
var height = re.currentLevel.tileHeight(x, y);
|
19
|
+
|
20
|
+
this.iso(x, y, height / re.iso.sizeZ);
|
21
|
+
|
22
|
+
},
|
23
|
+
|
24
|
+
depth:function(){
|
25
|
+
return this.posY + this.layer + this.posZ;
|
26
|
+
}
|
27
|
+
|
28
|
+
})
|
29
|
+
.init(function(){
|
30
|
+
//pushes tiles up so they are leveled
|
31
|
+
this.regY = this.sizeY - re.iso.sizeY;
|
32
|
+
});
|
@@ -0,0 +1,55 @@
|
|
1
|
+
re.c('level')
|
2
|
+
.requires('automap')
|
3
|
+
.defines({
|
4
|
+
|
5
|
+
setup:function(){
|
6
|
+
|
7
|
+
re.iso.sizeX = 25;
|
8
|
+
re.iso.sizeY = 25;
|
9
|
+
re.iso.sizeZ = 25;
|
10
|
+
|
11
|
+
//setups layers for objects on the same tile
|
12
|
+
re.draw.cursor = 1;
|
13
|
+
re.draw.box = 2;
|
14
|
+
|
15
|
+
for(var y=0; y<this.map.length; y++){
|
16
|
+
for(var x=0; x<this.map[0].length; x++){
|
17
|
+
|
18
|
+
var e = re.e('isoimage');
|
19
|
+
|
20
|
+
var tile = this.map[y][x];
|
21
|
+
|
22
|
+
if(tile == 1){
|
23
|
+
e.frame(1);
|
24
|
+
e.sizeY = 35;
|
25
|
+
}
|
26
|
+
|
27
|
+
e.iso(x, y);
|
28
|
+
|
29
|
+
//place in map
|
30
|
+
this.automap(x, y, e);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
this.cursor = re.e('cursor')
|
35
|
+
.attr('layer', re.draw.cursor);
|
36
|
+
|
37
|
+
this.box = re.e('isoimage')
|
38
|
+
.attr({
|
39
|
+
id:'box',
|
40
|
+
frameX:3,
|
41
|
+
layer:re.draw.box,
|
42
|
+
place:[0,0]
|
43
|
+
});
|
44
|
+
|
45
|
+
},
|
46
|
+
|
47
|
+
tileHeight:function(x, y){
|
48
|
+
var tile = this.automap(x, y);
|
49
|
+
if(!tile){
|
50
|
+
return 0;
|
51
|
+
}
|
52
|
+
return tile.isoHeight();
|
53
|
+
}
|
54
|
+
|
55
|
+
})
|