ruby2d 0.10.0 → 0.11.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.
@@ -0,0 +1,28 @@
1
+ # Ruby2D::Text
2
+
3
+ module Ruby2D
4
+ class Texture
5
+ attr_reader :width, :height, :texture_id
6
+
7
+ def initialize(pixel_data, width, height)
8
+ @pixel_data = pixel_data
9
+ @width = width
10
+ @height = height
11
+ @texture_id = 0
12
+ end
13
+
14
+ def draw(coordinates, texture_coordinates, color)
15
+ if @texture_id == 0
16
+ @texture_id = ext_create(@pixel_data, @width, @height)
17
+ @pixel_data = nil
18
+ end
19
+
20
+ color = [color.r, color.g, color.b, color.a]
21
+ ext_draw(coordinates, texture_coordinates, color, @texture_id)
22
+ end
23
+
24
+ def delete
25
+ ext_delete(@texture_id)
26
+ end
27
+ end
28
+ end
@@ -5,26 +5,27 @@ module Ruby2D
5
5
  include Renderable
6
6
 
7
7
  def initialize(path, opts = {})
8
- unless File.exist? path
9
- raise Error, "Cannot find tileset image file `#{path}`"
10
- end
11
8
  @path = path
9
+
10
+ # Initialize the tileset texture
11
+ @texture = Texture.new(*Image.load_image(@path))
12
+ @width = opts[:width] || @texture.width
13
+ @height = opts[:height] || @texture.height
14
+ @z = opts[:z] || 0
15
+
12
16
  @tiles = []
13
17
  @defined_tiles = {}
14
18
  @padding = opts[:padding] || 0
15
19
  @spacing = opts[:spacing] || 0
16
20
  @tile_width = opts[:tile_width]
17
21
  @tile_height = opts[:tile_height]
18
-
19
- unless ext_init(@path)
20
- raise Error, "Tileset `#{@path}` cannot be created"
21
- end
22
+ @scale = opts[:scale] || 1
22
23
 
23
24
  unless opts[:show] == false then add end
24
25
  end
25
26
 
26
- def define_tile(name, x, y)
27
- @defined_tiles[name] = { x: x, y: y }
27
+ def define_tile(name, x, y, rotate: 0, flip: nil)
28
+ @defined_tiles[name] = { x: x, y: y , rotate: rotate, flip: flip }
28
29
  end
29
30
 
30
31
  def set_tile(name, coordinates)
@@ -34,6 +35,8 @@ module Ruby2D
34
35
  @tiles.push({
35
36
  tile_x: tile.fetch(:x),
36
37
  tile_y: tile.fetch(:y),
38
+ tile_rotate: tile.fetch(:rotate),
39
+ tile_flip: tile.fetch(:flip),
37
40
  x: coordinate.fetch(:x),
38
41
  y: coordinate.fetch(:y)
39
42
  })
@@ -45,25 +48,40 @@ module Ruby2D
45
48
  end
46
49
  end
47
50
 
48
- def draw(opts = {})
49
- render(opts)
51
+ def draw
52
+ Window.render_ready_check
53
+
54
+ render
50
55
  end
51
56
 
52
57
  private
53
58
 
54
- def render(opts = {})
55
- opts[:tile_width] = opts[:tile_width] || @tile_width
56
- opts[:tile_height] = opts[:tile_height] || @tile_height
57
- opts[:padding] = opts[:padding] || @padding
58
- opts[:spacing] = opts[:spacing] || @spacing
59
+
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
59
67
 
60
68
  @tiles.each do |tile|
61
- self.class.ext_draw(
62
- [
63
- self, opts[:tile_width], opts[:tile_height], opts[:padding], opts[:spacing],
64
- tile.fetch(:tile_x), tile.fetch(:tile_y), tile.fetch(:x),
65
- tile.fetch(:y)
66
- ])
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 : Color.new([1.0, 1.0, 1.0, 1.0])
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))
81
+
82
+ @texture.draw(
83
+ vertices.coordinates, vertices.texture_coordinates, color
84
+ )
67
85
  end
68
86
  end
69
87
  end
@@ -17,7 +17,7 @@ module Ruby2D
17
17
  @y3 = opts[:y3] || 100
18
18
  @z = opts[:z] || 0
19
19
  self.color = opts[:color] || 'white'
20
- self.opacity = opts[:opacity] if opts[:opacity]
20
+ self.color.opacity = opts[:opacity] if opts[:opacity]
21
21
  add
22
22
  end
23
23
 
@@ -39,6 +39,8 @@ module Ruby2D
39
39
  end
40
40
 
41
41
  def self.draw(opts = {})
42
+ Window.render_ready_check
43
+
42
44
  ext_draw([
43
45
  opts[:x1], opts[:y1], opts[:color][0][0], opts[:color][0][1], opts[:color][0][2], opts[:color][0][3],
44
46
  opts[:x2], opts[:y2], opts[:color][1][0], opts[:color][1][1], opts[:color][1][2], opts[:color][1][3],
@@ -1,5 +1,5 @@
1
1
  # Ruby2D::VERSION
2
2
 
3
3
  module Ruby2D
4
- VERSION = '0.10.0'
4
+ VERSION = '0.11.0'
5
5
  end
@@ -0,0 +1,84 @@
1
+ # Ruby2D::Vertices
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
6
+
7
+ module Ruby2D
8
+ class Vertices
9
+ def initialize(x, y, width, height, rotate, crop: nil, flip: nil)
10
+ @flip = flip
11
+ @x = x
12
+ @y = y
13
+ @width = width.to_f
14
+ @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
+ @rotate = rotate
27
+ @rx = @x + (@width / 2.0)
28
+ @ry = @y + (@height / 2.0)
29
+ @crop = crop
30
+ end
31
+
32
+ def coordinates
33
+ x1, y1 = rotate(@x, @y); # Top left
34
+ x2, y2 = rotate(@x + @width, @y); # Top right
35
+ x3, y3 = rotate(@x + @width, @y + @height); # Bottom right
36
+ x4, y4 = rotate(@x, @y + @height); # Bottom left
37
+
38
+ [ x1, y1, x2, y2, x3, y3, x4, y4 ]
39
+ end
40
+
41
+ def texture_coordinates
42
+ if @crop.nil?
43
+ tx1 = 0.0; ty1 = 0.0 # Top left
44
+ tx2 = 1.0; ty2 = 0.0 # Top right
45
+ tx3 = 1.0; ty3 = 1.0 # Bottom right
46
+ tx4 = 0.0; ty4 = 1.0 # Bottom left
47
+ else
48
+ tx1 = @crop[:x] / @crop[:image_width].to_f; ty1 = @crop[:y] / @crop[:image_height].to_f # Top left
49
+ tx2 = tx1 + (@crop[:width] / @crop[:image_width].to_f); ty2 = ty1 # Top right
50
+ tx3 = tx2; ty3 = ty1 + (@crop[:height] / @crop[:image_height].to_f) # Botttom right
51
+ tx4 = tx1; ty4 = ty3 # Bottom left
52
+ end
53
+
54
+ [ tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4 ]
55
+ end
56
+
57
+ private
58
+
59
+ def rotate(x, y)
60
+ return [x, y] if @rotate == 0
61
+
62
+ # Convert from degrees to radians
63
+ angle = @rotate * Math::PI / 180.0
64
+
65
+ # Get the sine and cosine of the angle
66
+ sa = Math.sin(angle)
67
+ ca = Math.cos(angle)
68
+
69
+ # Translate point to origin
70
+ x -= @rx
71
+ y -= @ry
72
+
73
+ # Rotate point
74
+ xnew = x * ca - y * sa;
75
+ ynew = x * sa + y * ca;
76
+
77
+ # Translate point back
78
+ x = xnew + @rx;
79
+ y = ynew + @ry;
80
+
81
+ [x, y]
82
+ end
83
+ end
84
+ end
data/lib/ruby2d/window.rb CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  module Ruby2D
6
6
  class Window
7
+ @@open_window = false
7
8
 
8
9
  # Event structures
9
10
  EventDescriptor = Struct.new(:type, :id)
@@ -109,9 +110,7 @@ module Ruby2D
109
110
  @render_proc = Proc.new {}
110
111
 
111
112
  # Detect if window is being used through the DSL or as a class instance
112
- unless method(:update).parameters.empty? || method(:render).parameters.empty?
113
- @using_dsl = true
114
- end
113
+ @using_dsl = !(method(:update).parameters.empty? || method(:render).parameters.empty?)
115
114
 
116
115
  # Whether diagnostic messages should be printed
117
116
  @diagnostics = false
@@ -190,6 +189,12 @@ module Ruby2D
190
189
  def close
191
190
  DSL.window.close
192
191
  end
192
+
193
+ def render_ready_check
194
+ unless @@open_window
195
+ raise Error, "Attempting to draw before the window is ready. Please put calls to draw() inside of a render block."
196
+ end
197
+ end
193
198
  end
194
199
 
195
200
  # Public instance methods
@@ -616,6 +621,11 @@ module Ruby2D
616
621
 
617
622
  # Show the window
618
623
  def show
624
+ if @@open_window
625
+ raise Error, "Window#show called multiple times, Ruby2D only supports a single open window"
626
+ end
627
+
628
+ @@open_window = true
619
629
  ext_show
620
630
  end
621
631
 
data/lib/ruby2d.rb CHANGED
@@ -22,6 +22,8 @@ unless RUBY_ENGINE == 'mruby'
22
22
  require 'ruby2d/text'
23
23
  require 'ruby2d/sound'
24
24
  require 'ruby2d/music'
25
+ require 'ruby2d/texture'
26
+ require 'ruby2d/vertices'
25
27
 
26
28
  if defined?(RubyInstaller)
27
29
  s2d_dll_path = Gem::Specification.find_by_name('ruby2d').gem_dir + '/assets/mingw/bin'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Black
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-27 00:00:00.000000000 Z
11
+ date: 2021-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -274,6 +274,7 @@ files:
274
274
  - ext/ruby2d/common.c
275
275
  - ext/ruby2d/controllers.c
276
276
  - ext/ruby2d/extconf.rb
277
+ - ext/ruby2d/font.c
277
278
  - ext/ruby2d/gl.c
278
279
  - ext/ruby2d/gl2.c
279
280
  - ext/ruby2d/gl3.c
@@ -285,9 +286,7 @@ files:
285
286
  - ext/ruby2d/ruby2d.h
286
287
  - ext/ruby2d/shapes.c
287
288
  - ext/ruby2d/sound.c
288
- - ext/ruby2d/sprite.c
289
289
  - ext/ruby2d/text.c
290
- - ext/ruby2d/tileset.c
291
290
  - ext/ruby2d/window.c
292
291
  - lib/ruby2d.rb
293
292
  - lib/ruby2d/circle.rb
@@ -312,9 +311,11 @@ files:
312
311
  - lib/ruby2d/sprite.rb
313
312
  - lib/ruby2d/square.rb
314
313
  - lib/ruby2d/text.rb
314
+ - lib/ruby2d/texture.rb
315
315
  - lib/ruby2d/tileset.rb
316
316
  - lib/ruby2d/triangle.rb
317
317
  - lib/ruby2d/version.rb
318
+ - lib/ruby2d/vertices.rb
318
319
  - lib/ruby2d/window.rb
319
320
  homepage: http://www.ruby2d.com
320
321
  licenses:
@@ -335,7 +336,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
336
  - !ruby/object:Gem::Version
336
337
  version: '0'
337
338
  requirements: []
338
- rubygems_version: 3.2.24
339
+ rubygems_version: 3.2.27
339
340
  signing_key:
340
341
  specification_version: 4
341
342
  summary: Ruby 2D
data/ext/ruby2d/sprite.c DELETED
@@ -1,147 +0,0 @@
1
- // sprite.c
2
-
3
- #include "ruby2d.h"
4
-
5
-
6
- /*
7
- * Create a sprite, given an image file path
8
- */
9
- R2D_Sprite *R2D_CreateSprite(const char *path) {
10
-
11
- // Check if image file exists
12
- if (!R2D_FileExists(path)) {
13
- R2D_Error("R2D_CreateSprite", "Sprite image file `%s` not found", path);
14
- return NULL;
15
- }
16
-
17
- // Allocate the sprite structure
18
- R2D_Sprite *spr = (R2D_Sprite *) malloc(sizeof(R2D_Sprite));
19
- if (!spr) {
20
- R2D_Error("R2D_CreateSprite", "Out of memory!");
21
- return NULL;
22
- }
23
-
24
- // Load the sprite image file
25
- spr->img = R2D_CreateImage(path);
26
- if (!spr->img) {
27
- R2D_Error("R2D_CreateSprite", "Cannot create sprite image `%s`", path);
28
- free(spr);
29
- return NULL;
30
- }
31
-
32
- // Initialize values
33
- spr->path = path;
34
- spr->x = 0;
35
- spr->y = 0;
36
- spr->color.r = 1.f;
37
- spr->color.g = 1.f;
38
- spr->color.b = 1.f;
39
- spr->color.a = 1.f;
40
- spr->width = spr->img->width;
41
- spr->height = spr->img->height;
42
- spr->clip_width = spr->img->width;
43
- spr->clip_height = spr->img->height;
44
- spr->rotate = 0;
45
- spr->rx = 0;
46
- spr->ry = 0;
47
- spr->tx1 = 0.f;
48
- spr->ty1 = 0.f;
49
- spr->tx2 = 1.f;
50
- spr->ty2 = 0.f;
51
- spr->tx3 = 1.f;
52
- spr->ty3 = 1.f;
53
- spr->tx4 = 0.f;
54
- spr->ty4 = 1.f;
55
-
56
- return spr;
57
- }
58
-
59
-
60
- /*
61
- * Clip a sprite
62
- */
63
- void R2D_ClipSprite(R2D_Sprite *spr, int x, int y, int w, int h) {
64
- if (!spr) return;
65
-
66
- // Calculate ratios
67
- // rw = ratio width; rh = ratio height
68
- double rw = w / (double)spr->img->width;
69
- double rh = h / (double)spr->img->height;
70
-
71
- // Apply ratios to x, y coordinates
72
- // cx = crop x coord; cy = crop y coord
73
- double cx = x * rw;
74
- double cy = y * rh;
75
-
76
- // Convert given width, height to doubles
77
- // cw = crop width; ch = crop height
78
- double cw = (double)w;
79
- double ch = (double)h;
80
-
81
- // Apply ratio to texture width and height
82
- // tw = texture width; th = texture height
83
- double tw = rw * w;
84
- double th = rh * h;
85
-
86
- // Calculate and store sprite texture values
87
-
88
- spr->tx1 = cx / cw;
89
- spr->ty1 = cy / ch;
90
-
91
- spr->tx2 = (cx + tw) / cw;
92
- spr->ty2 = cy / ch;
93
-
94
- spr->tx3 = (cx + tw) / cw;
95
- spr->ty3 = (cy + th) / ch;
96
-
97
- spr->tx4 = cx / cw;
98
- spr->ty4 = (cy + th) / ch;
99
-
100
- // Store the sprite dimensions
101
- spr->width = (spr->width / (double)spr->clip_width ) * w;
102
- spr->height = (spr->height / (double)spr->clip_height) * h;
103
- spr->clip_width = w;
104
- spr->clip_height = h;
105
- }
106
-
107
-
108
- /*
109
- * Rotate a sprite
110
- */
111
- void R2D_RotateSprite(R2D_Sprite *spr, GLfloat angle, int position) {
112
-
113
- R2D_GL_Point p = R2D_GetRectRotationPoint(
114
- spr->x, spr->y, spr->width, spr->height, position
115
- );
116
-
117
- spr->rotate = angle;
118
- spr->rx = p.x;
119
- spr->ry = p.y;
120
- }
121
-
122
-
123
- /*
124
- * Draw a sprite
125
- */
126
- void R2D_DrawSprite(R2D_Sprite *spr) {
127
- if (!spr) return;
128
-
129
- if (spr->img->texture_id == 0) {
130
- R2D_GL_CreateTexture(&spr->img->texture_id, spr->img->format,
131
- spr->img->width, spr->img->height,
132
- spr->img->surface->pixels, GL_NEAREST);
133
- SDL_FreeSurface(spr->img->surface);
134
- }
135
-
136
- R2D_GL_DrawSprite(spr);
137
- }
138
-
139
-
140
- /*
141
- * Free a sprite
142
- */
143
- void R2D_FreeSprite(R2D_Sprite *spr) {
144
- if (!spr) return;
145
- R2D_FreeImage(spr->img);
146
- free(spr);
147
- }