gosling 2.3.0 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,24 @@
1
- require 'singleton'
2
-
3
- module Gosling
4
- ##
5
- # A cached Gosu::Image repository.
6
- #
7
- class ImageLibrary
8
- @@cache = {}
9
-
10
- include Singleton
11
-
12
- ##
13
- # When passed the path to an image, it first checks to see if that image is in the cache. If so, it returns the cached
14
- # Gosu::Image. Otherwise, it loads the image, stores it in the cache, and returns it.
15
- #
16
- def self.get(filename)
17
- unless @@cache.has_key?(filename)
18
- raise ArgumentError.new("File not found: '#{filename}' in '#{Dir.pwd}'") unless File.exists?(filename)
19
- @@cache[filename] = Gosu::Image.new(filename, tileable: true)
20
- end
21
- @@cache[filename]
22
- end
23
- end
24
- end
1
+ require 'singleton'
2
+
3
+ module Gosling
4
+ ##
5
+ # A cached Gosu::Image repository.
6
+ #
7
+ class ImageLibrary
8
+ @@cache = {}
9
+
10
+ include Singleton
11
+
12
+ ##
13
+ # When passed the path to an image, it first checks to see if that image is in the cache. If so, it returns the cached
14
+ # Gosu::Image. Otherwise, it loads the image, stores it in the cache, and returns it.
15
+ #
16
+ def self.get(filename)
17
+ unless @@cache.has_key?(filename)
18
+ raise ArgumentError.new("File not found: '#{filename}' in '#{Dir.pwd}'") unless File.exists?(filename)
19
+ @@cache[filename] = Gosu::Image.new(filename, tileable: true)
20
+ end
21
+ @@cache[filename]
22
+ end
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- module Gosling
2
- class InheritanceError < StandardError
3
- end
4
- end
1
+ module Gosling
2
+ class InheritanceError < StandardError
3
+ end
4
+ end
@@ -1,21 +1,23 @@
1
- require_relative 'object_cache.rb'
2
-
3
- class MatrixCache
4
- include Singleton
5
- include ObjectCache
6
-
7
- def initialize
8
- @cache = {}
9
- end
10
-
11
- protected
12
-
13
- def create
14
- Snow::Mat3.new
15
- end
16
-
17
- def reset(matrix)
18
- type_check(matrix, Snow::Mat3)
19
- matrix.load_identity
20
- end
21
- end
1
+ require 'singleton'
2
+
3
+ require_relative 'object_cache.rb'
4
+
5
+ class MatrixCache
6
+ include Singleton
7
+ include ObjectCache
8
+
9
+ def initialize
10
+ @cache = {}
11
+ end
12
+
13
+ protected
14
+
15
+ def create
16
+ Snow::Mat3.new
17
+ end
18
+
19
+ def reset(matrix)
20
+ type_check(matrix, Snow::Mat3)
21
+ matrix.load_identity
22
+ end
23
+ end
@@ -1,48 +1,48 @@
1
- require 'fiddle'
2
-
3
- class Object
4
- FIDDLE_FREEZE_BIT = ~(1 << 3)
5
-
6
- def unfreeze
7
- ptr = @fiddle_pointer || Fiddle::Pointer.new(object_id * 2)
8
- ptr[1] &= FIDDLE_FREEZE_BIT
9
- @fiddle_pointer = ptr
10
- end
11
- end
12
-
13
- module ObjectCache
14
- def clear
15
- @cache.clear
16
- end
17
-
18
- def recycle(obj)
19
- return if @cache.key?(obj.object_id)
20
- self.reset(obj)
21
- obj.freeze
22
- @cache[obj.object_id] = obj
23
- end
24
-
25
- def get
26
- if @cache.empty?
27
- self.create
28
- else
29
- obj = @cache.delete(@cache.keys.first)
30
- obj.unfreeze
31
- obj
32
- end
33
- end
34
-
35
- def size
36
- @cache.size
37
- end
38
-
39
- protected
40
-
41
- def create
42
- raise "Derived classes must implement create()."
43
- end
44
-
45
- def reset(obj)
46
- raise "Derived classes must implement reset()."
47
- end
48
- end
1
+ require 'fiddle'
2
+
3
+ class Object
4
+ FIDDLE_FREEZE_BIT = ~(1 << 3)
5
+
6
+ def unfreeze
7
+ ptr = @fiddle_pointer || Fiddle::Pointer.new(object_id * 2)
8
+ ptr[1] &= FIDDLE_FREEZE_BIT
9
+ @fiddle_pointer = ptr
10
+ end
11
+ end
12
+
13
+ module ObjectCache
14
+ def clear
15
+ @cache.clear
16
+ end
17
+
18
+ def recycle(obj)
19
+ return if @cache.key?(obj.object_id)
20
+ self.reset(obj)
21
+ obj.freeze
22
+ @cache[obj.object_id] = obj
23
+ end
24
+
25
+ def get
26
+ if @cache.empty?
27
+ self.create
28
+ else
29
+ obj = @cache.delete(@cache.keys.first)
30
+ obj.unfreeze
31
+ obj
32
+ end
33
+ end
34
+
35
+ def size
36
+ @cache.size
37
+ end
38
+
39
+ protected
40
+
41
+ def create
42
+ raise "Derived classes must implement create()."
43
+ end
44
+
45
+ def reset(obj)
46
+ raise "Derived classes must implement reset()."
47
+ end
48
+ end
@@ -1,42 +1,42 @@
1
- require 'snow-math'
2
-
3
- module Snow
4
- class Mat3
5
- ##
6
- # Monkey-patch fix for Mat3 * Vec3
7
- #
8
- def multiply(rhs, out = nil)
9
- case rhs
10
- when ::Snow::Mat3
11
- multiply_mat3(rhs, out)
12
- when ::Snow::Vec3
13
- values = (0..2).map { |i| get_row3(i) ** rhs }
14
- out ||= Snow::Vec3.new
15
- out.set(values)
16
- when Numeric
17
- scale(rhs, rhs, rhs, out)
18
- else
19
- raise TypeError, "Invalid type for RHS"
20
- end
21
- end
22
- alias_method :*, :multiply
23
-
24
- ##
25
- # Monkey-patch fix for #multiply! type-switching
26
- #
27
- def multiply!(rhs)
28
- multiply rhs, case rhs
29
- when ::Snow::Mat3, Numeric then self
30
- when ::Snow::Vec3 then rhs
31
- else raise TypeError, "Invalid type for RHS"
32
- end
33
- end
34
-
35
- ##
36
- # Returns true if this Mat3 is an identity matrix.
37
- #
38
- def identity?
39
- [1, 2, 3, 5, 6, 7].all? { |i| self[i] == 0 } && [0, 4, 8].all? { |i| self[i] == 1 }
40
- end
41
- end
42
- end
1
+ require 'snow-math'
2
+
3
+ module Snow
4
+ class Mat3
5
+ ##
6
+ # Monkey-patch fix for Mat3 * Vec3
7
+ #
8
+ def multiply(rhs, out = nil)
9
+ case rhs
10
+ when ::Snow::Mat3
11
+ multiply_mat3(rhs, out)
12
+ when ::Snow::Vec3
13
+ values = (0..2).map { |i| get_row3(i) ** rhs }
14
+ out ||= Snow::Vec3.new
15
+ out.set(values)
16
+ when Numeric
17
+ scale(rhs, rhs, rhs, out)
18
+ else
19
+ raise TypeError, "Invalid type for RHS"
20
+ end
21
+ end
22
+ alias_method :*, :multiply
23
+
24
+ ##
25
+ # Monkey-patch fix for #multiply! type-switching
26
+ #
27
+ def multiply!(rhs)
28
+ multiply rhs, case rhs
29
+ when ::Snow::Mat3, Numeric then self
30
+ when ::Snow::Vec3 then rhs
31
+ else raise TypeError, "Invalid type for RHS"
32
+ end
33
+ end
34
+
35
+ ##
36
+ # Returns true if this Mat3 is an identity matrix.
37
+ #
38
+ def identity?
39
+ [1, 2, 3, 5, 6, 7].all? { |i| self[i] == 0 } && [0, 4, 8].all? { |i| self[i] == 1 }
40
+ end
41
+ end
42
+ end
@@ -1,122 +1,122 @@
1
- require_relative 'actor.rb'
2
- require_relative 'collision.rb'
3
- require_relative 'utils.rb'
4
-
5
- module Gosling
6
- ##
7
- # A Polygon is an Actor with a shape defined by three or more vertices. Can be used to make triangles, hexagons, or
8
- # any other unusual geometry not covered by the other Actors. For circles, you should use Circle. For squares or
9
- # rectangles, see Rect.
10
- #
11
- class Polygon < Actor
12
- ##
13
- # Creates a new, square Polygon with a width and height of 1.
14
- #
15
- def initialize(window)
16
- type_check(window, Gosu::Window)
17
- super(window)
18
- @vertices = [
19
- Snow::Vec3[0, 0, 0],
20
- Snow::Vec3[1, 0, 0],
21
- Snow::Vec3[1, 1, 0],
22
- Snow::Vec3[0, 1, 0]
23
- ]
24
- end
25
-
26
- ##
27
- # Returns a copy of this Polygon's vertices (@vertices is read-only).
28
- #
29
- def get_vertices
30
- @vertices.dup
31
- end
32
-
33
- ##
34
- # Sets this polygon's vertices. Requires three or more Snow::Vec2, Vec3, Vec4, or Arrays containing 2 or more
35
- # numbers.
36
- #
37
- # Usage:
38
- # - polygon.set_vertices([Snow::Vec3[-1, 0, 0], Snow::Vec3[0, -1, 0], Snow::Vec3[1, 1, 0]])
39
- #
40
- def set_vertices(vertices)
41
- type_check(vertices, Array)
42
- raise ArgumentError.new("set_vertices() expects an array of at least three 2D vectors") unless vertices.length >= 3
43
- vertices.each do |v|
44
- types_check(v, Snow::Vec2, Snow::Vec3, Snow::Vec4, Array)
45
- if v.is_a?(Array)
46
- raise ArgumentError.new("set_vertices() expects an array of at least three 2D vectors") unless v.length >= 2
47
- v.each { |n| type_check(n, Numeric) }
48
- end
49
- end
50
-
51
- if @vertices.length < vertices.length
52
- @vertices.concat(Array.new(vertices.length - @vertices.length) { Snow::Vec3.new })
53
- elsif @vertices.length > vertices.length
54
- @vertices.pop(@vertices.length - vertices.length)
55
- end
56
-
57
- vertices.each_index { |i| @vertices[i].set(vertices[i][0], vertices[i][1], 0) }
58
- end
59
-
60
- ##
61
- # Sets this polygon to a rectangular shape with the given width and height, with its upper left at local [0, 0].
62
- #
63
- def set_vertices_rect(width, height)
64
- raise ArgumentError.new("Expected positive non-zero integer, but received #{width.inspect}!") unless width > 0
65
- raise ArgumentError.new("Expected positive non-zero integer, but received #{height.inspect}!") unless height > 0
66
-
67
- if @vertices.length < 4
68
- @vertices.concat(Array.new(4 - @vertices.length) { Snow::Vec3.new })
69
- elsif @vertices.length > 4
70
- @vertices.pop(@vertices.length - 4)
71
- end
72
-
73
- @vertices[0].set( 0, 0, 0)
74
- @vertices[1].set(width, 0, 0)
75
- @vertices[2].set(width, height, 0)
76
- @vertices[3].set( 0, height, 0)
77
- end
78
-
79
- ##
80
- # Returns an array containing all of our local vertices transformed to global-space. (See Actor#get_global_transform.)
81
- #
82
- def get_global_vertices(out = nil)
83
- type_check(out, Array) unless out.nil?
84
-
85
- tf = MatrixCache.instance.get
86
- get_global_transform(tf)
87
-
88
- if out.nil?
89
- return @vertices.map { |v| Transformable.transform_point(tf, v, Snow::Vec3.new) }
90
- end
91
-
92
- @vertices.each_index do |i|
93
- v = @vertices[i]
94
- if out[i]
95
- Transformable.transform_point(tf, v, out[i])
96
- else
97
- out[i] = Transformable.transform_point(tf, v)
98
- end
99
- end
100
- out
101
- ensure
102
- MatrixCache.instance.recycle(tf) if tf
103
- end
104
-
105
- ##
106
- # Returns true if the point is inside of this Polygon, false otherwise.
107
- #
108
- def is_point_in_bounds(point)
109
- Collision.is_point_in_shape?(point, self)
110
- end
111
-
112
- private
113
-
114
- def render(matrix)
115
- # TODO: write transformed vertices to a reserved list of vertices retained in memory each time
116
- type_check(matrix, Snow::Mat3)
117
- global_vertices = @vertices.map { |v| Transformable.transform_point(matrix, v) }
118
-
119
- fill_polygon(global_vertices)
120
- end
121
- end
122
- end
1
+ require_relative 'actor.rb'
2
+ require_relative 'collision.rb'
3
+ require_relative 'utils.rb'
4
+
5
+ module Gosling
6
+ ##
7
+ # A Polygon is an Actor with a shape defined by three or more vertices. Can be used to make triangles, hexagons, or
8
+ # any other unusual geometry not covered by the other Actors. For circles, you should use Circle. For squares or
9
+ # rectangles, see Rect.
10
+ #
11
+ class Polygon < Actor
12
+ ##
13
+ # Creates a new, square Polygon with a width and height of 1.
14
+ #
15
+ def initialize(window)
16
+ type_check(window, Gosu::Window)
17
+ super(window)
18
+ @vertices = [
19
+ Snow::Vec3[0, 0, 0],
20
+ Snow::Vec3[1, 0, 0],
21
+ Snow::Vec3[1, 1, 0],
22
+ Snow::Vec3[0, 1, 0]
23
+ ]
24
+ end
25
+
26
+ ##
27
+ # Returns a copy of this Polygon's vertices (@vertices is read-only).
28
+ #
29
+ def get_vertices
30
+ @vertices.dup
31
+ end
32
+
33
+ ##
34
+ # Sets this polygon's vertices. Requires three or more Snow::Vec2, Vec3, Vec4, or Arrays containing 2 or more
35
+ # numbers.
36
+ #
37
+ # Usage:
38
+ # - polygon.set_vertices([Snow::Vec3[-1, 0, 0], Snow::Vec3[0, -1, 0], Snow::Vec3[1, 1, 0]])
39
+ #
40
+ def set_vertices(vertices)
41
+ type_check(vertices, Array)
42
+ raise ArgumentError.new("set_vertices() expects an array of at least three 2D vectors") unless vertices.length >= 3
43
+ vertices.each do |v|
44
+ types_check(v, Snow::Vec2, Snow::Vec3, Snow::Vec4, Array)
45
+ if v.is_a?(Array)
46
+ raise ArgumentError.new("set_vertices() expects an array of at least three 2D vectors") unless v.length >= 2
47
+ v.each { |n| type_check(n, Numeric) }
48
+ end
49
+ end
50
+
51
+ if @vertices.length < vertices.length
52
+ @vertices.concat(Array.new(vertices.length - @vertices.length) { Snow::Vec3.new })
53
+ elsif @vertices.length > vertices.length
54
+ @vertices.pop(@vertices.length - vertices.length)
55
+ end
56
+
57
+ vertices.each_index { |i| @vertices[i].set(vertices[i][0], vertices[i][1], 0) }
58
+ end
59
+
60
+ ##
61
+ # Sets this polygon to a rectangular shape with the given width and height, with its upper left at local [0, 0].
62
+ #
63
+ def set_vertices_rect(width, height)
64
+ raise ArgumentError.new("Expected positive non-zero integer, but received #{width.inspect}!") unless width > 0
65
+ raise ArgumentError.new("Expected positive non-zero integer, but received #{height.inspect}!") unless height > 0
66
+
67
+ if @vertices.length < 4
68
+ @vertices.concat(Array.new(4 - @vertices.length) { Snow::Vec3.new })
69
+ elsif @vertices.length > 4
70
+ @vertices.pop(@vertices.length - 4)
71
+ end
72
+
73
+ @vertices[0].set( 0, 0, 0)
74
+ @vertices[1].set(width, 0, 0)
75
+ @vertices[2].set(width, height, 0)
76
+ @vertices[3].set( 0, height, 0)
77
+ end
78
+
79
+ ##
80
+ # Returns an array containing all of our local vertices transformed to global-space. (See Actor#get_global_transform.)
81
+ #
82
+ def get_global_vertices(out = nil)
83
+ type_check(out, Array) unless out.nil?
84
+
85
+ tf = MatrixCache.instance.get
86
+ get_global_transform(tf)
87
+
88
+ if out.nil?
89
+ return @vertices.map { |v| Transformable.transform_point(tf, v, Snow::Vec3.new) }
90
+ end
91
+
92
+ @vertices.each_index do |i|
93
+ v = @vertices[i]
94
+ if out[i]
95
+ Transformable.transform_point(tf, v, out[i])
96
+ else
97
+ out[i] = Transformable.transform_point(tf, v)
98
+ end
99
+ end
100
+ out
101
+ ensure
102
+ MatrixCache.instance.recycle(tf) if tf
103
+ end
104
+
105
+ ##
106
+ # Returns true if the point is inside of this Polygon, false otherwise.
107
+ #
108
+ def is_point_in_bounds(point)
109
+ Collision.is_point_in_shape?(point, self)
110
+ end
111
+
112
+ private
113
+
114
+ def render(matrix)
115
+ # TODO: write transformed vertices to a reserved list of vertices retained in memory each time
116
+ type_check(matrix, Snow::Mat3)
117
+ global_vertices = @vertices.map { |v| Transformable.transform_point(matrix, v) }
118
+
119
+ fill_polygon(global_vertices)
120
+ end
121
+ end
122
+ end