ruby2d 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }