ruby2d 0.11.2 → 0.12.0

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 (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