ruby2d 0.11.2 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (231) hide show
  1. checksums.yaml +4 -4
  2. data/assets/include/GLES2/gl2.h +656 -0
  3. data/assets/include/GLES2/gl2ext.h +3949 -0
  4. data/assets/include/GLES2/gl2ext_angle.h +701 -0
  5. data/assets/include/GLES2/gl2platform.h +27 -0
  6. data/assets/include/GLES3/gl3.h +1192 -0
  7. data/assets/include/GLES3/gl31.h +1507 -0
  8. data/assets/include/GLES3/gl32.h +1808 -0
  9. data/assets/include/GLES3/gl3platform.h +27 -0
  10. data/assets/include/KHR/khrplatform.h +290 -0
  11. data/assets/include/SDL2/SDL.h +1 -0
  12. data/assets/include/SDL2/SDL_assert.h +4 -2
  13. data/assets/include/SDL2/SDL_atomic.h +20 -0
  14. data/assets/include/SDL2/SDL_audio.h +40 -4
  15. data/assets/include/SDL2/SDL_blendmode.h +4 -6
  16. data/assets/include/SDL2/SDL_clipboard.h +47 -0
  17. data/assets/include/SDL2/SDL_config.h +6 -2
  18. data/assets/include/SDL2/SDL_config_android.h +2 -0
  19. data/assets/include/SDL2/SDL_config_emscripten.h +2 -0
  20. data/assets/include/SDL2/SDL_config_iphoneos.h +3 -1
  21. data/assets/include/SDL2/SDL_config_macosx.h +3 -6
  22. data/assets/include/SDL2/SDL_config_minimal.h +18 -11
  23. data/assets/include/SDL2/SDL_config_ngage.h +89 -0
  24. data/assets/include/SDL2/SDL_config_os2.h +5 -3
  25. data/assets/include/SDL2/SDL_config_pandora.h +1 -0
  26. data/assets/include/SDL2/SDL_config_windows.h +71 -45
  27. data/assets/include/SDL2/SDL_config_wingdk.h +253 -0
  28. data/assets/include/SDL2/SDL_config_winrt.h +11 -49
  29. data/assets/include/SDL2/SDL_config_xbox.h +235 -0
  30. data/assets/include/SDL2/SDL_cpuinfo.h +39 -4
  31. data/assets/include/SDL2/SDL_egl.h +59 -9
  32. data/assets/include/SDL2/SDL_endian.h +34 -3
  33. data/assets/include/SDL2/SDL_events.h +32 -1
  34. data/assets/include/SDL2/SDL_filesystem.h +5 -1
  35. data/assets/include/SDL2/SDL_gamecontroller.h +78 -5
  36. data/assets/include/SDL2/SDL_guid.h +100 -0
  37. data/assets/include/SDL2/SDL_hints.h +645 -43
  38. data/assets/include/SDL2/SDL_image.h +2045 -33
  39. data/assets/include/SDL2/SDL_joystick.h +127 -7
  40. data/assets/include/SDL2/SDL_keyboard.h +38 -1
  41. data/assets/include/SDL2/SDL_keycode.h +6 -1
  42. data/assets/include/SDL2/SDL_log.h +2 -2
  43. data/assets/include/SDL2/SDL_main.h +42 -2
  44. data/assets/include/SDL2/SDL_metal.h +2 -1
  45. data/assets/include/SDL2/SDL_mixer.h +2529 -396
  46. data/assets/include/SDL2/SDL_mouse.h +12 -1
  47. data/assets/include/SDL2/SDL_opengl.h +0 -51
  48. data/assets/include/SDL2/SDL_opengl_glext.h +2260 -231
  49. data/assets/include/SDL2/SDL_opengles2_gl2.h +374 -339
  50. data/assets/include/SDL2/SDL_opengles2_gl2ext.h +3479 -1496
  51. data/assets/include/SDL2/SDL_opengles2_gl2platform.h +6 -9
  52. data/assets/include/SDL2/SDL_opengles2_khrplatform.h +43 -14
  53. data/assets/include/SDL2/SDL_platform.h +32 -6
  54. data/assets/include/SDL2/SDL_rect.h +154 -2
  55. data/assets/include/SDL2/SDL_render.h +46 -17
  56. data/assets/include/SDL2/SDL_revision.h +4 -0
  57. data/assets/include/SDL2/SDL_rwops.h +1 -15
  58. data/assets/include/SDL2/SDL_scancode.h +46 -21
  59. data/assets/include/SDL2/SDL_sensor.h +24 -3
  60. data/assets/include/SDL2/SDL_stdinc.h +119 -8
  61. data/assets/include/SDL2/SDL_surface.h +3 -1
  62. data/assets/include/SDL2/SDL_system.h +66 -6
  63. data/assets/include/SDL2/SDL_syswm.h +2 -0
  64. data/assets/include/SDL2/SDL_test_common.h +1 -0
  65. data/assets/include/SDL2/SDL_test_font.h +90 -3
  66. data/assets/include/SDL2/SDL_thread.h +3 -3
  67. data/assets/include/SDL2/SDL_touch.h +8 -0
  68. data/assets/include/SDL2/SDL_ttf.h +2084 -155
  69. data/assets/include/SDL2/SDL_version.h +19 -3
  70. data/assets/include/SDL2/SDL_video.h +71 -9
  71. data/assets/include/SDL2/begin_code.h +4 -4
  72. data/assets/include/mrbconf.h +15 -17
  73. data/assets/include/mruby/array.h +8 -21
  74. data/assets/include/mruby/boxing_nan.h +115 -86
  75. data/assets/include/mruby/boxing_word.h +104 -78
  76. data/assets/include/mruby/common.h +6 -0
  77. data/assets/include/mruby/compile.h +3 -4
  78. data/assets/include/mruby/debug.h +4 -2
  79. data/assets/include/mruby/dump.h +5 -2
  80. data/assets/include/mruby/error.h +12 -2
  81. data/assets/include/mruby/gc.h +2 -0
  82. data/assets/include/mruby/hash.h +1 -3
  83. data/assets/include/mruby/irep.h +4 -4
  84. data/assets/include/mruby/numeric.h +21 -13
  85. data/assets/include/mruby/opcode.h +30 -0
  86. data/assets/include/mruby/ops.h +99 -101
  87. data/assets/include/mruby/presym/scanning.h +15 -9
  88. data/assets/include/mruby/proc.h +4 -2
  89. data/assets/include/mruby/string.h +3 -24
  90. data/assets/include/mruby/value.h +80 -40
  91. data/assets/include/mruby/variable.h +0 -15
  92. data/assets/include/mruby/version.h +5 -5
  93. data/assets/include/mruby.h +86 -16
  94. data/assets/macos/universal/bin/mrbc +0 -0
  95. data/assets/macos/universal/lib/libFLAC.a +0 -0
  96. data/assets/macos/universal/lib/libSDL2.a +0 -0
  97. data/assets/macos/universal/lib/libSDL2_image.a +0 -0
  98. data/assets/macos/universal/lib/libSDL2_mixer.a +0 -0
  99. data/assets/macos/universal/lib/libSDL2_ttf.a +0 -0
  100. data/assets/macos/universal/lib/libavif.a +0 -0
  101. data/assets/macos/universal/lib/libbrotlicommon-static.a +0 -0
  102. data/assets/macos/universal/lib/libbrotlidec-static.a +0 -0
  103. data/assets/macos/universal/lib/libfreetype.a +0 -0
  104. data/assets/macos/universal/lib/libgraphite2.a +0 -0
  105. data/assets/macos/universal/lib/libharfbuzz.a +0 -0
  106. data/assets/macos/universal/lib/libhwy.a +0 -0
  107. data/assets/macos/universal/lib/libjpeg.a +0 -0
  108. data/assets/macos/universal/lib/libjxl.a +0 -0
  109. data/assets/macos/universal/lib/libmodplug.a +0 -0
  110. data/assets/macos/universal/lib/libmpg123.a +0 -0
  111. data/assets/macos/universal/lib/libmruby.a +0 -0
  112. data/assets/macos/universal/lib/libogg.a +0 -0
  113. data/assets/macos/universal/lib/libpng.a +0 -0
  114. data/assets/macos/universal/lib/libtiff.a +0 -0
  115. data/assets/macos/universal/lib/libvorbis.a +0 -0
  116. data/assets/macos/universal/lib/libvorbisfile.a +0 -0
  117. data/assets/macos/universal/lib/libwebp.a +0 -0
  118. data/assets/macos/universal/lib/libzstd.a +0 -0
  119. data/assets/wasm/libmruby.a +0 -0
  120. data/assets/wasm/template.html +52 -4
  121. data/assets/windows/mingw-w64-ucrt-x86_64/bin/mrbc.exe +0 -0
  122. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
  123. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libLerc.a +0 -0
  124. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
  125. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_image.a +0 -0
  126. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
  127. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_ttf.a +0 -0
  128. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlicommon.a +0 -0
  129. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlidec.a +0 -0
  130. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbz2.a +0 -0
  131. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libdeflate.a +0 -0
  132. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libfreetype.a +0 -0
  133. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libglew32.a +0 -0
  134. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libgraphite2.a +0 -0
  135. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libharfbuzz.a +0 -0
  136. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libhwy.a +0 -0
  137. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjbig.a +0 -0
  138. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjpeg.a +0 -0
  139. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjxl.a +0 -0
  140. data/assets/windows/mingw-w64-ucrt-x86_64/lib/liblzma.a +0 -0
  141. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a +0 -0
  142. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
  143. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmruby.a +0 -0
  144. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a +0 -0
  145. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
  146. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a +0 -0
  147. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng.a +0 -0
  148. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
  149. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libssp.a +1 -0
  150. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
  151. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libtiff.a +0 -0
  152. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a +0 -0
  153. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a +0 -0
  154. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libwebp.a +0 -0
  155. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
  156. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libzstd.a +0 -0
  157. data/assets/windows/mingw-w64-x86_64/bin/mrbc.exe +0 -0
  158. data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
  159. data/assets/windows/mingw-w64-x86_64/lib/libLerc.a +0 -0
  160. data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
  161. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_image.a +0 -0
  162. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
  163. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_ttf.a +0 -0
  164. data/assets/windows/mingw-w64-x86_64/lib/libbrotlicommon.a +0 -0
  165. data/assets/windows/mingw-w64-x86_64/lib/libbrotlidec.a +0 -0
  166. data/assets/windows/mingw-w64-x86_64/lib/libdeflate.a +0 -0
  167. data/assets/windows/mingw-w64-x86_64/lib/libfreetype.a +0 -0
  168. data/assets/windows/mingw-w64-x86_64/lib/libglew32.a +0 -0
  169. data/assets/windows/mingw-w64-x86_64/lib/libharfbuzz.a +0 -0
  170. data/assets/windows/mingw-w64-x86_64/lib/libhwy.a +0 -0
  171. data/assets/windows/mingw-w64-x86_64/lib/libjpeg.a +0 -0
  172. data/assets/windows/mingw-w64-x86_64/lib/libjxl.a +0 -0
  173. data/assets/windows/mingw-w64-x86_64/lib/liblzma.a +0 -0
  174. data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
  175. data/assets/windows/mingw-w64-x86_64/lib/libmruby.a +0 -0
  176. data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
  177. data/assets/windows/mingw-w64-x86_64/lib/libpng.a +0 -0
  178. data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
  179. data/assets/windows/mingw-w64-x86_64/lib/libssp.a +0 -0
  180. data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
  181. data/assets/windows/mingw-w64-x86_64/lib/libtiff.a +0 -0
  182. data/assets/windows/mingw-w64-x86_64/lib/libwebp.a +0 -0
  183. data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
  184. data/assets/windows/mingw-w64-x86_64/lib/libzstd.a +0 -0
  185. data/ext/ruby2d/canvas.c +540 -0
  186. data/ext/ruby2d/extconf.rb +39 -21
  187. data/ext/ruby2d/gl.c +3 -3
  188. data/ext/ruby2d/image.c +7 -7
  189. data/ext/ruby2d/ruby2d.c +741 -24
  190. data/ext/ruby2d/ruby2d.h +66 -3
  191. data/ext/ruby2d/sound.c +16 -2
  192. data/lib/ruby2d/canvas.rb +315 -0
  193. data/lib/ruby2d/circle.rb +30 -15
  194. data/lib/ruby2d/cli/build.rb +11 -4
  195. data/lib/ruby2d/cli/enable_console.rb +3 -1
  196. data/lib/ruby2d/color.rb +133 -77
  197. data/lib/ruby2d/core.rb +32 -0
  198. data/lib/ruby2d/dsl.rb +38 -32
  199. data/lib/ruby2d/exceptions.rb +2 -1
  200. data/lib/ruby2d/font.rb +97 -62
  201. data/lib/ruby2d/image.rb +48 -27
  202. data/lib/ruby2d/line.rb +84 -45
  203. data/lib/ruby2d/music.rb +33 -23
  204. data/lib/ruby2d/pixel.rb +10 -9
  205. data/lib/ruby2d/pixmap.rb +39 -0
  206. data/lib/ruby2d/pixmap_atlas.rb +56 -0
  207. data/lib/ruby2d/quad.rb +98 -49
  208. data/lib/ruby2d/rectangle.rb +35 -36
  209. data/lib/ruby2d/renderable.rb +7 -6
  210. data/lib/ruby2d/sound.rb +23 -17
  211. data/lib/ruby2d/sprite.rb +181 -140
  212. data/lib/ruby2d/square.rb +21 -20
  213. data/lib/ruby2d/text.rb +47 -19
  214. data/lib/ruby2d/texture.rb +13 -3
  215. data/lib/ruby2d/tileset.rb +97 -44
  216. data/lib/ruby2d/triangle.rb +91 -42
  217. data/lib/ruby2d/version.rb +3 -1
  218. data/lib/ruby2d/vertices.rb +81 -45
  219. data/lib/ruby2d/window.rb +508 -371
  220. data/lib/ruby2d.rb +11 -29
  221. metadata +84 -16
  222. data/assets/include/SDL2/SDL_config_psp.h +0 -165
  223. data/assets/include/SDL2/SDL_config_wiz.h +0 -154
  224. data/assets/include/glew.h +0 -23686
  225. data/assets/macos/universal/lib/libpng16.a +0 -0
  226. data/assets/wasm/build_config.rb +0 -13
  227. data/assets/windows/glew/README.md +0 -10
  228. data/assets/windows/glew/glew.h +0 -23686
  229. data/assets/windows/glew/libglew32.a +0 -0
  230. data/assets/windows/mingw-w64-x86_64/lib/libpng16.a +0 -0
  231. data/lib/ruby2d/entity.rb +0 -17
data/lib/ruby2d/image.rb CHANGED
@@ -1,48 +1,69 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Image
2
4
 
3
5
  module Ruby2D
6
+ # Images in many popular formats can be drawn in the window.
7
+ # To draw an image in the window, use the following, providing the image file path:
8
+ # +Image.new('star.png')+
4
9
  class Image
5
10
  include Renderable
6
11
 
7
12
  attr_reader :path
8
13
  attr_accessor :x, :y, :width, :height, :rotate, :data
9
14
 
10
- def self.load_image(path)
11
- unless File.exist? path
12
- raise Error, "Cannot find image file `#{path}`"
13
- end
14
-
15
- ext_load_image(path)
15
+ # Load an image +path+ and return a Texture, using a pixmap atlas if provided
16
+ # @param path [#to_s] The location of the file to load as an image.
17
+ # @param atlas [PixmapAtlas] Pixmap atlas to use to manage the image file
18
+ # @return [Texture] loaded
19
+ def self.load_image_as_texture(path, atlas:)
20
+ pixmap = if atlas
21
+ atlas.load_and_keep_image(path, as: path)
22
+ else
23
+ Pixmap.new path
24
+ end
25
+ pixmap.texture
16
26
  end
17
27
 
18
- def initialize(path, opts = {})
19
- @path = path
28
+ # Create an Image
29
+ # @param path [#to_s] The location of the file to load as an image.
30
+ # @param width [Numeric] The +width+ of image, or default is width from image file
31
+ # @param height [Numeric] The +height+ of image, or default is height from image file
32
+ # @param x [Numeric]
33
+ # @param y [Numeric]
34
+ # @param z [Numeric]
35
+ # @param rotate [Numeric] Angle, default is 0
36
+ # @param color [Numeric] (or +colour+) Tint the image when rendering
37
+ # @param opacity [Numeric] Opacity of the image when rendering
38
+ # @param show [Boolean] If +true+ the image is added to +Window+ automatically.
39
+ def initialize(path, atlas: nil,
40
+ width: nil, height: nil, x: 0, y: 0, z: 0,
41
+ rotate: 0, color: nil, colour: nil,
42
+ opacity: nil, show: true)
43
+ @path = path.to_s
20
44
 
21
- @texture = Texture.new(*Image.load_image(@path))
22
- @width = opts[:width] || @texture.width
23
- @height = opts[:height] || @texture.height
45
+ # Consider input pixmap atlas if supplied to load image file
46
+ @texture = Image.load_image_as_texture @path, atlas: atlas
47
+ @width = width || @texture.width
48
+ @height = height || @texture.height
24
49
 
25
- @x = opts[:x] || 0
26
- @y = opts[:y] || 0
27
- @z = opts[:z] || 0
28
- @rotate = opts[:rotate] || 0
29
- self.color = opts[:color] || 'white'
30
- self.color.opacity = opts[:opacity] if opts[:opacity]
50
+ @x = x
51
+ @y = y
52
+ @z = z
53
+ @rotate = rotate
54
+ self.color = color || colour || 'white'
55
+ self.color.opacity = opacity unless opacity.nil?
31
56
 
32
- unless opts[:show] == false then add end
57
+ add if show
33
58
  end
34
59
 
35
- def draw(opts = {})
60
+ def draw(x: 0, y: 0, width: nil, height: nil, rotate: 0, color: nil, colour: nil)
36
61
  Window.render_ready_check
37
62
 
38
- opts[:width] = opts[:width] || @width
39
- opts[:height] = opts[:height] || @height
40
- opts[:rotate] = opts[:rotate] || @rotate
41
- unless opts[:color]
42
- opts[:color] = [1.0, 1.0, 1.0, 1.0]
43
- end
44
-
45
- render(x: opts[:x], y: opts[:y], width: opts[:width], height: opts[:height], color: Color.new(opts[:color]), rotate: opts[:rotate])
63
+ render(x: x, y: y, width:
64
+ width || @width, height: height || @height,
65
+ color: Color.new(color || colour || 'white'),
66
+ rotate: rotate || @rotate)
46
67
  end
47
68
 
48
69
  private
data/lib/ruby2d/line.rb CHANGED
@@ -1,26 +1,52 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Line
2
4
 
3
5
  module Ruby2D
6
+ # A line between two points.
4
7
  class Line
5
8
  include Renderable
6
9
 
7
10
  attr_accessor :x1, :x2, :y1, :y2, :width
8
11
 
9
- def initialize(opts = {})
10
- @x1 = opts[:x1] || 0
11
- @y1 = opts[:y1] || 0
12
- @x2 = opts[:x2] || 100
13
- @y2 = opts[:y2] || 100
14
- @z = opts[:z] || 0
15
- @width = opts[:width] || 2
16
- self.color = opts[:color] || 'white'
17
- self.color.opacity = opts[:opacity] if opts[:opacity]
12
+ # Create an Line
13
+ # @param [Numeric] x1
14
+ # @param [Numeric] y1
15
+ # @param [Numeric] x2
16
+ # @param [Numeric] y2
17
+ # @param [Numeric] width The +width+ or thickness of the line
18
+ # @param [Numeric] z
19
+ # @param [String, Array] color A single colour or an array of exactly 4 colours
20
+ # @param [Numeric] opacity Opacity of the image when rendering
21
+ # @raise [ArgumentError] if an array of colours does not have 4 entries
22
+ def initialize(x1: 0, y1: 0, x2: 100, y2: 100, z: 0,
23
+ width: 2, color: nil, colour: nil, opacity: nil)
24
+ @x1 = x1
25
+ @y1 = y1
26
+ @x2 = x2
27
+ @y2 = y2
28
+ @z = z
29
+ @width = width
30
+ self.color = color || colour || 'white'
31
+ self.color.opacity = opacity unless opacity.nil?
18
32
  add
19
33
  end
20
34
 
21
- def color=(c)
22
- @color = Color.set(c)
23
- update_color(@color)
35
+ # Change the colour of the line
36
+ # @param [String, Array] color A single colour or an array of exactly 4 colours
37
+ # @raise [ArgumentError] if an array of colours does not have 4 entries
38
+ def color=(color)
39
+ # convert to Color or Color::Set
40
+ color = Color.set(color)
41
+
42
+ # require 4 colours if multiple colours provided
43
+ if color.is_a?(Color::Set) && color.length != 4
44
+ raise ArgumentError,
45
+ "`#{self.class}` requires 4 colors, one for each vertex. #{color.length} were given."
46
+ end
47
+
48
+ @color = color # converted above
49
+ invalidate_color_components
24
50
  end
25
51
 
26
52
  # Return the length of the line
@@ -33,57 +59,70 @@ module Ruby2D
33
59
  # the width. For reference:
34
60
  # https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
35
61
  def contains?(x, y)
36
- points_distance(x1, y1, x, y) <= length &&
37
- points_distance(x2, y2, x, y) <= length &&
38
- (((@y2 - @y1) * x - (@x2 - @x1) * y + @x2 * @y1 - @y2 * @x1).abs / length) <= 0.5 * @width
62
+ line_len = length
63
+ points_distance(@x1, @y1, x, y) <= line_len &&
64
+ points_distance(@x2, @y2, x, y) <= line_len &&
65
+ (((@y2 - @y1) * x - (@x2 - @x1) * y + @x2 * @y1 - @y2 * @x1).abs / line_len) <= 0.5 * @width
39
66
  end
40
67
 
41
- def self.draw(opts = {})
68
+ # Draw a line without creating a Line
69
+ # @param [Numeric] x1
70
+ # @param [Numeric] y1
71
+ # @param [Numeric] x2
72
+ # @param [Numeric] y2
73
+ # @param [Numeric] width The +width+ or thickness of the line
74
+ # @param [Array] colors An array or 4 arrays of colour components.
75
+ def self.draw(x1:, y1:, x2:, y2:, width:, color:)
42
76
  Window.render_ready_check
43
77
 
44
78
  ext_draw([
45
- opts[:x1], opts[:y1], opts[:x2], opts[:y2], opts[:width],
46
- opts[:color][0][0], opts[:color][0][1], opts[:color][0][2], opts[:color][0][3],
47
- opts[:color][1][0], opts[:color][1][1], opts[:color][1][2], opts[:color][1][3],
48
- opts[:color][2][0], opts[:color][2][1], opts[:color][2][2], opts[:color][2][3],
49
- opts[:color][3][0], opts[:color][3][1], opts[:color][3][2], opts[:color][3][3]
50
- ])
79
+ x1, y1, x2, y2, width,
80
+ # splat each colour's components
81
+ *color[0], *color[1], *color[2], *color[3]
82
+ ])
51
83
  end
52
84
 
53
85
  private
54
86
 
55
87
  def render
56
88
  self.class.ext_draw([
57
- @x1, @y1, @x2, @y2, @width,
58
- @c1.r, @c1.g, @c1.b, @c1.a,
59
- @c2.r, @c2.g, @c2.b, @c2.a,
60
- @c3.r, @c3.g, @c3.b, @c3.a,
61
- @c4.r, @c4.g, @c4.b, @c4.a
62
- ])
89
+ @x1, @y1, @x2, @y2, @width,
90
+ # splat the colour components from helper
91
+ *color_components
92
+ ])
63
93
  end
64
94
 
65
95
  # Calculate the distance between two points
66
96
  def points_distance(x1, y1, x2, y2)
67
- Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
97
+ Math.sqrt((x1 - x2).abs2 + (y1 - y2).abs2)
68
98
  end
69
99
 
70
- def update_color(c)
71
- if c.is_a? Color::Set
72
- if c.length == 4
73
- @c1 = c[0]
74
- @c2 = c[1]
75
- @c3 = c[2]
76
- @c4 = c[3]
77
- else
78
- raise ArgumentError, "`#{self.class}` requires 4 colors, one for each vertex. #{c.length} were given."
79
- end
80
- else
81
- @c1 = c
82
- @c2 = c
83
- @c3 = c
84
- @c4 = c
85
- end
100
+ # Return colours as a memoized flattened array of 4 x colour components
101
+ def color_components
102
+ check_if_opacity_changed
103
+ @color_components ||= if @color.is_a? Color::Set
104
+ # Splat the colours from the set; see +def color=+ where colour set
105
+ # size is enforced
106
+ [
107
+ *@color[0].to_a, *@color[1].to_a, *@color[2].to_a, *@color[3].to_a
108
+ ]
109
+ else
110
+ # All vertex colours are the same
111
+ c_a = @color.to_a
112
+ [
113
+ *c_a, *c_a, *c_a, *c_a
114
+ ]
115
+ end
116
+ end
117
+
118
+ # Invalidate memoized colour components if opacity has been changed via +color=+
119
+ def check_if_opacity_changed
120
+ @color_components = nil if @color_components && @color_components[3] != @color.opacity
86
121
  end
87
122
 
123
+ # Invalidate the memoized colour components. Called when Line's colour is changed
124
+ def invalidate_color_components
125
+ @color_components = nil
126
+ end
88
127
  end
89
128
  end
data/lib/ruby2d/music.rb CHANGED
@@ -1,20 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Music
2
4
 
3
5
  module Ruby2D
6
+ # Music is for longer pieces which can be played, paused, stopped, resumed,
7
+ # and faded out, like a background soundtrack.
4
8
  class Music
5
-
6
9
  attr_reader :path
7
10
  attr_accessor :loop, :data
8
11
 
9
- def initialize(path, opts = {})
10
- unless File.exist? path
11
- raise Error, "Cannot find audio file `#{path}`"
12
- end
12
+ #
13
+ # Load music from a file
14
+ # @param [String] path File to load the music from
15
+ # @param [true, false] loop If +true+ playback will loop automatically, default is +false+
16
+ # @raise [Error] if file cannot be found or music could not be successfully loaded.
17
+ def initialize(path, loop: false)
18
+ raise Error, "Cannot find audio file `#{path}`" unless File.exist? path
19
+
13
20
  @path = path
14
- @loop = opts[:loop] || false
15
- unless ext_init(@path)
16
- raise Error, "Music `#{@path}` cannot be created"
17
- end
21
+ @loop = loop
22
+ raise Error, "Music `#{@path}` cannot be created" unless ext_init(@path)
18
23
  end
19
24
 
20
25
  # Play the music
@@ -37,31 +42,36 @@ module Ruby2D
37
42
  ext_stop
38
43
  end
39
44
 
40
- # Returns the volume, in percentage
41
- def self.volume
42
- self.ext_get_volume
43
- end
45
+ class << self
46
+ # Returns the volume, in percentage
47
+ def volume
48
+ ext_get_volume
49
+ end
44
50
 
45
- # Set music volume, 0 to 100%
46
- def self.volume=(v)
47
- # If a negative value, volume will be 0
48
- if v < 0 then v = 0 end
49
- self.ext_set_volume(v)
51
+ # Set music volume, 0 to 100%
52
+ def volume=(volume)
53
+ # Clamp value to between 0-100
54
+ ext_set_volume(volume.clamp(0, 100))
55
+ end
50
56
  end
51
57
 
52
58
  # Alias instance methods to class methods
53
- def volume; Music.volume end
54
- def volume=(v); Music.volume=(v) end
59
+ def volume
60
+ Music.volume
61
+ end
62
+
63
+ def volume=(volume)
64
+ Music.volume = (volume)
65
+ end
55
66
 
56
67
  # Fade out music over provided milliseconds
57
- def fadeout(ms)
58
- ext_fadeout(ms)
68
+ def fadeout(milliseconds)
69
+ ext_fadeout(milliseconds)
59
70
  end
60
71
 
61
72
  # Returns the length in seconds
62
73
  def length
63
74
  ext_length
64
75
  end
65
-
66
76
  end
67
77
  end
data/lib/ruby2d/pixel.rb CHANGED
@@ -1,17 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Pixel
2
4
 
3
5
  module Ruby2D
6
+ # Draw a single pixel by calling +Pixel.draw(...)+
4
7
  class Pixel
8
+ def self.draw(x:, y:, size:, color:)
9
+ color = color.to_a if color.is_a? Color
5
10
 
6
- def self.draw(opts = {})
7
- ext_draw([
8
- opts[:x] , opts[:y],
9
- opts[:x] + opts[:size], opts[:y],
10
- opts[:x] + opts[:size], opts[:y] + opts[:size],
11
- opts[:x] , opts[:y] + opts[:size],
12
- opts[:color][0], opts[:color][1], opts[:color][2], opts[:color][3]
13
- ])
11
+ ext_draw([x, y,
12
+ x + size, y,
13
+ x + size, y + size,
14
+ x, y + size,
15
+ color[0], color[1], color[2], color[3]])
14
16
  end
15
-
16
17
  end
17
18
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ruby2D::Pixmap
4
+
5
+ module Ruby2D
6
+ # Error when failed to load an image
7
+ class InvalidImageFileError < Ruby2D::Error
8
+ def initialize(file_path)
9
+ super("Failed to load image file: #{file_path}")
10
+ end
11
+ end
12
+
13
+ # Error finding image file
14
+ class UnknownImageFileError < Ruby2D::Error
15
+ def initialize(file_path)
16
+ super "Cannot find image file `#{file_path}`"
17
+ end
18
+ end
19
+
20
+ #
21
+ # A pixmap represents an image made up of pixel data of fixed width and height.
22
+ class Pixmap
23
+ attr_reader :width, :height, :path
24
+
25
+ def initialize(file_path)
26
+ file_path = file_path.to_s
27
+ raise UnknownImageFileError, file_path unless File.exist? file_path
28
+
29
+ ext_load_pixmap(file_path)
30
+ raise InvalidImageFileError, file_path unless @ext_pixel_data
31
+
32
+ @path = file_path
33
+ end
34
+
35
+ def texture
36
+ @texture ||= Texture.new(@ext_pixel_data, @width, @height)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ruby2D::PixmapAtlas
4
+
5
+ module Ruby2D
6
+ #
7
+ # A pixmap is a 2D grid of pixel data of fixed width and height. A pixmap atlas
8
+ # is a dictionary of named pixmaps where each named pixmap is loaded once and can be re-used
9
+ # multiple times without the overhead of repeated loading and multiple copies.
10
+ class PixmapAtlas
11
+ def initialize
12
+ @atlas = {} # empty map
13
+ end
14
+
15
+ # Empty the atlas, eventually releasing all the loaded
16
+ # pixmaps (except for any that are referenced elsewhere)
17
+ def clear
18
+ @atlas.clear
19
+ end
20
+
21
+ # Find a previosly loaded Pixmap in the atlas by name
22
+ #
23
+ # @param [String] name
24
+ # @return [Pixmap, nil]
25
+ def [](name)
26
+ @atlas[name]
27
+ end
28
+
29
+ # Get the number of Pixmaps in the atlas
30
+ def count
31
+ @atlas.count
32
+ end
33
+
34
+ # Iterate through each Pixmap in the atlas
35
+ def each(&block)
36
+ @atlas.each(&block)
37
+ end
38
+
39
+ # Load a pixmap from an image +file_path+ and store it +as+ named for later lookup.
40
+ #
41
+ # @param [String] file_path The path to the image file to load as a +Pixmap+
42
+ # @param [String] as The name to associated with the Pixmap; if +nil+ then +file_path+ is used +as+ the name
43
+ #
44
+ # @raise [Pixmap::InvalidImageFileError] if the image file cannot be loaded
45
+ # @return [Pixmap] the new (or existing) Pixmap
46
+ def load_and_keep_image(file_path, as: nil)
47
+ name = as || file_path
48
+ if @atlas.member? name
49
+ @atlas[name]
50
+ else
51
+ pixmap = Pixmap.new file_path
52
+ @atlas[name] = pixmap
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/ruby2d/quad.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Quad
2
4
 
3
5
  module Ruby2D
6
+ # A quadrilateral based on four points in clockwise order starting at the top left.
4
7
  class Quad
5
8
  include Renderable
6
9
 
@@ -9,29 +12,55 @@ module Ruby2D
9
12
  # x2,y2 == top right
10
13
  # x3,y3 == bottom right
11
14
  # x4,y4 == bottom left
12
- attr_accessor :x1, :y1, :c1,
13
- :x2, :y2, :c2,
14
- :x3, :y3, :c3,
15
- :x4, :y4, :c4
16
-
17
- def initialize(opts = {})
18
- @x1 = opts[:x1] || 0
19
- @y1 = opts[:y1] || 0
20
- @x2 = opts[:x2] || 100
21
- @y2 = opts[:y2] || 0
22
- @x3 = opts[:x3] || 100
23
- @y3 = opts[:y3] || 100
24
- @x4 = opts[:x4] || 0
25
- @y4 = opts[:y4] || 100
26
- @z = opts[:z] || 0
27
- self.color = opts[:color] || 'white'
28
- self.color.opacity = opts[:opacity] if opts[:opacity]
15
+ attr_accessor :x1, :y1,
16
+ :x2, :y2,
17
+ :x3, :y3,
18
+ :x4, :y4
19
+
20
+ # Create an quadrilateral
21
+ # @param [Numeric] x1
22
+ # @param [Numeric] y1
23
+ # @param [Numeric] x2
24
+ # @param [Numeric] y2
25
+ # @param [Numeric] x3
26
+ # @param [Numeric] y3
27
+ # @param [Numeric] x4
28
+ # @param [Numeric] y4
29
+ # @param [Numeric] z
30
+ # @param [String, Array] color A single colour or an array of exactly 4 colours
31
+ # @param [Numeric] opacity Opacity of the image when rendering
32
+ # @raise [ArgumentError] if an array of colours does not have 4 entries
33
+ def initialize(x1: 0, y1: 0, x2: 100, y2: 0, x3: 100, y3: 100, x4: 0, y4: 100,
34
+ z: 0, color: nil, colour: nil, opacity: nil)
35
+ @x1 = x1
36
+ @y1 = y1
37
+ @x2 = x2
38
+ @y2 = y2
39
+ @x3 = x3
40
+ @y3 = y3
41
+ @x4 = x4
42
+ @y4 = y4
43
+ @z = z
44
+ self.color = color || colour || 'white'
45
+ self.color.opacity = opacity unless opacity.nil?
29
46
  add
30
47
  end
31
48
 
32
- def color=(c)
33
- @color = Color.set(c)
34
- update_color(@color)
49
+ # Change the colour of the line
50
+ # @param [String, Array] color A single colour or an array of exactly 4 colours
51
+ # @raise [ArgumentError] if an array of colours does not have 4 entries
52
+ def color=(color)
53
+ # convert to Color or Color::Set
54
+ color = Color.set(color)
55
+
56
+ # require 4 colours if multiple colours provided
57
+ if color.is_a?(Color::Set) && color.length != 4
58
+ raise ArgumentError,
59
+ "`#{self.class}` requires 4 colors, one for each vertex. #{color.length} were given."
60
+ end
61
+
62
+ @color = color # converted above
63
+ invalidate_color_components
35
64
  end
36
65
 
37
66
  # The logic is the same as for a triangle
@@ -48,49 +77,69 @@ module Ruby2D
48
77
  questioned_area <= self_area
49
78
  end
50
79
 
51
- def self.draw(opts = {})
80
+ # Draw a line without creating a Line
81
+ # @param [Numeric] x1
82
+ # @param [Numeric] y1
83
+ # @param [Numeric] x2
84
+ # @param [Numeric] y2
85
+ # @param [Numeric] x3
86
+ # @param [Numeric] y3
87
+ # @param [Numeric] x4
88
+ # @param [Numeric] y4
89
+ # @param color [Array<Array<float,float,float,float>>] An array of 4 array of colour components
90
+ # (e.g. [[1.0, 0, 0, 1.0], ...])
91
+ def self.draw(x1:, y1:, x2:, y2:, x3:, y3:, x4:, y4:, color:)
52
92
  Window.render_ready_check
53
-
54
93
  ext_draw([
55
- opts[:x1], opts[:y1], opts[:color][0][0], opts[:color][0][1], opts[:color][0][2], opts[:color][0][3],
56
- opts[:x2], opts[:y2], opts[:color][1][0], opts[:color][1][1], opts[:color][1][2], opts[:color][1][3],
57
- opts[:x3], opts[:y3], opts[:color][2][0], opts[:color][2][1], opts[:color][2][2], opts[:color][2][3],
58
- opts[:x4], opts[:y4], opts[:color][3][0], opts[:color][3][1], opts[:color][3][2], opts[:color][3][3]
59
- ])
94
+ x1, y1, *color[0], # splat the colour components
95
+ x2, y2, *color[1],
96
+ x3, y3, *color[2],
97
+ x4, y4, *color[3]
98
+ ])
60
99
  end
61
100
 
62
101
  private
63
102
 
64
103
  def render
104
+ color_comp_arrays = color_components
65
105
  self.class.ext_draw([
66
- @x1, @y1, @c1.r, @c1.g, @c1.b, @c1.a,
67
- @x2, @y2, @c2.r, @c2.g, @c2.b, @c2.a,
68
- @x3, @y3, @c3.r, @c3.g, @c3.b, @c3.a,
69
- @x4, @y4, @c4.r, @c4.g, @c4.b, @c4.a
70
- ])
106
+ @x1, @y1, *color_comp_arrays[0], # splat the colour components
107
+ @x2, @y2, *color_comp_arrays[1],
108
+ @x3, @y3, *color_comp_arrays[2],
109
+ @x4, @y4, *color_comp_arrays[3]
110
+ ])
71
111
  end
72
112
 
73
113
  def triangle_area(x1, y1, x2, y2, x3, y3)
74
- (x1*y2 + x2*y3 + x3*y1 - x3*y2 - x1*y3 - x2*y1).abs / 2
114
+ (x1 * y2 + x2 * y3 + x3 * y1 - x3 * y2 - x1 * y3 - x2 * y1).abs / 2
75
115
  end
76
116
 
77
- def update_color(c)
78
- if c.is_a? Color::Set
79
- if c.length == 4
80
- @c1 = c[0]
81
- @c2 = c[1]
82
- @c3 = c[2]
83
- @c4 = c[3]
84
- else
85
- raise ArgumentError, "`#{self.class}` requires 4 colors, one for each vertex. #{c.length} were given."
86
- end
87
- else
88
- @c1 = c
89
- @c2 = c
90
- @c3 = c
91
- @c4 = c
92
- end
117
+ # Return colours as a memoized array of 4 x colour component arrays
118
+ def color_components
119
+ check_if_opacity_changed
120
+ @color_components ||= if @color.is_a? Color::Set
121
+ # Extract colour component arrays; see +def color=+ where colour set
122
+ # size is enforced
123
+ [
124
+ @color[0].to_a, @color[1].to_a, @color[2].to_a, @color[3].to_a
125
+ ]
126
+ else
127
+ # All vertex colours are the same
128
+ c_a = @color.to_a
129
+ [
130
+ c_a, c_a, c_a, c_a
131
+ ]
132
+ end
93
133
  end
94
134
 
135
+ # Invalidate memoized colour components if opacity has been changed via +color=+
136
+ def check_if_opacity_changed
137
+ @color_components = nil if @color_components && @color_components.first[3] != @color.opacity
138
+ end
139
+
140
+ # Invalidate the memoized colour components. Called when Line's colour is changed
141
+ def invalidate_color_components
142
+ @color_components = nil
143
+ end
95
144
  end
96
145
  end