dxopal 1.4.2 → 1.5.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +20 -20
  5. data/README.md +3 -3
  6. data/Rakefile +3 -14
  7. data/build/dxopal.js +643 -430
  8. data/build/dxopal.min.js +1 -1
  9. data/config.ru +7 -0
  10. data/doc/api/DXOpal.html +10 -10
  11. data/doc/api/DXOpal/Constants.html +115 -0
  12. data/doc/api/DXOpal/Constants/Colors.html +172 -0
  13. data/doc/api/DXOpal/Font.html +71 -17
  14. data/doc/api/DXOpal/Image.html +891 -398
  15. data/doc/api/DXOpal/Input.html +814 -91
  16. data/doc/api/DXOpal/Input/KeyCodes.html +986 -0
  17. data/doc/api/DXOpal/Input/MouseCodes.html +7 -7
  18. data/doc/api/DXOpal/Input/Touch.html +834 -0
  19. data/doc/api/DXOpal/RemoteResource.html +16 -18
  20. data/doc/api/DXOpal/Sound.html +15 -15
  21. data/doc/api/DXOpal/SoundEffect.html +11 -13
  22. data/doc/api/DXOpal/SoundEffect/WaveTypes.html +7 -7
  23. data/doc/api/DXOpal/Sprite.html +517 -40
  24. data/doc/api/DXOpal/Sprite/CollisionArea.html +126 -0
  25. data/doc/api/DXOpal/Sprite/CollisionArea/Base.html +649 -0
  26. data/doc/api/DXOpal/Sprite/CollisionArea/Circle.html +656 -0
  27. data/doc/api/DXOpal/Sprite/CollisionArea/Point.html +448 -0
  28. data/doc/api/DXOpal/Sprite/CollisionArea/Rect.html +549 -0
  29. data/doc/api/DXOpal/Sprite/CollisionArea/Triangle.html +423 -0
  30. data/doc/api/DXOpal/Sprite/CollisionCheck.html +926 -0
  31. data/doc/api/DXOpal/Sprite/CollisionCheck/ClassMethods.html +268 -0
  32. data/doc/api/DXOpal/Sprite/Physics.html +426 -0
  33. data/doc/api/DXOpal/Window.html +235 -152
  34. data/doc/api/Kernel.html +131 -0
  35. data/doc/api/_index.html +276 -4
  36. data/doc/api/class_list.html +1 -1
  37. data/doc/api/css/style.css +1 -0
  38. data/doc/api/file.README.html +19 -18
  39. data/doc/api/frames.html +1 -1
  40. data/doc/api/index.html +19 -18
  41. data/doc/api/method_list.html +1600 -0
  42. data/doc/api/top-level-namespace.html +154 -3
  43. data/doc/en/index.html +3 -0
  44. data/doc/ja/index.html +3 -0
  45. data/exe/dxopal +1 -1
  46. data/lib/dxopal/image.rb +29 -1
  47. data/lib/dxopal/input.rb +95 -5
  48. data/lib/dxopal/version.rb +1 -1
  49. data/lib/dxopal/window.rb +44 -13
  50. data/template/index.html +1 -1
  51. metadata +21 -7
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  Top Level Namespace
8
8
 
9
- &mdash; Documentation by YARD 0.9.24
9
+ &mdash; Documentation by YARD 0.9.26
10
10
 
11
11
  </title>
12
12
 
@@ -78,21 +78,172 @@
78
78
 
79
79
  </div>
80
80
 
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="DXOpal.html" title="DXOpal (module)">DXOpal</a></span>, <span class='object_link'><a href="Kernel.html" title="Kernel (module)">Kernel</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+ <h2>
100
+ Instance Method Summary
101
+ <small><a href="#" class="summary_toggle">collapse</a></small>
102
+ </h2>
103
+
104
+ <ul class="summary">
105
+
106
+ <li class="public ">
107
+ <span class="summary_signature">
108
+
109
+ <a href="top-level-namespace.html#require-instance_method" title="#require (instance method)">#<strong>require</strong>(*args) &#x21d2; Object </a>
110
+
111
+
112
+
113
+ </span>
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ <span class="summary_desc"><div class='inline'></div></span>
124
+
125
+ </li>
126
+
127
+
128
+ <li class="public ">
129
+ <span class="summary_signature">
130
+
131
+ <a href="top-level-namespace.html#require_remote-instance_method" title="#require_remote (instance method)">#<strong>require_remote</strong>(url) &#x21d2; Object </a>
132
+
133
+
134
+
135
+ </span>
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+ <span class="summary_desc"><div class='inline'></div></span>
146
+
147
+ </li>
148
+
149
+
150
+ </ul>
151
+
81
152
 
82
153
 
83
154
 
155
+ <div id="instance_method_details" class="method_details_list">
156
+ <h2>Instance Method Details</h2>
157
+
158
+
159
+ <div class="method_details first">
160
+ <h3 class="signature first" id="require-instance_method">
161
+
162
+ #<strong>require</strong>(*args) &#x21d2; <tt>Object</tt>
163
+
84
164
 
165
+
85
166
 
167
+
168
+ </h3><table class="source_code">
169
+ <tr>
170
+ <td>
171
+ <pre class="lines">
86
172
 
87
173
 
174
+ 24
175
+ 25
176
+ 26
177
+ 27
178
+ 28
179
+ 29
180
+ 30</pre>
181
+ </td>
182
+ <td>
183
+ <pre class="code"><span class="info file"># File 'lib/dxopal/patches/require_dxopal.rb', line 24</span>
88
184
 
185
+ <span class='kw'>def</span> <span class='id identifier rubyid_require'>require</span><span class='lparen'>(</span><span class='op'>*</span><span class='id identifier rubyid_args'>args</span><span class='rparen'>)</span>
186
+ <span class='kw'>if</span> <span class='id identifier rubyid_args'>args</span> <span class='op'>==</span> <span class='lbracket'>[</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>dxopal</span><span class='tstring_end'>&#39;</span></span><span class='rbracket'>]</span>
187
+ <span class='comment'># Do nothing, because DXOpal is already loaded and you don&#39;t need to find it
188
+ </span> <span class='kw'>else</span>
189
+ <span class='id identifier rubyid_dxopal_orig_require'>dxopal_orig_require</span><span class='lparen'>(</span><span class='op'>*</span><span class='id identifier rubyid_args'>args</span><span class='rparen'>)</span>
190
+ <span class='kw'>end</span>
191
+ <span class='kw'>end</span></pre>
192
+ </td>
193
+ </tr>
194
+ </table>
195
+ </div>
196
+
197
+ <div class="method_details ">
198
+ <h3 class="signature " id="require_remote-instance_method">
199
+
200
+ #<strong>require_remote</strong>(url) &#x21d2; <tt>Object</tt>
201
+
202
+
203
+
204
+
205
+
206
+ </h3><table class="source_code">
207
+ <tr>
208
+ <td>
209
+ <pre class="lines">
210
+
211
+
212
+ 2
213
+ 3
214
+ 4
215
+ 5
216
+ 6
217
+ 7
218
+ 8
219
+ 9
220
+ 10</pre>
221
+ </td>
222
+ <td>
223
+ <pre class="code"><span class="info file"># File 'lib/dxopal/patches/require_remote.rb', line 2</span>
224
+
225
+ <span class='kw'>def</span> <span class='id identifier rubyid_require_remote'>require_remote</span><span class='lparen'>(</span><span class='id identifier rubyid_url'>url</span><span class='rparen'>)</span>
226
+ <span class='backtick'>%x{</span><span class='tstring_content'>
227
+ var r = new XMLHttpRequest();
228
+ r.overrideMimeType(&quot;text/plain&quot;); // https://github.com/yhara/dxopal/issues/12
229
+ r.open(&quot;GET&quot;, url, false);
230
+ r.send(&#39;&#39;);
231
+ </span><span class='tstring_end'>}</span></span>
232
+ <span class='id identifier rubyid_eval'>eval</span> <span class='backtick'>`</span><span class='tstring_content'>r.responseText</span><span class='tstring_end'>`</span></span>
233
+ <span class='kw'>end</span></pre>
234
+ </td>
235
+ </tr>
236
+ </table>
237
+ </div>
238
+
239
+ </div>
89
240
 
90
241
  </div>
91
242
 
92
243
  <div id="footer">
93
- Generated on Sat Jan 18 14:57:06 2020 by
244
+ Generated on Tue Dec 29 11:37:22 2020 by
94
245
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
95
- 0.9.24 (ruby-2.5.5).
246
+ 0.9.26 (ruby-2.7.0).
96
247
  </div>
97
248
 
98
249
  </div>
@@ -34,6 +34,9 @@
34
34
  <li>
35
35
  <a href="../../examples/apple_catcher/index.html">Apple Catcher</a>
36
36
  </li>
37
+ <li>
38
+ <a href="../../examples/multi_touch/index.html">Multi touch</a>
39
+ </li>
37
40
  <li>
38
41
  <a href="../../examples/collision/index.html">Collision detection</a>
39
42
  </li>
@@ -34,6 +34,9 @@
34
34
  <li>
35
35
  <a href="../../examples/apple_catcher/index.html">Apple Catcher</a>
36
36
  </li>
37
+ <li>
38
+ <a href="../../examples/multi_touch/index.html">Multi touch</a>
39
+ </li>
37
40
  <li>
38
41
  <a href="../../examples/collision/index.html">Collision detection</a>
39
42
  </li>
data/exe/dxopal CHANGED
@@ -48,7 +48,7 @@ module DXOpal
48
48
  puts "Starting DXOpal Server"
49
49
  puts "(Open http://localhost:#{options[:port]}/index.html in the browser)"
50
50
  puts "---"
51
- app = Rack::Directory.new(Dir.pwd)
51
+ app = Rack::CommonLogger.new(Rack::Directory.new(Dir.pwd))
52
52
  Rack::Server.start(app: app, Port: options[:port])
53
53
  end
54
54
  end
@@ -6,6 +6,34 @@ module DXOpal
6
6
  class Image < RemoteResource
7
7
  RemoteResource.add_class(Image)
8
8
 
9
+ # Convert HSL to RGB (DXOpal original; not in DXRuby)
10
+ # h: 0-359
11
+ # s: 0-100
12
+ # l: 0-100
13
+ def self.hsl2rgb(h, s, l)
14
+ if l < 50
15
+ max = 2.55 * (l + l*(s/100.0))
16
+ min = 2.55 * (l - l*(s/100.0))
17
+ else
18
+ max = 2.55 * (l + (100-l)*(s/100.0))
19
+ min = 2.55 * (l - (100-l)*(s/100.0))
20
+ end
21
+ case h
22
+ when 0...60
23
+ [max, (h/60.0)*(max-min) + min, min]
24
+ when 60...120
25
+ [((120-h)/60.0)*(max-min) + min, max, min]
26
+ when 120...180
27
+ [min, max, ((h-120)/60.0)*(max-min) + min]
28
+ when 180...240
29
+ [min, ((240-h)/60.0)*(max-min) + min, max]
30
+ when 240...300
31
+ [((h-240)/60.0)*(max-min) + min, min, max]
32
+ else
33
+ [max, min, ((360-h)/60.0)*(max-min) + min]
34
+ end
35
+ end
36
+
9
37
  # Load remote image (called via Window.load_resources)
10
38
  def self._load(path_or_url)
11
39
  raw_img = `new Image()`
@@ -157,7 +185,7 @@ module DXOpal
157
185
 
158
186
  # Put a pixel on this image
159
187
  def []=(x, y, color)
160
- box_fill(x, y, x, y, color)
188
+ box_fill(x, y, x+1, y+1, color)
161
189
  end
162
190
 
163
191
  # Return true if the pixel at `(x, y)` has the `color`
@@ -20,6 +20,7 @@ module DXOpal
20
20
  @@touch_info = `{x: 0, y: 0}`
21
21
  @@pressing_touch = `new Object()`
22
22
 
23
+ @@canvas = canvas
23
24
  rect = `canvas.getBoundingClientRect()`
24
25
  @@canvas_x = `rect.left + window.pageXOffset`
25
26
  @@canvas_y = `rect.top + window.pageYOffset`
@@ -32,6 +33,7 @@ module DXOpal
32
33
  # Called on every frame from Window
33
34
  def self._on_tick
34
35
  @@tick += 1
36
+ self._update_touch_info
35
37
  end
36
38
 
37
39
  # Return 1 if 'right', -1 if 'left'
@@ -133,9 +135,11 @@ module DXOpal
133
135
  document.addEventListener('mouseup', function(ev){
134
136
  #{@@mouse_info}.x = ev.pageX - #{@@canvas_x};
135
137
  #{@@mouse_info}.y = ev.pageY - #{@@canvas_y};
138
+ // ev.button => ev.buttons
139
+ table = { 0: 1, 1: 4, 2: 2, 3: 8, 4: 16 };
136
140
  for (var k=1; k<=16; k<<=1) {
137
- if ((ev.buttons & k) == 0 && #{@@pressing_mouse_buttons}[k]) {
138
- #{@@pressing_mouse_buttons}[k] = -#{@@tick};
141
+ if (#{@@pressing_mouse_buttons}[k]) {
142
+ #{@@pressing_mouse_buttons}[table[ev.button]] = -#{@@tick};
139
143
  }
140
144
  }
141
145
  });
@@ -157,16 +161,19 @@ module DXOpal
157
161
 
158
162
  # Return true if the mouse button is being pressed
159
163
  def self.mouse_down?(mouse_code)
164
+ raise "missing argument of `mouse_down?'" unless mouse_code
160
165
  return `#{@@pressing_mouse_buttons}[mouse_code] > 0`
161
166
  end
162
167
 
163
168
  # Return true if the mouse button is pressed in the last tick
164
169
  def self.mouse_push?(mouse_code)
170
+ raise "missing argument of `mouse_push?'" unless mouse_code
165
171
  return `#{@@pressing_mouse_buttons}[mouse_code] == -(#{@@tick}-1)`
166
172
  end
167
173
 
168
174
  # Return true if the mouse button is released in the last tick
169
175
  def self.mouse_release?(mouse_code)
176
+ raise "missing argument of `mouse_release?'" unless mouse_code
170
177
  return `#{@@pressing_mouse_buttons}[mouse_code] == -(#{@@tick}-1)`
171
178
  end
172
179
 
@@ -176,24 +183,61 @@ module DXOpal
176
183
 
177
184
  # (internal) initialize touch events
178
185
  def self._init_touch_events
186
+ @@touches = {}
187
+ @@new_touches = []
179
188
  %x{
180
- document.addEventListener('touchmove', function(ev){
189
+ #{@@canvas}.addEventListener('touchmove', function(ev){
190
+ ev.preventDefault();
191
+ ev.stopPropagation();
181
192
  #{@@touch_info}.x = ev.changedTouches[0].pageX - #{@@canvas_x};
182
193
  #{@@touch_info}.y = ev.changedTouches[0].pageY - #{@@canvas_y};
194
+ for (var touch of ev.changedTouches) {
195
+ const id = touch.identifier;
196
+ const x = touch.pageX - #{@@canvas_x};
197
+ const y = touch.pageY - #{@@canvas_y};
198
+ #{@@touches[`id`]&._move(`x`, `y`)}
199
+ }
183
200
  });
184
- document.addEventListener('touchstart', function(ev){
201
+ #{@@canvas}.addEventListener('touchstart', function(ev){
202
+ ev.preventDefault();
203
+ ev.stopPropagation();
185
204
  #{@@touch_info}.x = ev.changedTouches[0].pageX - #{@@canvas_x};
186
205
  #{@@touch_info}.y = ev.changedTouches[0].pageY - #{@@canvas_y};
187
206
  #{@@pressing_touch}[0] = #{@@tick};
207
+ for (var touch of ev.changedTouches) {
208
+ const id = touch.identifier;
209
+ const x = touch.pageX - #{@@canvas_x};
210
+ const y = touch.pageY - #{@@canvas_y};
211
+ #{
212
+ new_touch = Touch.new(`id`, `x`, `y`)
213
+ @@touches[`id`] = new_touch
214
+ @@new_touches.push(new_touch)
215
+ }
216
+ }
188
217
  });
189
- document.addEventListener('touchend', function(ev){
218
+ #{@@canvas}.addEventListener('touchend', function(ev){
219
+ ev.preventDefault();
220
+ ev.stopPropagation();
190
221
  #{@@touch_info}.x = ev.changedTouches[0].pageX - #{@@canvas_x};
191
222
  #{@@touch_info}.y = ev.changedTouches[0].pageY - #{@@canvas_y};
192
223
  #{@@pressing_touch}[0] = -#{@@tick};
224
+ for (var touch of ev.changedTouches) {
225
+ const id = touch.identifier;
226
+ #{@@touches[`id`]&._released(@@tick)}
227
+ }
193
228
  });
194
229
  }
195
230
  end
196
231
 
232
+ def self._update_touch_info
233
+ # Clear old data
234
+ @@touches.delete_if{|id, t| t.released? && t._released_at < @@tick-1}
235
+ end
236
+
237
+ #
238
+ # Single touch
239
+ #
240
+
197
241
  # Return position of touch
198
242
  # (0, 0) is the top-left corner of the canvas
199
243
  def self.touch_x
@@ -221,5 +265,51 @@ module DXOpal
221
265
  def self.touch_release?
222
266
  return `#{@@pressing_touch}[0] == -(#{@@tick}-1)`
223
267
  end
268
+
269
+ #
270
+ # Multi touches
271
+ #
272
+
273
+ # Represents a touch
274
+ class Touch
275
+ def initialize(id, x, y)
276
+ @id = id
277
+ _move(x, y)
278
+ @_released_at = nil
279
+ @data = {}
280
+ end
281
+ attr_reader :id, :x, :y, :data, :_released_at
282
+
283
+ # Return true if this touch is released in the last tick
284
+ def released?
285
+ !!@_released_at
286
+ end
287
+
288
+ def inspect
289
+ rel = (released_at ? " released_at=#{released_at}" : "")
290
+ "#<DXOpal::Touch id=#{id} x=#{x} y=#{y} data=#{data.inspect}#{rel}>"
291
+ end
292
+
293
+ def _move(x, y)
294
+ @x = x
295
+ @y = y
296
+ end
297
+
298
+ def _released(tick)
299
+ @_released_at = tick
300
+ end
301
+ end
302
+
303
+ # Returns current touches as an array of Input::Touch
304
+ def self.touches
305
+ @@touches.values
306
+ end
307
+
308
+ # Returns newly created touches
309
+ def self.new_touches
310
+ ret = @@new_touches
311
+ @@new_touches = []
312
+ ret
313
+ end
224
314
  end
225
315
  end
@@ -1,3 +1,3 @@
1
1
  module DXOpal
2
- VERSION = "1.4.2"
2
+ VERSION = "1.5.2"
3
3
  end
@@ -3,6 +3,8 @@ require 'dxopal/constants/colors'
3
3
  module DXOpal
4
4
  module Window
5
5
  @@fps = 60
6
+ @@fps_ts = nil
7
+ @@fps_ct = 0
6
8
  @@real_fps = 0
7
9
  @@real_fps_ct = 1
8
10
  @@real_fps_t = Time.now
@@ -26,7 +28,8 @@ module DXOpal
26
28
  def self.loop(&block)
27
29
  already_running = !!@@block
28
30
  @@block = block
29
- _loop unless already_running
31
+ return if already_running
32
+ `window`.JS.requestAnimationFrame{|time| _loop(time) }
30
33
  end
31
34
 
32
35
  # (DXOpal original) Pause & resume
@@ -46,21 +49,34 @@ module DXOpal
46
49
  end
47
50
 
48
51
  # (internal) call @@block periodically
49
- def self._loop(time=0)
50
- @@img ||= _init(@@width, @@height)
51
- t0 = Time.now
52
+ def self._loop(timestamp)
53
+ @@img ||= _init
52
54
 
53
55
  # Calculate fps
54
- if t0 - @@real_fps_t >= 1.0
56
+ frame_msec = 1000.0 / @@fps
57
+ @@fps_ts ||= timestamp
58
+ passed_msec = timestamp - @@fps_ts
59
+ @@fps_ts = timestamp
60
+ @@fps_ct += passed_msec
61
+ if @@fps_ct >= frame_msec
62
+ @@fps_ct -= frame_msec
63
+ else
64
+ `window`.JS.requestAnimationFrame{|time| _loop(time) }
65
+ return
66
+ end
67
+
68
+ # Calculate real_fps
69
+ t = Time.now
70
+ if t - @@real_fps_t >= 1.0
55
71
  @@real_fps = @@real_fps_ct
56
72
  @@real_fps_ct = 1
57
- @@real_fps_t = t0
73
+ @@real_fps_t = t
58
74
  else
59
75
  @@real_fps_ct += 1
60
76
  end
61
77
 
62
78
  # Update physics
63
- Sprite.matter_tick(time) if Sprite.matter_enabled?
79
+ Sprite.matter_tick(timestamp) if Sprite.matter_enabled?
64
80
 
65
81
  # Detect inputs
66
82
  Input._on_tick
@@ -97,11 +113,12 @@ module DXOpal
97
113
  `window`.JS.requestAnimationFrame{|time| _loop(time) }
98
114
  end
99
115
 
100
- def self._init(w, h)
116
+ def self._init
101
117
  canvas = `document.getElementById("dxopal-canvas")`
102
- `canvas.width = w`
103
- `canvas.height = h`
104
- img = Image.new(w, h, canvas: canvas)
118
+ # If user did not change Window.width/Window.height, set the canvas size here
119
+ self.width = @@width
120
+ self.height = @@height
121
+ img = Image.new(self.width, self.height, canvas: canvas)
105
122
  Input._init(canvas)
106
123
  return img
107
124
  end
@@ -113,9 +130,23 @@ module DXOpal
113
130
  def self.fps=(w); @@fps = w; end
114
131
  def self.real_fps; @@real_fps; end
115
132
  def self.width; @@width; end
116
- def self.width=(w); @@width = w; end
133
+ # Set window width and resize the canvas
134
+ # Set `nil` to maximize canvas
135
+ def self.width=(w)
136
+ canvas = `document.getElementById("dxopal-canvas")`
137
+ @@width = w || `window.innerWidth`
138
+ `canvas.width = #{@@width}`
139
+ `canvas.style.width = #{@@width}`
140
+ end
117
141
  def self.height; @@height; end
118
- def self.height=(h); @@height = h; end
142
+ # Set window height and resize the canvas
143
+ # Set `nil` to maximize canvas
144
+ def self.height=(h)
145
+ canvas = `document.getElementById("dxopal-canvas")`
146
+ @@height = h || `window.innerHeight`
147
+ `canvas.height = #{@@height}`
148
+ `canvas.style.height = #{@@height}`
149
+ end
119
150
  @@bgcolor = Constants::Colors::C_BLACK
120
151
  def self.bgcolor; @@bgcolor; end
121
152
  def self.bgcolor=(col); @@bgcolor = col; end