entityjs 0.4.1 → 0.4.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 (111) hide show
  1. data/.gitignore +1 -0
  2. data/bin/entityjs +1 -1
  3. data/entityjs.gemspec +3 -2
  4. data/lib/entityjs.rb +13 -1
  5. data/lib/entityjs/command.rb +22 -16
  6. data/lib/entityjs/commands/build.rb +96 -48
  7. data/lib/entityjs/commands/eunit.rb +1 -1
  8. data/lib/entityjs/commands/html.rb +31 -0
  9. data/lib/entityjs/commands/min.rb +37 -0
  10. data/lib/entityjs/commands/new.rb +3 -0
  11. data/lib/entityjs/commands/server.rb +9 -3
  12. data/lib/entityjs/config.rb +163 -59
  13. data/lib/entityjs/dirc.rb +28 -0
  14. data/lib/entityjs/page.rb +73 -34
  15. data/lib/entityjs/version.rb +1 -1
  16. data/public/favicon.ico +0 -0
  17. data/public/play.html +33 -28
  18. data/public/qunit/qunit.entity.js +56 -6
  19. data/public/qunit/qunit.input.js +5 -5
  20. data/public/test.html +49 -0
  21. data/spec/javascripts/src/core/comp_spec.js +17 -6
  22. data/spec/javascripts/src/core/entity_spec.js +4 -5
  23. data/spec/javascripts/src/core/query_spec.js +25 -0
  24. data/spec/javascripts/src/core/re_spec.js +3 -3
  25. data/spec/javascripts/src/cycle/update_spec.js +8 -8
  26. data/spec/javascripts/src/display/align_spec.js +2 -2
  27. data/spec/javascripts/src/display/el_spec.js +17 -0
  28. data/spec/javascripts/src/input/keyboard_spec.js +4 -4
  29. data/spec/javascripts/src/input/mouse_spec.js +8 -7
  30. data/spec/javascripts/src/math/random_spec.js +8 -0
  31. data/spec/javascripts/src/util/clone_spec.js +20 -0
  32. data/spec/lib/entityjs/commands/build_spec.rb +3 -8
  33. data/spec/lib/entityjs/commands/html_spec.rb +27 -0
  34. data/spec/lib/entityjs/commands/min_spec.rb +30 -0
  35. data/spec/lib/entityjs/config_spec.rb +6 -0
  36. data/spec/lib/entityjs/page_spec.rb +4 -4
  37. data/src/core/comp.js +87 -31
  38. data/src/core/entity.js +38 -43
  39. data/src/core/load.js +2 -8
  40. data/src/core/query.js +17 -5
  41. data/src/core/re.js +1 -1
  42. data/src/core/system.js +8 -11
  43. data/src/cycle/drawlist.js +11 -11
  44. data/src/cycle/update.js +5 -5
  45. data/src/display/align.js +10 -3
  46. data/src/display/animate.js +26 -12
  47. data/src/display/el.js +99 -0
  48. data/src/input/keyboard.js +5 -5
  49. data/src/input/mouse.js +16 -11
  50. data/src/math/bisect.js +1 -1
  51. data/src/math/force.js +4 -4
  52. data/src/math/hitmap.js +2 -1
  53. data/src/math/iso.js +1 -1
  54. data/src/math/random.js +17 -2
  55. data/src/math/tile.js +1 -1
  56. data/src/media/sound.js +1 -1
  57. data/src/pattern/pathfind.js +2 -4
  58. data/src/save/storage.js +1 -1
  59. data/src/util/clone.js +12 -0
  60. data/src/util/scene.js +21 -16
  61. data/templates/circle/game.json +16 -0
  62. data/templates/circle/scripts/displays/circle.js +40 -0
  63. data/templates/circle/scripts/scenes/home.js +8 -17
  64. data/templates/circle/tests/scenes/home_test.js +3 -11
  65. data/templates/dom/game.json +6 -0
  66. data/templates/dom/scripts/els/btn.js +5 -0
  67. data/templates/dom/scripts/els/contain.js +5 -0
  68. data/templates/dom/scripts/els/header.js +5 -0
  69. data/templates/{animation → dom}/scripts/init.js +0 -0
  70. data/templates/dom/scripts/scenes/home.js +22 -0
  71. data/templates/{animation → dom}/scripts/scenes/load.js +0 -0
  72. data/templates/dom/tests/scenes/home_test.js +9 -0
  73. data/templates/{animation → dom}/tests/scenes/load_test.js +0 -0
  74. data/templates/isometric/game.json +16 -0
  75. data/templates/platform/game.json +18 -0
  76. data/templates/platform/scripts/displays/hero.js +1 -1
  77. data/templates/platform/scripts/items/coin.js +1 -1
  78. data/templates/platform/scripts/items/spring.js +1 -1
  79. data/templates/platform/tests/displays/hero_test.js +4 -4
  80. data/templates/platform/tests/factories.js +1 -1
  81. data/templates/platform/tests/items/coin_test.js +1 -1
  82. data/templates/pong/game.json +16 -0
  83. data/templates/tiltmaze/game.json +16 -0
  84. data/templates/tiltmaze/scripts/structs/level.js +1 -1
  85. data/templates/tiltmaze/scripts/tiles/walltile.js +1 -1
  86. metadata +45 -32
  87. data/.rspec +0 -2
  88. data/public/tests.html +0 -31
  89. data/src/cycle/worker.js +0 -9
  90. data/templates/animation/assets/images/hero.png +0 -0
  91. data/templates/animation/scripts/scenes/home.js +0 -41
  92. data/templates/animation/tests/init_test.js +0 -4
  93. data/templates/animation/tests/scenes/home_test.js +0 -15
  94. data/templates/arrow_keys/assets/images/arrow.png +0 -0
  95. data/templates/arrow_keys/config.yml +0 -22
  96. data/templates/arrow_keys/readme.txt +0 -9
  97. data/templates/arrow_keys/scripts/displays/arrow.js +0 -69
  98. data/templates/arrow_keys/scripts/init.js +0 -10
  99. data/templates/arrow_keys/scripts/inputs/controls.js +0 -35
  100. data/templates/arrow_keys/scripts/scenes/home.js +0 -20
  101. data/templates/arrow_keys/scripts/scenes/load.js +0 -57
  102. data/templates/arrow_keys/tests/displays/arrow_test.js +0 -29
  103. data/templates/arrow_keys/tests/init_test.js +0 -4
  104. data/templates/arrow_keys/tests/inputs/controls_test.js +0 -32
  105. data/templates/arrow_keys/tests/scenes/home_test.js +0 -0
  106. data/templates/arrow_keys/tests/scenes/load_test.js +0 -18
  107. data/templates/circle/config.yml +0 -22
  108. data/templates/isometric/config.yml +0 -22
  109. data/templates/platform/config.yml +0 -23
  110. data/templates/pong/config.yml +0 -22
  111. data/templates/tiltmaze/config.yml +0 -25
@@ -5,12 +5,20 @@ module Entityjs
5
5
  class Config
6
6
 
7
7
  def self.file_name
8
- 'config.yml'
8
+ 'game.json'
9
9
  end
10
10
 
11
+ def self.preprocess(data, ops={})
12
+ self.instance.preprocess(data, ops)
13
+ end
14
+
11
15
  def self.assets_folder
12
16
  return 'assets'
13
17
  end
18
+
19
+ def self.styles_folder
20
+ return 'styles'
21
+ end
14
22
 
15
23
  def self.tests_folder
16
24
  'tests'
@@ -20,8 +28,8 @@ module Entityjs
20
28
  return 'scripts'
21
29
  end
22
30
 
23
- def self.builds_folder
24
- return 'builds'
31
+ def self.build_folder
32
+ return 'build'
25
33
  end
26
34
 
27
35
  def self.sounds_folder
@@ -41,9 +49,16 @@ module Entityjs
41
49
  end
42
50
 
43
51
  def reload
44
- if File.exists?(Config.file_name)
45
- @yml = YAML::load(File.open(Config.file_name))
52
+ if File.exists?('config.yml')
53
+ puts "Warning: config.yml will be deprecated soon. Rename to #{Config.file_name}"
54
+
55
+ @data = YAML::load(IO.read('config.yml'))
56
+
57
+ elsif File.exists?(Config.file_name)
58
+ data = IO.read(Config.file_name)
59
+ @data = JSON::parse(data)
46
60
  end
61
+
47
62
  end
48
63
 
49
64
  def initialize
@@ -51,79 +66,101 @@ module Entityjs
51
66
  end
52
67
 
53
68
  def width
54
- if @yml.nil?
55
- return 500
56
- end
57
- @yml['width'] || 500
69
+ get_attr('width', 500)
58
70
  end
59
71
 
60
- def canvas_border
61
- if @yml.nil?
62
- return true
63
- end
64
-
65
- return @yml['canvas-border'] || true
72
+ def height
73
+ get_attr('height', 400)
66
74
  end
67
75
 
68
- def height
69
- if @yml.nil?
70
- return 400
71
- end
72
- @yml['height'] || 400
76
+ def canvas_id
77
+ get_attr('canvas-id', 'game-canvas')
73
78
  end
74
79
 
80
+ def canvas_container
81
+ get_attr('canvas-container', 'canvas-container')
82
+ end
83
+
75
84
  def scripts_ignore
76
- if @yml.nil?
77
- return []
78
- end
79
-
80
- y = @yml['scripts-ignore']
81
- if !y.nil?
82
- y.split(" ")
83
- end
85
+ return split_attr('scripts-ignore')
84
86
  end
85
87
 
88
+ def build_scripts_ignore
89
+ return split_attr('build-scripts-ignore')
90
+ end
91
+
92
+ def tests_scripts_ignore
93
+ return split_attr('tests-scripts-ignore')
94
+ end
95
+
86
96
  def scripts_order
87
- if @yml.nil?
88
- return []
89
- end
90
-
91
- y = @yml['order']
92
- if !y.nil?
93
- y.split(" ")
94
- end
97
+ return split_attr('order')
95
98
  end
96
99
 
97
100
  def tests_ignore
98
- if @yml.nil?
99
- return []
100
- end
101
-
102
- y = @yml['tests-ignore']
103
- if !y.nil?
104
- y.split(" ")
105
- end
101
+ return split_attr('tests-ignore')
106
102
  end
107
103
 
108
104
  def entity_ignore
109
- if @yml.nil?
110
- return []
111
- end
112
-
113
- y = @yml['entity-ignore']
114
- if !y.nil?
115
- y.split(" ")
116
- end
105
+ return split_attr('entity-ignore')
117
106
  end
118
107
 
119
- def canvas_id
120
- if @yml.nil?
121
- return 'game-canvas'
122
- end
123
-
124
- @yml['canvas-id'] || 'game-canvas'
108
+ def build_entity_ignore
109
+ return split_attr('build-entity-ignore')
125
110
  end
126
-
111
+
112
+ def build_name
113
+ return get_attr('build-name', self.title_slug+'.min')
114
+ end
115
+
116
+ def build_styles_name
117
+ return get_attr('build_styles_name', self.build_name)
118
+ end
119
+
120
+ def build_styles_ignore
121
+ return split_attr('build-styles-ignore')
122
+ end
123
+
124
+ def tests_entity_ignore
125
+ return split_attr('tests-entity-ignore')
126
+ end
127
+
128
+ def title
129
+ return get_attr('title', 'game')
130
+ end
131
+
132
+ def title_slug
133
+ return title.downcase.gsub(' ', '-')
134
+ end
135
+
136
+ def styles_ignore
137
+ return split_attr('styles-ignore')
138
+ end
139
+
140
+ def build_head
141
+ return get_attr('build-head', '')
142
+ end
143
+
144
+ def build_foot
145
+ return get_attr('build-foot', '')
146
+ end
147
+
148
+ def build_ignore_play
149
+ return get_attr('build-ignore-play', nil)
150
+ end
151
+
152
+ def build_path
153
+ return get_attr('build-path', Config.build_folder)
154
+ end
155
+
156
+ def build_assets_path
157
+ return get_attr('build-assets-path', Config.assets_folder)
158
+ end
159
+
160
+ def build_styles_path
161
+ return get_attr('build-styles-path', Config.styles_folder)
162
+ end
163
+
127
164
  def license
128
165
  contents = IO.read(Entityjs::root+'/license.txt')
129
166
 
@@ -132,6 +169,73 @@ module Entityjs
132
169
  return contents+"\n"
133
170
  end
134
171
 
172
+ #replaces config variables in js/html strings with whats defined in config.json
173
+ # say if the contents inside config.json were:
174
+ # {"title":"My Game"}
175
+ # All js and html files with the word RE_TITLE will be replaced with My Game
176
+ # example, inside init.js:
177
+ # re.ready(function(){
178
+ # re.title = "RE_TITLE"; //this will be replaced
179
+ # re.RE_TITLE //this will be replaced with My Game
180
+ # });
181
+ def preprocess(contents, ops={})
182
+
183
+ #reload config for changes
184
+ self.reload
185
+
186
+ attrs = @data || {}
187
+
188
+ #setup default attrs
189
+ attrs['canvas-id'] = self.canvas_id
190
+ attrs['width'] = self.width
191
+ attrs['height'] = self.height
192
+ attrs['title'] = self.title
193
+ attrs['canvas-container'] = self.canvas_container
194
+
195
+ attrs.each do |k,v|
196
+ val = k.upcase
197
+
198
+ if val == 'JS' || val == 'CSS'
199
+ puts "Warning cannot use JS or CSS as config key. Rename it to something else!"
200
+ end
201
+
202
+ contents = contents.gsub("RE_#{val}", v.to_s)
203
+ end
204
+
205
+ #set width, height and canvas id
206
+ #contents = contents.sub("RE_WIDTH", Config.instance.width.to_s)
207
+ #contents = contents.sub("RE_HEIGHT", Config.instance.height.to_s)
208
+ #contents = contents.sub("RE_CANVAS_ID", Config.instance.canvas_id)
209
+
210
+ return contents
211
+ end
212
+
213
+ protected
214
+ #returns the wanted attr from data else returns the default
215
+ def get_attr(at, default=nil)
216
+ if @data.nil?
217
+ return default
218
+ end
219
+
220
+ return @data[at] || default
221
+ end
222
+
223
+ #returns the wanted attr in an array form
224
+ def split_attr(at)
225
+ if @data.nil?
226
+ return []
227
+ end
228
+
229
+ y = @data[at]
230
+ if !y.nil?
231
+ if y.is_a? Array
232
+ return y
233
+ else
234
+ return y.split(" ")
235
+ end
236
+ end
237
+ return []
238
+ end
135
239
 
136
240
  end
137
241
 
@@ -19,6 +19,11 @@ module Entityjs
19
19
  return false
20
20
  end
21
21
 
22
+ #checks if a local file exists
23
+ def self.exists?(file)
24
+ return File.file? Dirc.game_root+'/'+file
25
+ end
26
+
22
27
  def self.to_game_root
23
28
  Dir.chdir(@game_root)
24
29
  end
@@ -28,6 +33,29 @@ module Entityjs
28
33
  @game_root
29
34
  end
30
35
 
36
+ def self.find_styles(ignore=nil)
37
+ ignore ||= []
38
+
39
+ styles = Dir["#{Dirc.game_root}/#{Config.styles_folder}/**/*.css"].sort
40
+
41
+ if ignore.any?
42
+ styles.delete_if {|i| !i.match(/#{ignore.join('|')}/).nil?}
43
+ end
44
+
45
+ return styles
46
+ end
47
+
48
+ def self.find_styles_url(ignore=nil)
49
+ styles = self.find_styles(ignore)
50
+
51
+ #remove extra folders
52
+ styles = styles.collect do |i|
53
+ i[i.rindex(Config.styles_folder+'/')..-1]
54
+ end
55
+
56
+ return styles
57
+ end
58
+
31
59
  def self.find_tests_url(ignore=nil)
32
60
  valids = Compile.valid_scripts.join(",")
33
61
  ignore ||= []
@@ -7,12 +7,18 @@ module Entityjs
7
7
  return '.js'
8
8
  end
9
9
 
10
- def self.render_play
11
- self.set_vars("play.html")
10
+ def self.render_play_page(ops={})
11
+ self.set_vars("play.html", ops)
12
12
  end
13
13
 
14
- def self.render_tests
15
- self.set_vars('tests.html', true)
14
+ def self.render_favicon
15
+ path = Entityjs::public_path+'/favicon.ico'
16
+
17
+ return IO.read(path)
18
+ end
19
+
20
+ def self.render_test_page
21
+ self.set_vars('test.html', :tests=>true)
16
22
  end
17
23
 
18
24
  def self.render_entityjs_src(path)
@@ -22,49 +28,67 @@ module Entityjs
22
28
  end
23
29
 
24
30
  def self.render_test(path)
25
- file = path.sub(/#{self.processor_ext}$/i, '');
31
+ file = path.sub(/#{self.processor_ext}$/i, '')
26
32
 
27
- return Compile.test_to_js(file)
33
+ return Config.preprocess(Compile.test_to_js(file))
28
34
  end
29
35
 
30
36
  def self.render_script(path)
31
- file = path.sub(/#{self.processor_ext}$/i, '');
32
- return Compile.script_to_js(file)
37
+ file = path.sub(/#{self.processor_ext}$/i, '')
38
+ return Config.preprocess(Compile.script_to_js(file))
33
39
  end
34
40
 
35
41
  def self.render_eunit(path)
36
42
  IO.read(Entityjs::root+"/public/qunit/#{path}")
37
43
  end
38
-
44
+
39
45
  protected
40
- #defines varaibles on the template htmls for view on webpage
41
- def self.set_vars(path, tests=false)
46
+ def self.set_vars(path, ops={})
42
47
  #search locally first
43
- local = Dirc.game_root+'/'+path
44
- if File.file? local
45
- contents = IO.read(local);
48
+ if Dirc::exists?(path)
49
+ contents = IO.read(Dirc.game_root+'/'+path);
46
50
  else
47
- contents = IO.read("#{Entityjs::root}/public/#{path}")
51
+ contents = IO.read("#{Entityjs::public_path}/#{path}")
48
52
  end
49
-
50
- #reload config for changes
51
- Config.instance.reload
52
-
53
- #set width, height and canvas id
54
- contents = contents.sub("$WIDTH", Config.instance.width.to_s)
55
- contents = contents.sub("$HEIGHT", Config.instance.height.to_s)
56
- contents = contents.sub("$CANVAS_ID", Config.instance.canvas_id)
57
-
58
- if !Config.instance.canvas_border
59
- contents = contents.sub('border:1px #333 solid;', '')
60
- end
61
-
53
+
54
+ contents = Config.preprocess(contents)
55
+
62
56
  #set javascript srcs
63
- contents.sub("$JS", self.compile_js_html(tests))
57
+ if !ops[:js]
58
+ js = self.compile_js_html(ops[:tests])
59
+ else
60
+ js = ops[:js]
61
+ end
62
+
63
+ contents = contents.sub("RE_JS", js)
64
+
65
+ #add css
66
+ if !ops[:css]
67
+ css = self.compile_css_html
68
+ else
69
+ css = ops[:css]
70
+ end
71
+
72
+ contents = contents.sub("RE_CSS", css)
64
73
  end
65
-
74
+
75
+ def self.compile_css_html
76
+ styles_url = Dirc.find_styles_url(Config.instance.styles_ignore)
77
+
78
+ css = ''
79
+
80
+ styles_url.each do |s|
81
+
82
+ css += "\t<link rel=\"stylesheet\" href=\"#{s}\" type=\"text/css\"/>\n"
83
+ end
84
+
85
+ return css
86
+ end
87
+
66
88
  #compiles html js tags for render on webpage
67
89
  def self.compile_js_html(tests=false)
90
+ tests ||= false
91
+
68
92
  js = %Q(
69
93
  <script type=\"text/javascript\">
70
94
  window.addEventListener\(\"load\", function(){
@@ -73,8 +97,16 @@ module Entityjs
73
97
  }\);
74
98
  </script>
75
99
  )
76
- ent = Dirc.find_entity_src_url(Config.instance.entity_ignore)
77
- srcs = Dirc.find_scripts_url(Config.instance.scripts_ignore, Config.instance.scripts_order)
100
+ ent_ignore = Config.instance.entity_ignore
101
+ srcs_ignore = Config.instance.scripts_ignore
102
+
103
+ if tests
104
+ ent_ignore += Config.instance.tests_entity_ignore
105
+ srcs_ignore += Config.instance.tests_scripts_ignore
106
+ end
107
+
108
+ ent = Dirc.find_entity_src_url(ent_ignore)
109
+ srcs = Dirc.find_scripts_url(srcs_ignore, Config.instance.scripts_order)
78
110
 
79
111
  if tests
80
112
  tests_src = Dirc.find_tests_url(Config.instance.tests_ignore)
@@ -90,14 +122,21 @@ module Entityjs
90
122
  merg.each do |s|
91
123
 
92
124
  #output a divider for each js root
93
- first_folder = s.split('/').shift
125
+ folders = s.split('/')
126
+
127
+ #remove file at the end
128
+ folders.pop
129
+ folders.join('/')
130
+
131
+ first_folder = folders
94
132
  if last != first_folder
95
133
  js += "\n\n\t<!-- #{first_folder} -->\n"
96
134
  last = first_folder
97
135
  end
98
136
 
99
137
  #add processor extension to non-js files so the server processes it into js
100
- if s.match(/\.js$/).nil?
138
+ if !s.match(/^scripts\//).nil?
139
+ #add processor to all files, because preprocessor needs it to activate
101
140
  s += self.processor_ext
102
141
  end
103
142