ruby2d 0.11.3 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) 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/template.html +2 -1
  120. data/assets/windows/mingw-w64-ucrt-x86_64/bin/mrbc.exe +0 -0
  121. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
  122. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libLerc.a +0 -0
  123. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
  124. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_image.a +0 -0
  125. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
  126. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_ttf.a +0 -0
  127. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlicommon.a +0 -0
  128. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlidec.a +0 -0
  129. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libdeflate.a +0 -0
  130. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libfreetype.a +0 -0
  131. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libglew32.a +0 -0
  132. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libharfbuzz.a +0 -0
  133. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libhwy.a +0 -0
  134. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjpeg.a +0 -0
  135. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjxl.a +0 -0
  136. data/assets/windows/mingw-w64-ucrt-x86_64/lib/liblzma.a +0 -0
  137. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
  138. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmruby.a +0 -0
  139. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
  140. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng.a +0 -0
  141. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
  142. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libssp.a +0 -0
  143. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
  144. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libtiff.a +0 -0
  145. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libwebp.a +0 -0
  146. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
  147. data/assets/windows/mingw-w64-x86_64/bin/mrbc.exe +0 -0
  148. data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
  149. data/assets/windows/mingw-w64-x86_64/lib/libLerc.a +0 -0
  150. data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
  151. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_image.a +0 -0
  152. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
  153. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_ttf.a +0 -0
  154. data/assets/windows/mingw-w64-x86_64/lib/libbrotlicommon.a +0 -0
  155. data/assets/windows/mingw-w64-x86_64/lib/libbrotlidec.a +0 -0
  156. data/assets/windows/mingw-w64-x86_64/lib/libdeflate.a +0 -0
  157. data/assets/windows/mingw-w64-x86_64/lib/libfreetype.a +0 -0
  158. data/assets/windows/mingw-w64-x86_64/lib/libglew32.a +0 -0
  159. data/assets/windows/mingw-w64-x86_64/lib/libharfbuzz.a +0 -0
  160. data/assets/windows/mingw-w64-x86_64/lib/libhwy.a +0 -0
  161. data/assets/windows/mingw-w64-x86_64/lib/libjpeg.a +0 -0
  162. data/assets/windows/mingw-w64-x86_64/lib/libjxl.a +0 -0
  163. data/assets/windows/mingw-w64-x86_64/lib/liblzma.a +0 -0
  164. data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
  165. data/assets/windows/mingw-w64-x86_64/lib/libmruby.a +0 -0
  166. data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
  167. data/assets/windows/mingw-w64-x86_64/lib/libpng.a +0 -0
  168. data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
  169. data/assets/windows/mingw-w64-x86_64/lib/libssp.a +0 -0
  170. data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
  171. data/assets/windows/mingw-w64-x86_64/lib/libtiff.a +0 -0
  172. data/assets/windows/mingw-w64-x86_64/lib/libwebp.a +0 -0
  173. data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
  174. data/assets/windows/mingw-w64-x86_64/lib/libzstd.a +0 -0
  175. data/ext/ruby2d/canvas.c +540 -0
  176. data/ext/ruby2d/extconf.rb +33 -20
  177. data/ext/ruby2d/gl.c +3 -3
  178. data/ext/ruby2d/image.c +7 -7
  179. data/ext/ruby2d/ruby2d.c +741 -24
  180. data/ext/ruby2d/ruby2d.h +66 -3
  181. data/ext/ruby2d/sound.c +16 -2
  182. data/lib/ruby2d/canvas.rb +315 -0
  183. data/lib/ruby2d/circle.rb +30 -15
  184. data/lib/ruby2d/cli/build.rb +5 -3
  185. data/lib/ruby2d/cli/enable_console.rb +3 -1
  186. data/lib/ruby2d/color.rb +133 -77
  187. data/lib/ruby2d/core.rb +32 -0
  188. data/lib/ruby2d/dsl.rb +38 -32
  189. data/lib/ruby2d/exceptions.rb +2 -1
  190. data/lib/ruby2d/font.rb +97 -62
  191. data/lib/ruby2d/image.rb +48 -27
  192. data/lib/ruby2d/line.rb +84 -45
  193. data/lib/ruby2d/music.rb +33 -23
  194. data/lib/ruby2d/pixel.rb +10 -9
  195. data/lib/ruby2d/pixmap.rb +39 -0
  196. data/lib/ruby2d/pixmap_atlas.rb +56 -0
  197. data/lib/ruby2d/quad.rb +98 -49
  198. data/lib/ruby2d/rectangle.rb +35 -36
  199. data/lib/ruby2d/renderable.rb +7 -6
  200. data/lib/ruby2d/sound.rb +23 -17
  201. data/lib/ruby2d/sprite.rb +181 -140
  202. data/lib/ruby2d/square.rb +21 -20
  203. data/lib/ruby2d/text.rb +47 -19
  204. data/lib/ruby2d/texture.rb +13 -3
  205. data/lib/ruby2d/tileset.rb +97 -44
  206. data/lib/ruby2d/triangle.rb +91 -42
  207. data/lib/ruby2d/version.rb +3 -1
  208. data/lib/ruby2d/vertices.rb +81 -45
  209. data/lib/ruby2d/window.rb +508 -371
  210. data/lib/ruby2d.rb +11 -29
  211. metadata +51 -16
  212. data/assets/include/SDL2/SDL_config_psp.h +0 -165
  213. data/assets/include/SDL2/SDL_config_wiz.h +0 -154
  214. data/assets/include/glew.h +0 -23686
  215. data/assets/macos/universal/lib/libpng16.a +0 -0
  216. data/assets/windows/glew/README.md +0 -10
  217. data/assets/windows/glew/glew.h +0 -23686
  218. data/assets/windows/glew/libglew32.a +0 -0
  219. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng16.a +0 -0
  220. data/assets/windows/mingw-w64-x86_64/lib/libpng16.a +0 -0
  221. data/lib/ruby2d/entity.rb +0 -17
data/lib/ruby2d/text.rb CHANGED
@@ -1,27 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Text
2
4
 
3
5
  module Ruby2D
6
+ # Text string drawn using the specified font and size
4
7
  class Text
5
8
  include Renderable
6
9
 
7
10
  attr_reader :text, :size
8
11
  attr_accessor :x, :y, :rotate, :data
9
12
 
10
- def initialize(text, opts = {})
11
- @x = opts[:x] || 0
12
- @y = opts[:y] || 0
13
- @z = opts[:z] || 0
13
+ # Create a text string
14
+ # @param text The text to show
15
+ # @param [Numeric] size The font +size+
16
+ # @param [String] font Path to font file to use to draw the text
17
+ # @param [String] style Font style
18
+ # @param [Numeric] x
19
+ # @param [Numeric] y
20
+ # @param [Numeric] z
21
+ # @param [Numeric] rotate Angle, default is 0
22
+ # @param [Numeric] color or +colour+ Colour the text when rendering
23
+ # @param [Numeric] opacity Opacity of the image when rendering
24
+ # @param [true, false] show If +true+ the Text is added to +Window+ automatically.
25
+ def initialize(text, size: 20, style: nil, font: Font.default,
26
+ x: 0, y: 0, z: 0,
27
+ rotate: 0, color: nil, colour: nil,
28
+ opacity: nil, show: true)
29
+ @x = x
30
+ @y = y
31
+ @z = z
14
32
  @text = text.to_s
15
- @size = opts[:size] || 20
16
- @rotate = opts[:rotate] || 0
17
- @style = opts[:style]
18
- self.color = opts[:color] || 'white'
19
- self.color.opacity = opts[:opacity] if opts[:opacity]
20
- @font_path = opts[:font] || Font.default
33
+ @size = size
34
+ @rotate = rotate
35
+ @style = style
36
+ self.color = color || colour || 'white'
37
+ self.color.opacity = opacity unless opacity.nil?
38
+ @font_path = font
39
+ @texture = nil
21
40
  create_font
22
41
  create_texture
23
42
 
24
- unless opts[:show] == false then add end
43
+ add if show
25
44
  end
26
45
 
27
46
  # Returns the path of the font as a string
@@ -40,15 +59,25 @@ module Ruby2D
40
59
  create_texture
41
60
  end
42
61
 
43
- def draw(opts = {})
62
+ def draw(x:, y:, color:, rotate:)
44
63
  Window.render_ready_check
45
64
 
46
- opts[:rotate] = opts[:rotate] || @rotate
47
- unless opts[:color]
48
- opts[:color] = [1.0, 1.0, 1.0, 1.0]
49
- end
65
+ x ||= @rotate
66
+ color ||= [1.0, 1.0, 1.0, 1.0]
50
67
 
51
- render(x: opts[:x], y: opts[:y], color: Color.new(opts[:color]), rotate: opts[:rotate])
68
+ render(x: x, y: y, color: Color.new(color), rotate: rotate)
69
+ end
70
+
71
+ class << self
72
+ # Create a texture for the specified text
73
+ # @param text The text to show
74
+ # @param [Numeric] size The font +size+
75
+ # @param [String] font Path to font file to use to draw the text
76
+ # @param [String] style Font style
77
+ def create_texture(text, size: 20, style: nil, font: Font.default)
78
+ font = Font.load(font, size, style)
79
+ Texture.new(*Text.ext_load_text(font.ttf_font, text))
80
+ end
52
81
  end
53
82
 
54
83
  private
@@ -66,8 +95,7 @@ module Ruby2D
66
95
  end
67
96
 
68
97
  def create_texture
69
- if @texture then @texture.delete end
70
-
98
+ @texture&.delete
71
99
  @texture = Texture.new(*Text.ext_load_text(@font.ttf_font, @text))
72
100
  @width = @texture.width
73
101
  @height = @texture.height
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Texture
2
4
 
3
5
  module Ruby2D
6
+ # This internal class is used to hold raw pixel data which in turn is used to
7
+ # render textures via openGL rendering code.
4
8
  class Texture
5
9
  attr_reader :width, :height, :texture_id
6
10
 
11
+ WHITE_OPAQUE_AR = [1.0, 1.0, 1.0, 1.0].freeze
12
+
7
13
  def initialize(pixel_data, width, height)
8
14
  @pixel_data = pixel_data
9
15
  @width = width
@@ -11,13 +17,17 @@ module Ruby2D
11
17
  @texture_id = 0
12
18
  end
13
19
 
14
- def draw(coordinates, texture_coordinates, color)
15
- if @texture_id == 0
20
+ # Draw the texture
21
+ # @param coordinates [Array(x1, y1, x2, y2, x3, y3, x4, y4)] Destination coordinates
22
+ # @param texture_coordinates [Array(tx1, ty1, tx2, ty2, tx3, ty3, tx1, ty3)] Source (texture) coordinates
23
+ # @param color [Ruby2D::Color] Tint/blend the texture when it's drawn
24
+ def draw(coordinates, texture_coordinates, color = nil)
25
+ if @texture_id.zero?
16
26
  @texture_id = ext_create(@pixel_data, @width, @height)
17
27
  @pixel_data = nil
18
28
  end
19
29
 
20
- color = [color.r, color.g, color.b, color.a]
30
+ color = color.nil? ? WHITE_OPAQUE_AR : [color.r, color.g, color.b, color.a]
21
31
  ext_draw(coordinates, texture_coordinates, color, @texture_id)
22
32
  end
23
33
 
@@ -1,50 +1,95 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Tileset
2
4
 
3
5
  module Ruby2D
6
+ # Tilesets are images containing multiple unique tiles. These tiles can be drawn to the
7
+ # screen multiple times in interesting combinations to produce things like backgrounds
8
+ # or draw larger objects.
4
9
  class Tileset
5
10
  DEFAULT_COLOR = Color.new([1.0, 1.0, 1.0, 1.0])
6
11
 
7
12
  include Renderable
8
13
 
9
- def initialize(path, opts = {})
10
- @path = path
14
+ # Setup a Tileset with an image.
15
+ # @param path [#to_s] The location of the file to load as an image.
16
+ # @param width [Numeric] The +width+ of image, or default is width from image file
17
+ # @param height [Numeric] The +height+ of image, or default is height from image file
18
+ # @param z [Numeric]
19
+ # @param padding [Numeric]
20
+ # @param spacing [Numeric]
21
+ # @param tile_width [Numeric] Width of each tile in pixels
22
+ # @param tile_height [Numeric] Height of each tile in pixels
23
+ # @param scale [Numeric] Default is 1
24
+ # @param show [Boolean] If +true+ the image is added to +Window+ automatically.
25
+ def initialize(path, tile_width: 32, tile_height: 32, atlas: nil,
26
+ width: nil, height: nil, z: 0,
27
+ padding: 0, spacing: 0,
28
+ scale: 1, show: true)
29
+ @path = path.to_s
11
30
 
12
31
  # Initialize the tileset texture
13
- @texture = Texture.new(*Image.load_image(@path))
14
- @width = opts[:width] || @texture.width
15
- @height = opts[:height] || @texture.height
16
- @z = opts[:z] || 0
32
+ # Consider input pixmap atlas if supplied to load image file
33
+ @texture = Image.load_image_as_texture @path, atlas: atlas
34
+ @width = width || @texture.width
35
+ @height = height || @texture.height
36
+ @z = z
17
37
 
18
38
  @tiles = []
19
- @defined_tiles = {}
20
- @padding = opts[:padding] || 0
21
- @spacing = opts[:spacing] || 0
22
- @tile_width = opts[:tile_width]
23
- @tile_height = opts[:tile_height]
24
- @scale = opts[:scale] || 1
25
-
26
- unless opts[:show] == false then add end
39
+ @tile_definitions = {}
40
+ @padding = padding
41
+ @spacing = spacing
42
+ @tile_width = tile_width
43
+ @tile_height = tile_height
44
+ @scale = scale
45
+
46
+ _calculate_scaled_sizes
47
+
48
+ add if show
27
49
  end
28
50
 
51
+ # Define and name a tile in the tileset image by its position. The actual tiles
52
+ # to be drawn are declared using {#set_tile}
53
+ #
54
+ # @param name [String] A unique name for the tile in the tileset
55
+ # @param x [Numeric] Column position of the tile
56
+ # @param y [Numeric] Row position of the tile
57
+ # @param rotate [Numeric] Angle of the title when drawn, default is 0
58
+ # @param flip [nil, :vertical, :horizontal, :both] Direction to flip the tile if desired
29
59
  def define_tile(name, x, y, rotate: 0, flip: nil)
30
- @defined_tiles[name] = { x: x, y: y , rotate: rotate, flip: flip }
60
+ @tile_definitions[name] = { x: x, y: y, rotate: rotate, flip: flip }
31
61
  end
32
62
 
63
+ # Select and "stamp" or set/place a tile to be drawn
64
+ # @param name [String] The name of the tile defined using +#define_tile+
65
+ # @param coordinates [Array<{"x", "y" => Numeric}>] one or more +{x:, y:}+ coordinates to draw the tile
33
66
  def set_tile(name, coordinates)
34
- tile = @defined_tiles.fetch(name)
67
+ tile_def = @tile_definitions.fetch(name)
68
+ crop = _calculate_tile_crop(tile_def)
35
69
 
36
70
  coordinates.each do |coordinate|
71
+ # Use Vertices object for tile placement so we can use them
72
+ # directly when drawing the textures instead of making them for
73
+ # every tile placement for each draw, and re-use the crop from
74
+ # the tile definition
75
+ vertices = Vertices.new(
76
+ coordinate.fetch(:x), coordinate.fetch(:y),
77
+ @scaled_tile_width, @scaled_tile_height,
78
+ tile_def.fetch(:rotate),
79
+ crop: crop,
80
+ flip: tile_def.fetch(:flip)
81
+ )
82
+ # Remember the referenced tile for if we ever want to recalculate
83
+ # them all due to change to scale etc (currently n/a since
84
+ # scale is immutable)
37
85
  @tiles.push({
38
- tile_x: tile.fetch(:x),
39
- tile_y: tile.fetch(:y),
40
- tile_rotate: tile.fetch(:rotate),
41
- tile_flip: tile.fetch(:flip),
42
- x: coordinate.fetch(:x),
43
- y: coordinate.fetch(:y)
44
- })
86
+ tile_def: tile_def,
87
+ vertices: vertices
88
+ })
45
89
  end
46
90
  end
47
91
 
92
+ # Removes all stamped tiles so nothing is drawn.
48
93
  def clear_tiles
49
94
  @tiles = []
50
95
  end
@@ -57,28 +102,36 @@ module Ruby2D
57
102
 
58
103
  private
59
104
 
60
- def render
61
- scaled_padding = @padding * @scale
62
- scaled_spacing = @spacing * @scale
63
- scaled_tile_width = @tile_width * @scale
64
- scaled_tile_height = @tile_height * @scale
65
- scaled_width = @width * @scale
66
- scaled_height = @height * @scale
67
-
68
- @tiles.each do |tile|
69
- crop = {
70
- x: scaled_padding + (tile.fetch(:tile_x) * (scaled_spacing + scaled_tile_width)),
71
- y: scaled_padding + (tile.fetch(:tile_y) * (scaled_spacing + scaled_tile_height)),
72
- width: scaled_tile_width,
73
- height: scaled_tile_height,
74
- image_width: scaled_width,
75
- image_height: scaled_height,
76
- }
77
-
78
- color = defined?(@color) ? @color : DEFAULT_COLOR
79
-
80
- vertices = Vertices.new(tile.fetch(:x), tile.fetch(:y), scaled_tile_width, scaled_tile_height, tile.fetch(:tile_rotate), crop: crop, flip: tile.fetch(:tile_flip))
105
+ def _calculate_tile_crop(tile_def)
106
+ # Re-use if crop has already been calculated
107
+ return tile_def.fetch(:scaled_crop) if tile_def.key?(:scaled_crop)
108
+
109
+ # Calculate the crop for each tile definition the first time a tile
110
+ # is placed/set, so that we can later re-use when placing tiles,
111
+ # avoiding creating the crop object for every placement.
112
+ tile_def[:scaled_crop] = {
113
+ x: @scaled_padding + (tile_def.fetch(:x) * (@scaled_spacing + @scaled_tile_width)),
114
+ y: @scaled_padding + (tile_def.fetch(:y) * (@scaled_spacing + @scaled_tile_height)),
115
+ width: @scaled_tile_width,
116
+ height: @scaled_tile_height,
117
+ image_width: @scaled_width,
118
+ image_height: @scaled_height
119
+ }.freeze
120
+ end
121
+
122
+ def _calculate_scaled_sizes
123
+ @scaled_padding = @padding * @scale
124
+ @scaled_spacing = @spacing * @scale
125
+ @scaled_tile_width = @tile_width * @scale
126
+ @scaled_tile_height = @tile_height * @scale
127
+ @scaled_width = @width * @scale
128
+ @scaled_height = @height * @scale
129
+ end
81
130
 
131
+ def render
132
+ color = defined?(@color) ? @color : DEFAULT_COLOR
133
+ @tiles.each do |placement|
134
+ vertices = placement.fetch(:vertices)
82
135
  @texture.draw(
83
136
  vertices.coordinates, vertices.texture_coordinates, color
84
137
  )
@@ -1,29 +1,57 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::Triangle
2
4
 
3
5
  module Ruby2D
6
+ # A triangle
4
7
  class Triangle
5
8
  include Renderable
6
9
 
7
- attr_accessor :x1, :y1, :c1,
8
- :x2, :y2, :c2,
9
- :x3, :y3, :c3
10
-
11
- def initialize(opts= {})
12
- @x1 = opts[:x1] || 50
13
- @y1 = opts[:y1] || 0
14
- @x2 = opts[:x2] || 100
15
- @y2 = opts[:y2] || 100
16
- @x3 = opts[:x3] || 0
17
- @y3 = opts[:y3] || 100
18
- @z = opts[:z] || 0
19
- self.color = opts[:color] || 'white'
20
- self.color.opacity = opts[:opacity] if opts[:opacity]
10
+ attr_accessor :x1, :y1,
11
+ :x2, :y2,
12
+ :x3, :y3
13
+ attr_reader :color
14
+
15
+ # Create a triangle
16
+ # @param x1 [Numeric]
17
+ # @param y1 [Numeric]
18
+ # @param x2 [Numeric]
19
+ # @param y2 [Numeric]
20
+ # @param x3 [Numeric]
21
+ # @param y3 [Numeric]
22
+ # @param z [Numeric]
23
+ # @param color [String, Array] A single colour or an array of exactly 3 colours
24
+ # @param opacity [Numeric] Opacity of the image when rendering
25
+ # @raise [ArgumentError] if an array of colours does not have 3 entries
26
+ def initialize(x1: 50, y1: 0, x2: 100, y2: 100, x3: 0, y3: 100,
27
+ z: 0, color: 'white', colour: nil, opacity: nil)
28
+ @x1 = x1
29
+ @y1 = y1
30
+ @x2 = x2
31
+ @y2 = y2
32
+ @x3 = x3
33
+ @y3 = y3
34
+ @z = z
35
+ self.color = color || colour
36
+ self.color.opacity = opacity if opacity
21
37
  add
22
38
  end
23
39
 
24
- def color=(c)
25
- @color = Color.set(c)
26
- update_color(@color)
40
+ # Change the colour of the line
41
+ # @param [String, Array] color A single colour or an array of exactly 3 colours
42
+ # @raise [ArgumentError] if an array of colours does not have 3 entries
43
+ def color=(color)
44
+ # convert to Color or Color::Set
45
+ color = Color.set(color)
46
+
47
+ # require 3 colours if multiple colours provided
48
+ if color.is_a?(Color::Set) && color.length != 3
49
+ raise ArgumentError,
50
+ "`#{self.class}` requires 3 colors, one for each vertex. #{color.length} were given."
51
+ end
52
+
53
+ @color = color # converted above
54
+ invalidate_color_components
27
55
  end
28
56
 
29
57
  # A point is inside a triangle if the area of 3 triangles, constructed from
@@ -38,45 +66,66 @@ module Ruby2D
38
66
  questioned_area <= self_area
39
67
  end
40
68
 
41
- def self.draw(opts = {})
69
+ # Draw a triangle
70
+ # @param x1 [Numeric]
71
+ # @param y1 [Numeric]
72
+ # @param x2 [Numeric]
73
+ # @param y2 [Numeric]
74
+ # @param x3 [Numeric]
75
+ # @param y3 [Numeric]
76
+ # @param z [Numeric]
77
+ # @param color [Array<Array<float,float,float,float>>] An array of 3 arrays of colour components
78
+ # (e.g. [[1.0, 0, 0, 1.0], ...])
79
+ def self.draw(x1:, y1:, x2:, y2:, x3:, y3:, color:)
42
80
  Window.render_ready_check
43
-
44
81
  ext_draw([
45
- opts[:x1], opts[:y1], opts[:color][0][0], opts[:color][0][1], opts[:color][0][2], opts[:color][0][3],
46
- opts[:x2], opts[:y2], opts[:color][1][0], opts[:color][1][1], opts[:color][1][2], opts[:color][1][3],
47
- opts[:x3], opts[:y3], opts[:color][2][0], opts[:color][2][1], opts[:color][2][2], opts[:color][2][3]
48
- ])
82
+ x1, y1, *color[0], # splat the colour components
83
+ x2, y2, *color[1],
84
+ x3, y3, *color[2]
85
+ ])
49
86
  end
50
87
 
51
88
  private
52
89
 
53
90
  def render
91
+ color_comp_arrays = color_components
54
92
  self.class.ext_draw([
55
- @x1, @y1, @c1.r, @c1.g, @c1.b, @c1.a,
56
- @x2, @y2, @c2.r, @c2.g, @c2.b, @c2.a,
57
- @x3, @y3, @c3.r, @c3.g, @c3.b, @c3.a
58
- ])
93
+ @x1, @y1, *color_comp_arrays[0], # splat the colour components
94
+ @x2, @y2, *color_comp_arrays[1],
95
+ @x3, @y3, *color_comp_arrays[2]
96
+ ])
59
97
  end
60
98
 
61
99
  def triangle_area(x1, y1, x2, y2, x3, y3)
62
- (x1*y2 + x2*y3 + x3*y1 - x3*y2 - x1*y3 - x2*y1).abs / 2
100
+ (x1 * y2 + x2 * y3 + x3 * y1 - x3 * y2 - x1 * y3 - x2 * y1).abs / 2
63
101
  end
64
102
 
65
- def update_color(c)
66
- if c.is_a? Color::Set
67
- if c.length == 3
68
- @c1 = c[0]
69
- @c2 = c[1]
70
- @c3 = c[2]
71
- else
72
- raise ArgumentError, "`#{self.class}` requires 3 colors, one for each vertex. #{c.length} were given."
73
- end
74
- else
75
- @c1 = c
76
- @c2 = c
77
- @c3 = c
78
- end
103
+ # Return colours as a memoized array of 3 x colour component arrays
104
+ def color_components
105
+ check_if_opacity_changed
106
+ @color_components ||= if @color.is_a? Color::Set
107
+ # Extract colour component arrays; see +def color=+ where colour set
108
+ # size is enforced
109
+ [
110
+ @color[0].to_a, @color[1].to_a, @color[2].to_a
111
+ ]
112
+ else
113
+ # All vertex colours are the same
114
+ c_a = @color.to_a
115
+ [
116
+ c_a, c_a, c_a
117
+ ]
118
+ end
79
119
  end
80
120
 
121
+ # Invalidate memoized colour components if opacity has been changed via +color=+
122
+ def check_if_opacity_changed
123
+ @color_components = nil if @color_components && @color_components.first[3] != @color.opacity
124
+ end
125
+
126
+ # Invalidate the memoized colour components. Called when Line's colour is changed
127
+ def invalidate_color_components
128
+ @color_components = nil
129
+ end
81
130
  end
82
131
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Ruby2D::VERSION
2
4
 
3
5
  module Ruby2D
4
- VERSION = '0.11.3'
6
+ VERSION = '0.12.0'
5
7
  end
@@ -1,10 +1,11 @@
1
- # Ruby2D::Vertices
1
+ # frozen_string_literal: true
2
2
 
3
- # This class generates a vertices array which are passed to the openGL rendering code.
4
- # The vertices array is split up into 4 groups (1 - top left, 2 - top right, 3 - bottom right, 4 - bottom left)
5
- # This class is responsible for transforming textures, it can scale / crop / rotate and flip textures
3
+ # Ruby2D::Vertices
6
4
 
7
5
  module Ruby2D
6
+ # This internal class generates a vertices array which are passed to the openGL rendering code.
7
+ # The vertices array is split up into 4 groups (1 - top left, 2 - top right, 3 - bottom right, 4 - bottom left)
8
+ # This class is responsible for transforming textures, it can scale / crop / rotate and flip textures
8
9
  class Vertices
9
10
  def initialize(x, y, width, height, rotate, crop: nil, flip: nil)
10
11
  @flip = flip
@@ -12,53 +13,36 @@ module Ruby2D
12
13
  @y = y
13
14
  @width = width.to_f
14
15
  @height = height.to_f
15
-
16
- if @flip == :horizontal || @flip == :both
17
- @x = @x + @width
18
- @width = -@width
19
- end
20
-
21
- if @flip == :vertical || @flip == :both
22
- @y = y + @height
23
- @height = -@height
24
- end
25
-
26
16
  @rotate = rotate
27
17
  @rx = @x + (@width / 2.0)
28
18
  @ry = @y + (@height / 2.0)
29
19
  @crop = crop
20
+ @coordinates = nil
21
+ @texture_coordinates = nil
22
+ _apply_flip unless @flip.nil?
30
23
  end
31
24
 
32
25
  def coordinates
33
- if @rotate == 0
34
- x1, y1 = @x, @y; # Top left
35
- x2, y2 = @x + @width, @y; # Top right
36
- x3, y3 = @x + @width, @y + @height; # Bottom right
37
- x4, y4 = @x, @y + @height; # Bottom left
38
- else
39
- x1, y1 = rotate(@x, @y); # Top left
40
- x2, y2 = rotate(@x + @width, @y); # Top right
41
- x3, y3 = rotate(@x + @width, @y + @height); # Bottom right
42
- x4, y4 = rotate(@x, @y + @height); # Bottom left
43
- end
44
-
45
- [ x1, y1, x2, y2, x3, y3, x4, y4 ]
26
+ @coordinates ||= if @rotate.zero?
27
+ _unrotated_coordinates
28
+ else
29
+ _calculate_coordinates
30
+ end
46
31
  end
47
32
 
48
- def texture_coordinates
49
- if @crop.nil?
50
- tx1 = 0.0; ty1 = 0.0 # Top left
51
- tx2 = 1.0; ty2 = 0.0 # Top right
52
- tx3 = 1.0; ty3 = 1.0 # Bottom right
53
- tx4 = 0.0; ty4 = 1.0 # Bottom left
54
- else
55
- tx1 = @crop[:x] / @crop[:image_width].to_f; ty1 = @crop[:y] / @crop[:image_height].to_f # Top left
56
- tx2 = tx1 + (@crop[:width] / @crop[:image_width].to_f); ty2 = ty1 # Top right
57
- tx3 = tx2; ty3 = ty1 + (@crop[:height] / @crop[:image_height].to_f) # Botttom right
58
- tx4 = tx1; ty4 = ty3 # Bottom left
59
- end
33
+ TEX_UNCROPPED_COORDS = [
34
+ 0.0, 0.0, # top left
35
+ 1.0, 0.0, # top right
36
+ 1.0, 1.0, # bottom right
37
+ 0.0, 1.0 # bottom left
38
+ ].freeze
60
39
 
61
- [ tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4 ]
40
+ def texture_coordinates
41
+ @texture_coordinates ||= if @crop.nil?
42
+ TEX_UNCROPPED_COORDS
43
+ else
44
+ _calculate_texture_coordinates
45
+ end
62
46
  end
63
47
 
64
48
  private
@@ -76,14 +60,66 @@ module Ruby2D
76
60
  y -= @ry
77
61
 
78
62
  # Rotate point
79
- xnew = x * ca - y * sa;
80
- ynew = x * sa + y * ca;
63
+ xnew = x * ca - y * sa
64
+ ynew = x * sa + y * ca
81
65
 
82
66
  # Translate point back
83
- x = xnew + @rx;
84
- y = ynew + @ry;
67
+ x = xnew + @rx
68
+ y = ynew + @ry
85
69
 
86
70
  [x, y]
87
71
  end
72
+
73
+ def _unrotated_coordinates
74
+ x1 = @x
75
+ y1 = @y; # Top left
76
+ x2 = @x + @width
77
+ y2 = @y; # Top right
78
+ x3 = @x + @width
79
+ y3 = @y + @height; # Bottom right
80
+ x4 = @x
81
+ y4 = @y + @height; # Bottom left
82
+ [x1, y1, x2, y2, x3, y3, x4, y4]
83
+ end
84
+
85
+ def _calculate_coordinates
86
+ x1, y1 = rotate(@x, @y); # Top left
87
+ x2, y2 = rotate(@x + @width, @y); # Top right
88
+ x3, y3 = rotate(@x + @width, @y + @height); # Bottom right
89
+ x4, y4 = rotate(@x, @y + @height); # Bottom left
90
+ [x1, y1, x2, y2, x3, y3, x4, y4]
91
+ end
92
+
93
+ def _calculate_texture_coordinates
94
+ img_width = @crop[:image_width].to_f
95
+ img_height = @crop[:image_height].to_f
96
+
97
+ # Top left
98
+ tx1 = @crop[:x] / img_width
99
+ ty1 = @crop[:y] / img_height
100
+ # Top right
101
+ tx2 = tx1 + (@crop[:width] / img_width)
102
+ ty2 = ty1
103
+ # Botttom right
104
+ tx3 = tx2
105
+ ty3 = ty1 + (@crop[:height] / img_height)
106
+ # Bottom left
107
+ # tx4 = tx1
108
+ # ty4 = ty3
109
+
110
+ [tx1, ty1, tx2, ty2, tx3, ty3, tx1, ty3]
111
+ end
112
+
113
+ def _apply_flip
114
+ if @flip == :horizontal || @flip == :both
115
+ @x += @width
116
+ @width = -@width
117
+ end
118
+
119
+ return unless @flip == :vertical || @flip == :both
120
+
121
+ @y += @height
122
+ @height = -@height
123
+ end
88
124
  end
89
125
  end