yeah 0.2.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +52 -20
  4. data/bin/yeah +30 -0
  5. data/lib/yeah.rb +6 -9
  6. data/lib/yeah/_platform/asset.rb +24 -0
  7. data/lib/yeah/_platform/display.rb +181 -0
  8. data/lib/yeah/_platform/image.rb +16 -0
  9. data/lib/yeah/_platform/keyboard.rb +37 -0
  10. data/lib/yeah/_platform/mouse.rb +30 -0
  11. data/lib/yeah/_platform/sound.rb +15 -0
  12. data/lib/yeah/_platform/ticker.rb +21 -0
  13. data/lib/yeah/_template/Gemfile +4 -0
  14. data/lib/yeah/_template/code/code.rb +4 -0
  15. data/lib/yeah/_template/code/game.rb +7 -0
  16. data/lib/yeah/_web.rb +9 -0
  17. data/lib/yeah/color.rb +45 -13
  18. data/lib/yeah/constants.rb +6 -0
  19. data/lib/yeah/game.rb +89 -41
  20. data/lib/yeah/vector.rb +122 -99
  21. data/lib/yeah/version.rb +3 -0
  22. data/lib/yeah/web/dependencies.rb +2 -0
  23. data/lib/yeah/web/runner.html.erb +61 -0
  24. data/lib/yeah/web/server.rb +60 -0
  25. data/lib/yeah/web/setup.rb +5 -0
  26. data/lib/yeah/web/start.rb +1 -0
  27. data/opal/yeah/web.rb +8 -0
  28. data/opal/yeah/web/asset.opal +38 -0
  29. data/opal/yeah/web/constants.opal +5 -0
  30. data/opal/yeah/web/display.opal +244 -0
  31. data/opal/yeah/web/image.opal +23 -0
  32. data/opal/yeah/web/keyboard.opal +139 -0
  33. data/opal/yeah/web/mouse.opal +58 -0
  34. data/opal/yeah/web/sound.opal +19 -0
  35. data/opal/yeah/web/ticker.opal +39 -0
  36. metadata +111 -19
  37. data/CHANGELOG.md +0 -28
  38. data/lib/monkey/numeric.rb +0 -6
  39. data/lib/yeah/basic_physics.rb +0 -11
  40. data/lib/yeah/desktop.rb +0 -72
  41. data/lib/yeah/entity.rb +0 -137
  42. data/lib/yeah/map.rb +0 -40
  43. data/lib/yeah/rectangle.rb +0 -21
  44. data/lib/yeah/surface.rb +0 -66
@@ -0,0 +1,3 @@
1
+ module Yeah
2
+ VERSION = '0.3.3'
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'opal'
2
+ require 'yeah'
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Game</title>
5
+
6
+ <style>
7
+ body {
8
+ background: black;
9
+ margin: 0;
10
+ }
11
+
12
+ .center-content {
13
+ /* Internet Explorer 10 */
14
+ display: -ms-flexbox;
15
+ -ms-flex-pack: center;
16
+ -ms-flex-align: center;
17
+ /* Firefox */
18
+ display: -moz-box;
19
+ -moz-box-pack: center;
20
+ -moz-box-align: center;
21
+ /* Safari, Opera, and Chrome */
22
+ display: -webkit-box;
23
+ -webkit-box-pack: center;
24
+ -webkit-box-align: center;
25
+ /* W3C */
26
+ display: box;
27
+ box-pack: center;
28
+ box-align: center;
29
+ }
30
+
31
+ html, body{
32
+ width: 100%;
33
+ height: 100%;
34
+ }
35
+
36
+ canvas {
37
+ max-width: 100%;
38
+ max-height: 100%;
39
+ }
40
+
41
+ .hidden {
42
+ display: none;
43
+ }
44
+ </style>
45
+ </head>
46
+ <body class="center-content">
47
+ <canvas></canvas>
48
+
49
+ <div class="hidden">
50
+ <%= @server.asset_include_tags %>
51
+ </div>
52
+
53
+ <%= javascript_include_tag 'yeah/web/dependencies' %>
54
+ <%= javascript_include_tag 'yeah/web' %>
55
+ <%= javascript_include_tag 'yeah/web/setup' %>
56
+
57
+ <%= javascript_include_tag 'code' %>
58
+
59
+ <%= javascript_include_tag 'yeah/web/start' %>
60
+ </body>
61
+ </html>
@@ -0,0 +1,60 @@
1
+ require 'pathname'
2
+ require 'rack'
3
+ require 'opal'
4
+
5
+ module Yeah
6
+ module Web
7
+
8
+ # The `Web::Server` serves a game over the Internet. It can be started easily
9
+ # by entering `yeah serve` in a command-line within a game project.
10
+ class Server
11
+ # @param [Integer] port to serve game over
12
+ # Start serving the game.
13
+ def start(port = 1234)
14
+ Rack::Server.start(app: Application.new, Port: port)
15
+ end
16
+
17
+ private
18
+
19
+ # For internal usage.
20
+ # @see Yeah::Web::Server
21
+ class Application < Opal::Server
22
+ def initialize
23
+ @index_path = gem_path.join('lib', 'yeah', 'web', 'runner.html.erb').to_s
24
+
25
+ super
26
+
27
+ # Append stdlib paths
28
+ $LOAD_PATH.each { |p| append_path(p) }
29
+
30
+ # Append Yeah paths
31
+ append_path gem_path.join('lib')
32
+ append_path gem_path.join('opal')
33
+
34
+ # Append game (working directory) paths
35
+ append_path 'assets'
36
+ append_path 'code'
37
+ end
38
+
39
+ def asset_include_tags
40
+ paths = Dir['assets/**/*'].select { |p| File.file? p }
41
+
42
+ paths.map do |path|
43
+ case path
44
+ when /\.(ogg|wav|mp3)$/
45
+ "<audio src=\"#{path}\"></audio>"
46
+ else
47
+ "<img src=\"#{path}\" />"
48
+ end
49
+ end.join("\n")
50
+ end
51
+
52
+ private
53
+
54
+ def gem_path
55
+ @gem_path ||= Pathname.new(__FILE__).join('..', '..', '..', '..')
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,5 @@
1
+ module Yeah
2
+ include Web
3
+ end
4
+
5
+ include Yeah
@@ -0,0 +1 @@
1
+ Game.default.new
data/opal/yeah/web.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'yeah/web/constants'
2
+ require 'yeah/web/asset'
3
+ require 'yeah/web/image'
4
+ require 'yeah/web/sound'
5
+ require 'yeah/web/display'
6
+ require 'yeah/web/keyboard'
7
+ require 'yeah/web/mouse'
8
+ require 'yeah/web/ticker'
@@ -0,0 +1,38 @@
1
+ module Yeah
2
+ module Web
3
+ class Asset
4
+ ASSETS_PATH = "./assets"
5
+
6
+ class << self
7
+ def [](*args)
8
+ new(*args)
9
+ end
10
+ end
11
+
12
+ def initialize(path)
13
+ setup_native
14
+
15
+ self.path = path
16
+ end
17
+
18
+ def path
19
+ `#@native.src`.sub(/.*:\/\/.*#{ASSETS_PATH}\//i, '')
20
+ end
21
+ def path=(val)
22
+ # TODO: use Pathname#join if it is implemented in Opal
23
+ full_path = "#{ASSETS_PATH}/#{val}"
24
+ `#@native.src = #{full_path};`
25
+ end
26
+
27
+ def to_n
28
+ @native
29
+ end
30
+
31
+ private
32
+
33
+ def setup_native
34
+ raise NotImplementedError
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module Yeah
2
+ module Web
3
+ DEFAULT_CANVAS_SELECTOR = 'canvas'
4
+ end
5
+ end
@@ -0,0 +1,244 @@
1
+ module Yeah
2
+ module Web
3
+ class Display
4
+ attr_reader :font_family, :font_size
5
+
6
+ def initialize(options = {})
7
+ canvas_selector = options.fetch(:canvas_selector, DEFAULT_CANVAS_SELECTOR)
8
+
9
+ @canvas = `document.querySelectorAll(#{canvas_selector})[0]`
10
+ @context = `#@canvas.getContext('2d')`
11
+ self.size = options.fetch(:size, DEFAULT_DISPLAY_SIZE)
12
+ self.font_family = DEFAULT_DISPLAY_FONT_FAMILY
13
+ self.font_size = DEFAULT_DISPLAY_FONT_SIZE
14
+ @transform = [1, 0, 0, 1, 0, 0]
15
+ @transforms = []
16
+ end
17
+
18
+ def size
19
+ V[`#@canvas.width`, `#@canvas.height`]
20
+ end
21
+ def size=(value)
22
+ `#@canvas.width = #{value.x}`
23
+ `#@canvas.height = #{value.y}`
24
+ end
25
+
26
+ def width
27
+ `#@canvas.width`
28
+ end
29
+ def width=(value)
30
+ `#@canvas.width = #{value.x}`
31
+ end
32
+
33
+ def height
34
+ `#@canvas.height`
35
+ end
36
+ def height=(value)
37
+ `#@canvas.height = #{value.x}`
38
+ end
39
+
40
+ def fill_color
41
+ C[`#@context.fillStyle`]
42
+ end
43
+ def fill_color=(color)
44
+ `#@context.fillStyle = #{color.to_hex}`
45
+ end
46
+
47
+ def stroke_color
48
+ C[`#@context.strokeStyle`]
49
+ end
50
+ def stroke_color=(color)
51
+ `#@context.strokeStyle = #{color.to_hex}`
52
+ end
53
+
54
+ def stroke_width
55
+ `#@context.lineWidth`
56
+ end
57
+ def stroke_width=(numeric)
58
+ `#@context.lineWidth = #{numeric}`
59
+ end
60
+
61
+ def font_family=(type)
62
+ @font_family= type
63
+
64
+ font = "#{@font_size}px #{@font_family}"
65
+ `#@context.font = #{font}`
66
+ end
67
+
68
+ def font_size=(size)
69
+ @font_size = size
70
+
71
+ font = "#{@font_size}px #{@font_family}"
72
+ `#@context.font = #{font}`
73
+ end
74
+
75
+ def color_at(position)
76
+ data = `#@context.getImageData(#{position.x}, #{position.y}, 1, 1).data`
77
+ C[`data[0]`, `data[1]`, `data[2]`]
78
+ end
79
+
80
+ def transformation
81
+ @transform + [0, 0, 1] # appendage to fulfill signature
82
+ end
83
+
84
+ def translate(displacement)
85
+ @transform[4] += `#{@transform[0]} * #{displacement.x} +
86
+ #{@transform[2]} * #{displacement.y}`
87
+ @transform[5] += `#{@transform[1]} * #{displacement.x} +
88
+ #{@transform[3]} * #{displacement.y}`
89
+
90
+ %x{
91
+ #@context.setTransform(#{@transform[0]}, #{@transform[1]},
92
+ #{@transform[2]}, #{@transform[3]},
93
+ #{@transform[4]}, #{@transform[5]}); }
94
+ end
95
+
96
+ def scale(multiplier)
97
+ %x{
98
+ #{@transform} = [#{@transform[0]} * #{multiplier.x},
99
+ #{@transform[1]} * #{multiplier.x},
100
+ #{@transform[2]} * #{multiplier.y},
101
+ #{@transform[3]} * #{multiplier.y},
102
+ #{@transform[4]}, #{@transform[5]}];
103
+
104
+ #@context.setTransform(#{@transform[0]}, #{@transform[1]},
105
+ #{@transform[2]}, #{@transform[3]},
106
+ #{@transform[4]}, #{@transform[5]}); }
107
+ end
108
+
109
+ def rotate(radians)
110
+ %x{
111
+ var cos = Math.cos(#{radians}),
112
+ sin = Math.sin(#{radians}),
113
+ e0 = #{@transform[0]} * cos + #{@transform[2]} * sin,
114
+ e1 = #{@transform[1]} * cos + #{@transform[3]} * sin,
115
+ e2 = #{@transform[0]} * -sin + #{@transform[2]} * cos,
116
+ e3 = #{@transform[1]} * -sin + #{@transform[3]} * cos;
117
+
118
+ #@transform = [e0, e1, e2, e3, #{@transform[4]}, #{@transform[5]}];
119
+
120
+ #@context.setTransform(#{@transform[0]}, #{@transform[1]},
121
+ #{@transform[2]}, #{@transform[3]},
122
+ #{@transform[4]}, #{@transform[5]}); }
123
+ end
124
+
125
+ def push
126
+ @transforms.push(@transform.dup)
127
+ end
128
+
129
+ def pop
130
+ @transform = @transforms.pop
131
+
132
+ %x{
133
+ #@context.setTransform(#{@transform[0]}, #{@transform[1]},
134
+ #{@transform[2]}, #{@transform[3]},
135
+ #{@transform[4]}, #{@transform[5]}); }
136
+ end
137
+
138
+ def stroke_line(start_pos, end_pos)
139
+ %x{
140
+ #@context.beginPath();
141
+ #@context.moveTo(#{start_pos.x}, #{start_pos.y});
142
+ #@context.lineTo(#{end_pos.x}, #{end_pos.y});
143
+ #@context.closePath();
144
+ #@context.stroke();
145
+ }
146
+ end
147
+
148
+ def stroke_rectangle(position, size)
149
+ `#@context.strokeRect(#{position.x}, #{position.y}, #{size.x}, #{size.y})`
150
+ end
151
+
152
+ def fill_rectangle(position, size)
153
+ `#@context.fillRect(#{position.x}, #{position.y}, #{size.x}, #{size.y})`
154
+ end
155
+
156
+ def stroke_ellipse(center, radius)
157
+ %x{
158
+ #@context.beginPath();
159
+ #@context.save();
160
+ #@context.beginPath();
161
+ #@context.translate(#{center.x} - #{radius.x},
162
+ #{center.y} - #{radius.y});
163
+ #@context.scale(#{radius.x}, #{radius.y});
164
+ #@context.arc(1, 1, 1, 0, 2 * Math.PI, false);
165
+ #@context.restore();
166
+ #@context.stroke();
167
+ }
168
+ end
169
+
170
+ def fill_ellipse(center, radius)
171
+ %x{
172
+ #@context.beginPath();
173
+ #@context.save();
174
+ #@context.beginPath();
175
+ #@context.translate(#{center.x} - #{radius.x},
176
+ #{center.y} - #{radius.y});
177
+ #@context.scale(#{radius.x}, #{radius.y});
178
+ #@context.arc(1, 1, 1, 0, 2 * Math.PI, false);
179
+ #@context.restore();
180
+ #@context.fill();
181
+ }
182
+ end
183
+
184
+ def clear
185
+ `#@context.fillRect(0, 0, #{size.x}, #{size.y})`
186
+ end
187
+
188
+ def begin_shape
189
+ `#@context.beginPath()`
190
+ end
191
+
192
+ def end_shape
193
+ `#@context.closePath()`
194
+ end
195
+
196
+ def move_to(position)
197
+ `#@context.moveTo(#{position.x}, #{position.y})`
198
+ end
199
+
200
+ def line_to(position)
201
+ `#@context.lineTo(#{position.x}, #{position.y})`
202
+ end
203
+
204
+ def curve_to(position, control)
205
+ `#@context.quadraticCurveTo(#{control.x}, #{control.y},
206
+ #{position.x}, #{position.y})`
207
+ end
208
+
209
+ def curve2_to(position, control1, control2)
210
+ `#@context.bezierCurveTo(#{control1.x}, #{control1.y},
211
+ #{control2.x}, #{control2.y},
212
+ #{position.x}, #{position.y})`
213
+ end
214
+
215
+ def stroke_shape
216
+ `#@context.stroke()`
217
+ end
218
+
219
+ def fill_shape
220
+ `#@context.fill()`
221
+ end
222
+
223
+ def image(image, position)
224
+ `#@context.drawImage(#{image.to_n}, #{position.x}, #{position.y})`
225
+ end
226
+
227
+ def image_cropped(image, position, crop_position, crop_size)
228
+ %x{#@context.drawImage(#{image.to_n},
229
+ #{crop_position.x}, #{crop_position.y},
230
+ #{crop_size.x}, #{crop_size.y},
231
+ #{position.x}, #{position.y},
232
+ #{crop_size.x}, #{crop_size.y})}
233
+ end
234
+
235
+ def fill_text(text, position)
236
+ `#@context.fillText(#{text}, #{position.x}, #{position.y})`
237
+ end
238
+
239
+ def stroke_text(text, position)
240
+ `#@context.strokeText(#{text}, #{position.x}, #{position.y})`
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,23 @@
1
+ module Yeah
2
+ module Web
3
+ class Image < Asset
4
+ def size
5
+ V[`#@native.width`, `#@native.height`]
6
+ end
7
+
8
+ def width
9
+ `#@native.width`
10
+ end
11
+
12
+ def height
13
+ `#@native.height`
14
+ end
15
+
16
+ private
17
+
18
+ def setup_native
19
+ `#@native = new Image();`
20
+ end
21
+ end
22
+ end
23
+ end