dxopal 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.ignore +5 -0
- data/.nojekyll +4 -0
- data/CHANGELOG.md +90 -0
- data/DEVELOPMENT.md +57 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +39 -0
- data/README.md +22 -0
- data/Rakefile +66 -0
- data/TODO.md +278 -0
- data/build/dxopal.js +46590 -0
- data/build/dxopal.min.js +1 -0
- data/config.ru +39 -0
- data/doc/api/DXOpal.html +129 -0
- data/doc/api/DXOpal/Font.html +485 -0
- data/doc/api/DXOpal/Image.html +2533 -0
- data/doc/api/DXOpal/Input.html +1086 -0
- data/doc/api/DXOpal/Input/MouseCodes.html +146 -0
- data/doc/api/DXOpal/RemoteResource.html +641 -0
- data/doc/api/DXOpal/Sound.html +568 -0
- data/doc/api/DXOpal/SoundEffect.html +444 -0
- data/doc/api/DXOpal/SoundEffect/WaveTypes.html +130 -0
- data/doc/api/DXOpal/Sprite.html +1419 -0
- data/doc/api/DXOpal/Window.html +1915 -0
- data/doc/api/_index.html +228 -0
- data/doc/api/class_list.html +51 -0
- data/doc/api/css/common.css +1 -0
- data/doc/api/css/full_list.css +58 -0
- data/doc/api/css/style.css +492 -0
- data/doc/api/file.CHANGELOG.html +162 -0
- data/doc/api/file.README.html +124 -0
- data/doc/api/file_list.html +61 -0
- data/doc/api/frames.html +17 -0
- data/doc/api/index.html +124 -0
- data/doc/api/js/app.js +248 -0
- data/doc/api/js/full_list.js +216 -0
- data/doc/api/js/jquery.js +4 -0
- data/doc/api/method_list.html +939 -0
- data/doc/api/top-level-namespace.html +110 -0
- data/doc/en/index.html +93 -0
- data/doc/ja/index.html +92 -0
- data/dxopal.gemspec +29 -0
- data/exe/dxopal +44 -0
- data/index.html +56 -0
- data/opal/dxopal.rb +54 -0
- data/opal/dxopal/constants/colors.rb +16 -0
- data/opal/dxopal/font.rb +20 -0
- data/opal/dxopal/image.rb +301 -0
- data/opal/dxopal/input.rb +170 -0
- data/opal/dxopal/input/key_codes.rb +168 -0
- data/opal/dxopal/remote_resource.rb +65 -0
- data/opal/dxopal/sound.rb +53 -0
- data/opal/dxopal/sound_effect.rb +84 -0
- data/opal/dxopal/sprite.rb +94 -0
- data/opal/dxopal/sprite/collision_area.rb +288 -0
- data/opal/dxopal/sprite/collision_check.rb +106 -0
- data/opal/dxopal/sprite/collision_checker.rb +169 -0
- data/opal/dxopal/sprite/physics.rb +82 -0
- data/opal/dxopal/version.rb +3 -0
- data/opal/dxopal/window.rb +173 -0
- data/template/index.html +13 -0
- data/template/main.rb +9 -0
- metadata +191 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module DXOpal
|
2
|
+
module Constants
|
3
|
+
# Pre-defined ARGB colors
|
4
|
+
module Colors
|
5
|
+
C_BLACK = [255, 0, 0, 0]
|
6
|
+
C_RED = [255, 255, 0, 0]
|
7
|
+
C_GREEN = [255, 0, 255, 0]
|
8
|
+
C_BLUE = [255, 0, 0, 255]
|
9
|
+
C_YELLOW = [255, 255, 255, 0]
|
10
|
+
C_CYAN = [255, 0, 255, 255]
|
11
|
+
C_MAGENTA = [255, 255, 0, 255]
|
12
|
+
C_WHITE = [255, 255, 255, 255]
|
13
|
+
C_DEFAULT = [0, 0, 0, 0]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/opal/dxopal/font.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module DXOpal
|
2
|
+
class Font
|
3
|
+
def self.default; @@default ||= Font.new(24); end
|
4
|
+
def self.default=(f); @@default = f; end
|
5
|
+
|
6
|
+
def initialize(size, fontname=nil, option={})
|
7
|
+
@size = size
|
8
|
+
@orig_fontname = fontname
|
9
|
+
@fontname = fontname || "sans-serif"
|
10
|
+
end
|
11
|
+
|
12
|
+
def size; @size; end
|
13
|
+
def fontname; @orig_fontname; end
|
14
|
+
|
15
|
+
# Return a string like "48px serif"
|
16
|
+
def _spec_str
|
17
|
+
"#{@size}px #{@fontname}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'dxopal/remote_resource'
|
2
|
+
|
3
|
+
module DXOpal
|
4
|
+
class Image < RemoteResource
|
5
|
+
RemoteResource.add_class(Image)
|
6
|
+
|
7
|
+
# Load remote image (called via Window.load_resources)
|
8
|
+
def self._load(path_or_url)
|
9
|
+
raw_img = `new Image()`
|
10
|
+
img_promise = %x{
|
11
|
+
new Promise(function(resolve, reject) {
|
12
|
+
raw_img.onload = function() {
|
13
|
+
resolve(raw_img);
|
14
|
+
};
|
15
|
+
raw_img.src = path_or_url;
|
16
|
+
});
|
17
|
+
}
|
18
|
+
|
19
|
+
img = new(0, 0)
|
20
|
+
%x{
|
21
|
+
#{img_promise}.then(function(raw_img){
|
22
|
+
img.$_resize(raw_img.width, raw_img.height);
|
23
|
+
img.$_draw_raw_image(0, 0, raw_img);
|
24
|
+
});
|
25
|
+
}
|
26
|
+
return img, img_promise
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create an instance of Image
|
30
|
+
def initialize(width, height, color=C_DEFAULT, canvas: nil)
|
31
|
+
@width, @height = width, height
|
32
|
+
@canvas = canvas || `document.createElement("canvas")`
|
33
|
+
@ctx = `#{@canvas}.getContext('2d')`
|
34
|
+
_resize(@width, @height)
|
35
|
+
box_fill(0, 0, @width, @height, color)
|
36
|
+
end
|
37
|
+
attr_reader :ctx, :canvas, :width, :height
|
38
|
+
|
39
|
+
# Set size of this image
|
40
|
+
def _resize(w, h)
|
41
|
+
@width, @height = w, h
|
42
|
+
%x{
|
43
|
+
#{@canvas}.width = w;
|
44
|
+
#{@canvas}.height = h;
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Draw an Image on this image
|
49
|
+
def draw(x, y, image)
|
50
|
+
%x{
|
51
|
+
#{@ctx}.drawImage(#{image.canvas}, x, y);
|
52
|
+
}
|
53
|
+
return self
|
54
|
+
end
|
55
|
+
|
56
|
+
# Draw an Image on this image with rotation
|
57
|
+
# - angle: Rotation angle (radian)
|
58
|
+
# - center_x, center_y: Rotation center in the `image` (default: center of the `image`)
|
59
|
+
def draw_rot(x, y, image, angle, center_x=nil, center_y=nil)
|
60
|
+
draw_ex(x, y, image, angle: angle, center_x: center_x, center_y: center_y)
|
61
|
+
end
|
62
|
+
|
63
|
+
def draw_ex(x, y, image, options={})
|
64
|
+
scale_x = options[:scale_x] || 1
|
65
|
+
scale_y = options[:scale_y] || 1
|
66
|
+
center_x = options[:center_x] || image.width/2
|
67
|
+
center_y = options[:center_y] || image.height/2
|
68
|
+
# TODO: alpha
|
69
|
+
# TODO: blend
|
70
|
+
angle = options[:angle] || 0
|
71
|
+
|
72
|
+
cx = x + center_x
|
73
|
+
cy = y + center_y
|
74
|
+
%x{
|
75
|
+
#{@ctx}.translate(cx, cy);
|
76
|
+
#{@ctx}.rotate(angle * Math.PI / 180.0);
|
77
|
+
#{@ctx}.scale(scale_x, scale_y);
|
78
|
+
#{@ctx}.drawImage(#{image.canvas}, x-cx, y-cy);
|
79
|
+
#{@ctx}.setTransform(1, 0, 0, 1, 0, 0); // reset
|
80
|
+
}
|
81
|
+
return self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Draw some text on this image
|
85
|
+
def draw_font(x, y, string, font, color=[255,255,255])
|
86
|
+
ctx = @ctx
|
87
|
+
%x{
|
88
|
+
ctx.font = #{font._spec_str};
|
89
|
+
ctx.textBaseline = 'top';
|
90
|
+
ctx.fillStyle = #{_rgba(color)};
|
91
|
+
ctx.fillText(string, x, y);
|
92
|
+
}
|
93
|
+
return self
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get a pixel as ARGB array
|
97
|
+
def [](x, y)
|
98
|
+
ctx = @ctx
|
99
|
+
ret = nil
|
100
|
+
%x{
|
101
|
+
var pixel = ctx.getImageData(x, y, 1, 1);
|
102
|
+
var rgba = pixel.data;
|
103
|
+
ret = [rgba[3], rgba[0], rgba[1], rgba[2]];
|
104
|
+
}
|
105
|
+
return ret
|
106
|
+
end
|
107
|
+
|
108
|
+
# Put a pixel on this image
|
109
|
+
def []=(x, y, color)
|
110
|
+
box_fill(x, y, x, y, color)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Return true if the pixel at `(x, y)` has the `color`
|
114
|
+
def compare(x, y, color)
|
115
|
+
ctx = @ctx
|
116
|
+
rgba1 = _rgba_ary(color)
|
117
|
+
rgba2 = nil
|
118
|
+
ret = nil
|
119
|
+
%x{
|
120
|
+
var pixel = ctx.getImageData(x, y, 1, 1);
|
121
|
+
rgba2 = pixel.data;
|
122
|
+
// TODO: what is the right way to compare an Array and an Uint8ClampedArray?
|
123
|
+
ret = rgba1[0] == rgba2[0] &&
|
124
|
+
rgba1[1] == rgba2[1] &&
|
125
|
+
rgba1[2] == rgba2[2] &&
|
126
|
+
rgba1[3] == rgba2[3]
|
127
|
+
}
|
128
|
+
return ret
|
129
|
+
end
|
130
|
+
|
131
|
+
# Draw a line on this image
|
132
|
+
def line(x1, y1, x2, y2, color)
|
133
|
+
ctx = @ctx
|
134
|
+
%x{
|
135
|
+
ctx.beginPath();
|
136
|
+
ctx.strokeStyle = #{_rgba(color)};
|
137
|
+
ctx.moveTo(x1, y1);
|
138
|
+
ctx.lineTo(x2, y2);
|
139
|
+
ctx.stroke();
|
140
|
+
}
|
141
|
+
return self
|
142
|
+
end
|
143
|
+
|
144
|
+
# Draw a rectangle on this image
|
145
|
+
def box(x1, y1, x2, y2, color)
|
146
|
+
ctx = @ctx
|
147
|
+
%x{
|
148
|
+
ctx.beginPath();
|
149
|
+
ctx.strokeStyle = #{_rgba(color)};
|
150
|
+
ctx.rect(x1, y1, x2-x1+1, y2-y1+1);
|
151
|
+
ctx.stroke();
|
152
|
+
}
|
153
|
+
return self
|
154
|
+
end
|
155
|
+
|
156
|
+
# Draw a filled box on this image
|
157
|
+
def box_fill(x1, y1, x2, y2, color)
|
158
|
+
ctx = @ctx
|
159
|
+
%x{
|
160
|
+
ctx.beginPath();
|
161
|
+
ctx.fillStyle = #{_rgba(color)};
|
162
|
+
ctx.fillRect(x1, y1, x2-x1+1, y2-y1+1);
|
163
|
+
}
|
164
|
+
return self
|
165
|
+
end
|
166
|
+
|
167
|
+
# Draw a circle on this image
|
168
|
+
def circle(x, y, r, color)
|
169
|
+
ctx = @ctx
|
170
|
+
%x{
|
171
|
+
ctx.beginPath();
|
172
|
+
ctx.strokeStyle = #{_rgba(color)};
|
173
|
+
ctx.arc(x, y, r, 0, Math.PI*2, false)
|
174
|
+
ctx.stroke();
|
175
|
+
}
|
176
|
+
return self
|
177
|
+
end
|
178
|
+
|
179
|
+
# Draw a filled circle on this image
|
180
|
+
def circle_fill(x, y, r, color)
|
181
|
+
ctx = @ctx
|
182
|
+
%x{
|
183
|
+
ctx.beginPath();
|
184
|
+
ctx.fillStyle = #{_rgba(color)};
|
185
|
+
ctx.arc(x, y, r, 0, Math.PI*2, false)
|
186
|
+
ctx.fill();
|
187
|
+
}
|
188
|
+
return self
|
189
|
+
end
|
190
|
+
|
191
|
+
# Draw a triangle on this image
|
192
|
+
def triangle(x1, y1, x2, y2, x3, y3, color)
|
193
|
+
ctx = @ctx
|
194
|
+
%x{
|
195
|
+
ctx.beginPath();
|
196
|
+
ctx.strokeStyle = #{_rgba(color)};
|
197
|
+
ctx.moveTo(x1, y1);
|
198
|
+
ctx.lineTo(x2, y2);
|
199
|
+
ctx.lineTo(x3, y3);
|
200
|
+
ctx.lineTo(x1, y1);
|
201
|
+
ctx.stroke();
|
202
|
+
}
|
203
|
+
return self
|
204
|
+
end
|
205
|
+
|
206
|
+
# Draw a filled triangle on this image
|
207
|
+
def triangle_fill(x1, y1, x2, y2, x3, y3, color)
|
208
|
+
ctx = @ctx
|
209
|
+
%x{
|
210
|
+
ctx.beginPath();
|
211
|
+
ctx.fillStyle = #{_rgba(color)};
|
212
|
+
ctx.moveTo(x1, y1);
|
213
|
+
ctx.lineTo(x2, y2);
|
214
|
+
ctx.lineTo(x3, y3);
|
215
|
+
ctx.fill();
|
216
|
+
}
|
217
|
+
return self
|
218
|
+
end
|
219
|
+
|
220
|
+
# Fill this image with `color`
|
221
|
+
def fill(color)
|
222
|
+
box_fill(0, 0, @width-1, @height-1, color)
|
223
|
+
end
|
224
|
+
|
225
|
+
# Clear this image (i.e. fill with `[0,0,0,0]`)
|
226
|
+
def clear
|
227
|
+
fill([0, 0, 0, 0])
|
228
|
+
end
|
229
|
+
|
230
|
+
# Return an Image which is a copy of the specified area
|
231
|
+
def slice(x, y, width, height)
|
232
|
+
newimg = Image.new(width, height)
|
233
|
+
data = _image_data(x, y, width, height)
|
234
|
+
newimg._put_image_data(data, 0, 0)
|
235
|
+
return newimg
|
236
|
+
end
|
237
|
+
|
238
|
+
# Slice this image into xcount*ycount tiles
|
239
|
+
def slice_tiles(xcount, ycount)
|
240
|
+
tile_w = @width / xcount
|
241
|
+
tile_h = @height / ycount
|
242
|
+
return (0...ycount).flat_map{|v|
|
243
|
+
(0...xcount).map{|u|
|
244
|
+
slice(tile_w * u, tile_h * v, tile_w, tile_h)
|
245
|
+
}
|
246
|
+
}
|
247
|
+
end
|
248
|
+
|
249
|
+
# Copy an <img> onto this image
|
250
|
+
def _draw_raw_image(x, y, raw_img)
|
251
|
+
%x{
|
252
|
+
#{@ctx}.drawImage(#{raw_img}, x, y)
|
253
|
+
}
|
254
|
+
end
|
255
|
+
|
256
|
+
# Return .getImageData
|
257
|
+
def _image_data(x=0, y=0, w=@width, h=@height)
|
258
|
+
return `#{@ctx}.getImageData(x, y, w, h)`
|
259
|
+
end
|
260
|
+
|
261
|
+
# Call .putImageData
|
262
|
+
def _put_image_data(image_data, x, y)
|
263
|
+
`#{@ctx}.putImageData(image_data, x, y)`
|
264
|
+
end
|
265
|
+
|
266
|
+
# Return a string like 'rgb(255, 255, 255)'
|
267
|
+
# `color` is 3 or 4 numbers
|
268
|
+
def _rgb(color)
|
269
|
+
case color.length
|
270
|
+
when 4
|
271
|
+
# Just ignore alpha
|
272
|
+
rgb = color[1, 3]
|
273
|
+
when 3
|
274
|
+
rgb = color
|
275
|
+
else
|
276
|
+
raise "invalid color: #{color.inspect}"
|
277
|
+
end
|
278
|
+
return "rgb(" + rgb.join(', ') + ")";
|
279
|
+
end
|
280
|
+
|
281
|
+
# Return a string like 'rgba(255, 255, 255, 128)'
|
282
|
+
# `color` is 3 or 4 numbers
|
283
|
+
def _rgba(color)
|
284
|
+
return "rgba(" + _rgba_ary(color).join(', ') + ")"
|
285
|
+
end
|
286
|
+
|
287
|
+
# Return an array like `[255, 255, 255, 128]`
|
288
|
+
def _rgba_ary(color)
|
289
|
+
case color.length
|
290
|
+
when 4
|
291
|
+
# color is ARGB in DXRuby, so move A to the last
|
292
|
+
color[1, 3] + [color[0]/255.0]
|
293
|
+
when 3
|
294
|
+
# Complement 255 as alpha
|
295
|
+
color + [1.0]
|
296
|
+
else
|
297
|
+
raise "invalid color: #{color.inspect}"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module DXOpal
|
2
|
+
module Input
|
3
|
+
module MouseCodes
|
4
|
+
M_LBUTTON = 1
|
5
|
+
M_RBUTTON = 2
|
6
|
+
M_MBUTTON = 4
|
7
|
+
# DXOpal extention
|
8
|
+
M_4TH_BUTTON = 8
|
9
|
+
M_5TH_BUTTON = 16
|
10
|
+
end
|
11
|
+
|
12
|
+
def self._pressing_keys; @@pressing_keys; end
|
13
|
+
|
14
|
+
# Internal setup for Input class
|
15
|
+
def self._init(canvas)
|
16
|
+
@@tick = 0
|
17
|
+
@@pressing_keys = `new Object()`
|
18
|
+
@@mouse_info = `{x: 0, y: 0}`
|
19
|
+
@@pressing_mouse_buttons = `new Object()`
|
20
|
+
|
21
|
+
rect = `canvas.getBoundingClientRect()`
|
22
|
+
@@canvas_x = `rect.left + window.pageXOffset`
|
23
|
+
@@canvas_y = `rect.top + window.pageYOffset`
|
24
|
+
|
25
|
+
self._init_mouse_events
|
26
|
+
self.keyevent_target = `window` unless Input.keyevent_target
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called on every frame from Window
|
30
|
+
def self._on_tick
|
31
|
+
@@tick += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return 1 if 'right', -1 if 'left'
|
35
|
+
def self.x(pad_number=0)
|
36
|
+
ret = 0
|
37
|
+
ret += 1 if key_down?(K_RIGHT)
|
38
|
+
ret -= 1 if key_down?(K_LEFT)
|
39
|
+
ret
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return 1 if 'down', -1 if 'up'
|
43
|
+
def self.y(pad_number=0)
|
44
|
+
ret = 0
|
45
|
+
ret += 1 if key_down?(K_DOWN)
|
46
|
+
ret -= 1 if key_down?(K_UP)
|
47
|
+
ret
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Keyboard
|
52
|
+
#
|
53
|
+
|
54
|
+
# Return true if the key is being pressed
|
55
|
+
def self.key_down?(code)
|
56
|
+
return `#{@@pressing_keys}[code] > 0`
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return true if the key is just pressed
|
60
|
+
def self.key_push?(code)
|
61
|
+
return `#{@@pressing_keys}[code] == #{@@tick}-1`
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return true if the key is just released
|
65
|
+
def self.key_release?(code)
|
66
|
+
return `#{@@pressing_keys}[code] == -(#{@@tick}-1)`
|
67
|
+
end
|
68
|
+
|
69
|
+
# (private) JS keydown event handler
|
70
|
+
ON_KEYDOWN_ = %x{
|
71
|
+
function(ev){
|
72
|
+
#{Input._pressing_keys}[ev.keyCode] = #{@@tick};
|
73
|
+
ev.preventDefault();
|
74
|
+
ev.stopPropagation();
|
75
|
+
}
|
76
|
+
}
|
77
|
+
# (private) JS keyup event handler
|
78
|
+
ON_KEYUP_ = %x{
|
79
|
+
function(ev){
|
80
|
+
#{Input._pressing_keys}[ev.keyCode] = -#{@@tick};
|
81
|
+
ev.preventDefault();
|
82
|
+
ev.stopPropagation();
|
83
|
+
}
|
84
|
+
}
|
85
|
+
# Set DOM element to receive keydown/keyup event
|
86
|
+
#
|
87
|
+
# By default, `window` is set to this (i.e. all key events are
|
88
|
+
# stolen by DXOpal.) If canvas element is set to this, only key events
|
89
|
+
# happend on canvas are processed by DXOpal.
|
90
|
+
def self.keyevent_target=(target)
|
91
|
+
if @@keyevent_target
|
92
|
+
%x{
|
93
|
+
#{@@keyevent_target}.removeEventListener('keydown', #{ON_KEYDOWN_});
|
94
|
+
#{@@keyevent_target}.removeEventListener('keyup', #{ON_KEYUP_});
|
95
|
+
}
|
96
|
+
end
|
97
|
+
@@keyevent_target = target
|
98
|
+
%x{
|
99
|
+
if (#{@@keyevent_target}.tagName == "CANVAS") {
|
100
|
+
#{@@keyevent_target}.setAttribute('tabindex', 0);
|
101
|
+
}
|
102
|
+
#{@@keyevent_target}.addEventListener('keydown', #{ON_KEYDOWN_});
|
103
|
+
#{@@keyevent_target}.addEventListener('keyup', #{ON_KEYUP_});
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return DOM element set by `keyevent_target=`
|
108
|
+
def self.keyevent_target; @@keyevent_target; end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Mouse
|
112
|
+
#
|
113
|
+
|
114
|
+
# (internal) initialize mouse events
|
115
|
+
def self._init_mouse_events
|
116
|
+
%x{
|
117
|
+
document.addEventListener('mousemove', function(ev){
|
118
|
+
#{@@mouse_info}.x = ev.pageX - #{@@canvas_x};
|
119
|
+
#{@@mouse_info}.y = ev.pageY - #{@@canvas_y};
|
120
|
+
});
|
121
|
+
document.addEventListener('mousedown', function(ev){
|
122
|
+
#{@@mouse_info}.x = ev.pageX - #{@@canvas_x};
|
123
|
+
#{@@mouse_info}.y = ev.pageY - #{@@canvas_y};
|
124
|
+
for (var k=1; k<=16; k<<=1) {
|
125
|
+
if (ev.buttons & k) {
|
126
|
+
#{@@pressing_mouse_buttons}[k] = #{@@tick};
|
127
|
+
}
|
128
|
+
}
|
129
|
+
});
|
130
|
+
document.addEventListener('mouseup', function(ev){
|
131
|
+
#{@@mouse_info}.x = ev.pageX - #{@@canvas_x};
|
132
|
+
#{@@mouse_info}.y = ev.pageY - #{@@canvas_y};
|
133
|
+
for (var k=1; k<=16; k<<=1) {
|
134
|
+
if ((ev.buttons & k) == 0 && #{@@pressing_mouse_buttons}[k]) {
|
135
|
+
#{@@pressing_mouse_buttons}[k] = -#{@@tick};
|
136
|
+
}
|
137
|
+
}
|
138
|
+
});
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
# Return position of mouse cursor
|
143
|
+
# (0, 0) is the top-left corner of the canvas
|
144
|
+
def self.mouse_x
|
145
|
+
return `#{@@mouse_info}.x`
|
146
|
+
end
|
147
|
+
def self.mouse_y
|
148
|
+
return `#{@@mouse_info}.y`
|
149
|
+
end
|
150
|
+
class << self
|
151
|
+
alias mouse_pos_x mouse_x
|
152
|
+
alias mouse_pos_y mouse_y
|
153
|
+
end
|
154
|
+
|
155
|
+
# Return true if the mouse button is being pressed
|
156
|
+
def self.mouse_down?(mouse_code)
|
157
|
+
return `#{@@pressing_mouse_buttons}[mouse_code] > 0`
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return true if the mouse button is pressed in the last tick
|
161
|
+
def self.mouse_push?(mouse_code)
|
162
|
+
return `#{@@pressing_mouse_buttons}[mouse_code] == -(#{@@tick}-1)`
|
163
|
+
end
|
164
|
+
|
165
|
+
# Return true if the mouse button is released in the last tick
|
166
|
+
def self.mouse_release?(mouse_code)
|
167
|
+
return `#{@@pressing_mouse_buttons}[mouse_code] == -(#{@@tick}-1)`
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|