cyberarm_engine 0.14.0 → 0.18.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +5 -4
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/assets/textures/logo.png +0 -0
  8. data/cyberarm_engine.gemspec +11 -9
  9. data/lib/cyberarm_engine.rb +19 -7
  10. data/lib/cyberarm_engine/animator.rb +13 -11
  11. data/lib/cyberarm_engine/background.rb +19 -15
  12. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  13. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  14. data/lib/cyberarm_engine/builtin/intro_state.rb +128 -0
  15. data/lib/cyberarm_engine/cache.rb +4 -0
  16. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  17. data/lib/cyberarm_engine/common.rb +18 -13
  18. data/lib/cyberarm_engine/config_file.rb +2 -2
  19. data/lib/cyberarm_engine/game_object.rb +63 -72
  20. data/lib/cyberarm_engine/game_state.rb +11 -3
  21. data/lib/cyberarm_engine/model.rb +207 -0
  22. data/lib/cyberarm_engine/model/material.rb +21 -0
  23. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  24. data/lib/cyberarm_engine/model/parser.rb +74 -0
  25. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  26. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  27. data/lib/cyberarm_engine/model_cache.rb +31 -0
  28. data/lib/cyberarm_engine/opengl.rb +28 -0
  29. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  30. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  31. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  32. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  33. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  34. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  35. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  36. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  37. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  38. data/lib/cyberarm_engine/ray.rb +5 -5
  39. data/lib/cyberarm_engine/stats.rb +2 -2
  40. data/lib/cyberarm_engine/text.rb +51 -27
  41. data/lib/cyberarm_engine/timer.rb +1 -1
  42. data/lib/cyberarm_engine/transform.rb +43 -20
  43. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  44. data/lib/cyberarm_engine/ui/dsl.rb +45 -12
  45. data/lib/cyberarm_engine/ui/element.rb +211 -61
  46. data/lib/cyberarm_engine/ui/elements/button.rb +72 -42
  47. data/lib/cyberarm_engine/ui/elements/check_box.rb +5 -2
  48. data/lib/cyberarm_engine/ui/elements/container.rb +81 -29
  49. data/lib/cyberarm_engine/ui/elements/edit_box.rb +175 -2
  50. data/lib/cyberarm_engine/ui/elements/edit_line.rb +139 -48
  51. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -1
  52. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  53. data/lib/cyberarm_engine/ui/elements/list_box.rb +78 -2
  54. data/lib/cyberarm_engine/ui/elements/progress.rb +5 -5
  55. data/lib/cyberarm_engine/ui/elements/radio.rb +1 -1
  56. data/lib/cyberarm_engine/ui/elements/slider.rb +13 -16
  57. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -1
  58. data/lib/cyberarm_engine/ui/elements/text_block.rb +153 -0
  59. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +27 -19
  60. data/lib/cyberarm_engine/ui/event.rb +7 -7
  61. data/lib/cyberarm_engine/ui/gui_state.rb +88 -16
  62. data/lib/cyberarm_engine/ui/style.rb +23 -11
  63. data/lib/cyberarm_engine/ui/theme.rb +95 -21
  64. data/lib/cyberarm_engine/vector.rb +33 -30
  65. data/lib/cyberarm_engine/version.rb +2 -2
  66. data/lib/cyberarm_engine/window.rb +35 -18
  67. metadata +70 -18
  68. data/lib/cyberarm_engine/ui/elements/label.rb +0 -52
@@ -1,11 +1,11 @@
1
1
  module Gosu
2
2
  class Color
3
- def _dump(level)
3
+ def _dump(_level)
4
4
  [
5
- "%02X" % self.alpha,
6
- "%02X" % self.red,
7
- "%02X" % self.green,
8
- "%02X" % self.blue
5
+ "%02X" % alpha,
6
+ "%02X" % red,
7
+ "%02X" % green,
8
+ "%02X" % blue
9
9
  ].join
10
10
  end
11
11
 
@@ -17,21 +17,33 @@ end
17
17
 
18
18
  module CyberarmEngine
19
19
  class Style
20
+ attr_reader :hash
21
+
20
22
  def initialize(hash = {})
21
- @hash = Marshal.load(Marshal.dump(hash))
23
+ h = Marshal.load(Marshal.dump(hash))
24
+
25
+ h[:default] = {}
26
+
27
+ h.each do |key, value|
28
+ next if value.is_a?(Hash)
29
+
30
+ h[:default][key] = value
31
+ end
32
+
33
+ @hash = h
22
34
  end
23
35
 
24
- def method_missing(method, *args, &block)
36
+ def method_missing(method, *args)
25
37
  if method.to_s.end_with?("=")
26
38
  raise "Did not expect more than 1 argument" if args.size > 1
27
- return @hash[method.to_s.sub("=", "").to_sym] = args.first
28
39
 
29
- elsif args.size == 0
30
- return @hash[method]
40
+ @hash[method.to_s.sub("=", "").to_sym] = args.first
31
41
 
42
+ elsif args.empty?
43
+ @hash[method]
32
44
  else
33
45
  raise ArgumentError, "Did not expect arguments"
34
46
  end
35
47
  end
36
48
  end
37
- end
49
+ end
@@ -11,17 +11,21 @@ module CyberarmEngine
11
11
 
12
12
  def theme_defaults(options)
13
13
  raise "Error" unless self.class.ancestors.include?(CyberarmEngine::Element)
14
+
14
15
  _theme = THEME
15
- _theme = _theme.merge(options[:theme]) if options[:theme]
16
+ _theme = deep_merge(_theme, options[:theme]) if options[:theme]
16
17
  _theme.delete(:theme) if options[:theme]
17
18
 
18
19
  hash = {}
19
20
  class_names = self.class.ancestors
20
- class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! {|c| c.to_s.split("::").last.to_sym}.reverse!
21
+ class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! do |c|
22
+ c.to_s.split("::").last.to_sym
23
+ end.reverse!
21
24
 
22
25
  class_names.each do |klass|
23
26
  next unless data = _theme.dig(klass)
24
- data.each do |key, value|
27
+
28
+ data.each do |_key, _value|
25
29
  hash.merge!(data)
26
30
  end
27
31
  end
@@ -32,7 +36,7 @@ module CyberarmEngine
32
36
  # Derived from Rails Hash#deep_merge!
33
37
  # Enables passing partial themes through Element options without issue
34
38
  def deep_merge(original, intergrate, &block)
35
- hash = original.merge(intergrate) do |key, this_val, other_val|
39
+ original.merge(intergrate) do |key, this_val, other_val|
36
40
  if this_val.is_a?(Hash) && other_val.is_a?(Hash)
37
41
  deep_merge(this_val, other_val, &block)
38
42
  elsif block_given?
@@ -41,8 +45,6 @@ module CyberarmEngine
41
45
  other_val
42
46
  end
43
47
  end
44
-
45
- return hash
46
48
  end
47
49
 
48
50
  THEME = {
@@ -51,33 +53,44 @@ module CyberarmEngine
51
53
  y: 0,
52
54
  z: 30,
53
55
 
54
- width: nil,
56
+ width: nil,
55
57
  height: nil,
56
- color: Gosu::Color::WHITE,
58
+ color: Gosu::Color::WHITE,
57
59
  background: Gosu::Color::NONE,
58
- margin: 0,
59
- padding: 0,
60
+ margin: 0,
61
+ padding: 0,
60
62
  border_thickness: 0,
61
63
  border_color: Gosu::Color::NONE,
62
- border_radius: 0,
64
+ border_radius: 0
65
+ },
66
+
67
+ Container: { # < Element (Base class for Stack and Flow)
68
+ debug_color: Gosu::Color::YELLOW
63
69
  },
64
70
 
65
71
  Button: { # < Label
66
- margin: 1,
67
- padding: 4,
72
+ margin: 1,
73
+ padding: 4,
68
74
  border_thickness: 1,
69
75
  border_color: ["ffd59674".hex, "ffff8746".hex],
70
76
  border_radius: 0,
71
77
  background: ["ffc75e61".to_i(16), "ffe26623".to_i(16)],
78
+ text_align: :center,
79
+ text_wrap: :none,
72
80
 
73
81
  hover: {
74
- color: Gosu::Color.rgb(200,200,200),
75
- background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)],
82
+ color: Gosu::Color.rgb(200, 200, 200),
83
+ background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)]
76
84
  },
77
85
 
78
86
  active: {
79
87
  color: Gosu::Color::BLACK,
80
88
  background: ["ffB23E41".to_i(16)]
89
+ },
90
+
91
+ disabled: {
92
+ color: Gosu::Color::GRAY,
93
+ background: 0xff303030
81
94
  }
82
95
  },
83
96
 
@@ -89,24 +102,85 @@ module CyberarmEngine
89
102
  caret_color: Gosu::Color::WHITE,
90
103
  caret_interval: 500,
91
104
  selection_color: Gosu::Color.rgba(255, 128, 50, 200),
105
+ text_align: :left
92
106
  },
93
107
 
94
108
  Image: { # < Element
109
+ color: Gosu::Color::WHITE,
110
+ tileable: false,
95
111
  retro: false
96
112
  },
97
113
 
98
- Label: { # < Element
99
- text_size: 28,
100
- text_shadow: false,
101
- font: "Arial",
102
- margin: 0,
103
- padding: 2
114
+ TextBlock: { # < Element
115
+ text_size: 28,
116
+ text_wrap: :word_wrap, # :word_wrap, :break_word, :none
117
+ text_shadow: false,
118
+ text_align: :left,
119
+ font: "Arial",
120
+ margin: 0,
121
+ padding: 2
122
+ },
123
+
124
+ Banner: { # < TextBlock
125
+ text_size: 48
126
+ },
127
+
128
+ Title: { # < TextBlock
129
+ text_size: 34
130
+ },
131
+
132
+ Subtitle: { # < TextBlock
133
+ text_size: 26
134
+ },
135
+
136
+ Tagline: { # < TextBlock
137
+ text_size: 24
138
+ },
139
+
140
+ Caption: { # < TextBlock
141
+ text_size: 22
142
+ },
143
+
144
+ Para: { # < TextBlock
145
+ text_size: 18
146
+ },
147
+
148
+ Inscription: { # < TextBlock
149
+ text_size: 16
150
+ },
151
+
152
+ ToolTip: { # < TextBlock
153
+ color: Gosu::Color::WHITE,
154
+ padding_top: 4,
155
+ padding_bottom: 4,
156
+ padding_left: 8,
157
+ padding_right: 8,
158
+ border_thickness: 1,
159
+ border_color: 0xffaaaaaa,
160
+ background: 0xff404040
161
+ },
162
+ Link: { # < TextBlock
163
+ color: Gosu::Color::BLUE,
164
+ border_thickness: 1,
165
+ border_bottom_color: Gosu::Color::BLUE,
166
+ hover: {
167
+ color: 0xff_ff00ff,
168
+ border_bottom_color: 0xff_ff00ff
169
+ },
170
+ active: {
171
+ color: 0xff_ff0000,
172
+ border_bottom_color: 0xff_ff0000
173
+ }
104
174
  },
105
175
 
106
176
  ToggleButton: { # < Button
107
177
  checkmark: "√"
108
178
  },
109
179
 
180
+ CheckBox: { # < Flow
181
+ text_wrap: :none
182
+ },
183
+
110
184
  Progress: { # < Element
111
185
  width: 250,
112
186
  height: 36,
@@ -60,22 +60,15 @@ module CyberarmEngine
60
60
  Vector.new(0, 0, -1)
61
61
  end
62
62
 
63
+ attr_accessor :x, :y, :z, :weight
64
+
63
65
  def initialize(x = 0, y = 0, z = 0, weight = 0)
64
- @x, @y, @z, @weight = x, y, z, weight
66
+ @x = x
67
+ @y = y
68
+ @z = z
69
+ @weight = weight
65
70
  end
66
71
 
67
- def x; @x; end
68
- def x=(n); @x = n; end
69
-
70
- def y; @y; end
71
- def y=(n); @y = n; end
72
-
73
- def z; @z; end
74
- def z=(n); @z = n; end
75
-
76
- def weight; @weight; end
77
- def weight=(n); @weight = n; end
78
-
79
72
  alias w weight
80
73
  alias w= weight=
81
74
 
@@ -83,14 +76,14 @@ module CyberarmEngine
83
76
  def ==(other)
84
77
  if other.is_a?(Numeric)
85
78
  @x == other &&
86
- @y == other &&
87
- @z == other &&
88
- @weight == other
79
+ @y == other &&
80
+ @z == other &&
81
+ @weight == other
89
82
  elsif other.is_a?(Vector)
90
83
  @x == other.x &&
91
- @y == other.y &&
92
- @z == other.z &&
93
- @weight == other.weight
84
+ @y == other.y &&
85
+ @z == other.z &&
86
+ @weight == other.weight
94
87
  else
95
88
  other == self
96
89
  end
@@ -137,6 +130,17 @@ module CyberarmEngine
137
130
  operator("*", other)
138
131
  end
139
132
 
133
+ def multiply_transform(transform)
134
+ e = transform.elements
135
+
136
+ x = @x * e[0] + @y * e[1] + @z * e[2] + 1 * e[3]
137
+ y = @x * e[4] + @y * e[5] + @z * e[6] + 1 * e[7]
138
+ z = @x * e[8] + @y * e[9] + @z * e[10] + 1 * e[11]
139
+ w = @x * e[12] + @y * e[13] + @z * e[14] + 1 * e[15]
140
+
141
+ Vector.new(x / 1, y / 1, z / 1, w / 1)
142
+ end
143
+
140
144
  # Divides Vector and Numeric or Vector and Vector, excluding {weight}
141
145
  # @return [CyberarmEngine::Vector]
142
146
  def /(other)
@@ -161,20 +165,20 @@ module CyberarmEngine
161
165
  def dot(other)
162
166
  product = 0
163
167
 
164
- a = self.to_a
168
+ a = to_a
165
169
  b = other.to_a
166
170
 
167
171
  3.times do |i|
168
- product = product + (a[i] * b[i])
172
+ product += (a[i] * b[i])
169
173
  end
170
174
 
171
- return product
175
+ product
172
176
  end
173
177
 
174
178
  # cross product of {Vector}
175
179
  # @return [CyberarmEngine::Vector]
176
180
  def cross(other)
177
- a = self.to_a
181
+ a = to_a
178
182
  b = other.to_a
179
183
 
180
184
  Vector.new(
@@ -187,7 +191,7 @@ module CyberarmEngine
187
191
  # returns degrees
188
192
  # @return [Float]
189
193
  def angle(other)
190
- Math.acos( self.normalized.dot(other.normalized) ) * 180 / Math::PI
194
+ Math.acos(normalized.dot(other.normalized)) * 180 / Math::PI
191
195
  end
192
196
 
193
197
  # returns magnitude of Vector, ignoring #weight
@@ -209,7 +213,6 @@ module CyberarmEngine
209
213
  self / Vector.new(mag, mag, mag)
210
214
  end
211
215
 
212
-
213
216
  # returns a direction {Vector}
214
217
  #
215
218
  # z is pitch
@@ -254,19 +257,19 @@ module CyberarmEngine
254
257
  # 2D distance using X and Y
255
258
  # @return [Float]
256
259
  def distance(other)
257
- Math.sqrt((@x-other.x)**2 + (@y-other.y)**2)
260
+ Math.sqrt((@x - other.x)**2 + (@y - other.y)**2)
258
261
  end
259
262
 
260
263
  # 2D distance using X and Z
261
264
  # @return [Float]
262
265
  def gl_distance2d(other)
263
- Math.sqrt((@x-other.x)**2 + (@z-other.z)**2)
266
+ Math.sqrt((@x - other.x)**2 + (@z - other.z)**2)
264
267
  end
265
268
 
266
269
  # 3D distance using X, Y, and Z
267
270
  # @return [Float]
268
271
  def distance3d(other)
269
- Math.sqrt((@x-other.x)**2 + (@y-other.y)**2 + (@z-other.z)**2)
272
+ Math.sqrt((@x - other.x)**2 + (@y - other.y)**2 + (@z - other.z)**2)
270
273
  end
271
274
 
272
275
  # Converts {Vector} to Array
@@ -284,7 +287,7 @@ module CyberarmEngine
284
287
  # Converts {Vector} to Hash
285
288
  # @return [Hash]
286
289
  def to_h
287
- {x: @x, y: @y, z: @z, weight: @weight}
290
+ { x: @x, y: @y, z: @z, weight: @weight }
288
291
  end
289
292
  end
290
- end
293
+ end
@@ -1,4 +1,4 @@
1
1
  module CyberarmEngine
2
- NAME = "InDev"
3
- VERSION = "0.14.0"
2
+ NAME = "InDev".freeze
3
+ VERSION = "0.18.0".freeze
4
4
  end
@@ -1,10 +1,13 @@
1
1
  module CyberarmEngine
2
2
  class Window < Gosu::Window
3
+ include Common
4
+
3
5
  IMAGES = {}
4
- SAMPLES= {}
5
- SONGS = {}
6
+ SAMPLES = {}
7
+ SONGS = {}
6
8
 
7
9
  attr_accessor :show_cursor
10
+ attr_writer :exit_on_opengl_error
8
11
  attr_reader :last_frame_time
9
12
 
10
13
  def self.now
@@ -12,19 +15,20 @@ module CyberarmEngine
12
15
  end
13
16
 
14
17
  def self.dt
15
- $window.last_frame_time/1000.0
18
+ $window.last_frame_time / 1000.0
16
19
  end
17
20
 
18
- def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0/60, resizable: false)
21
+ def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
19
22
  @show_cursor = false
20
23
 
21
- super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable)
24
+ super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
22
25
  $window = self
23
- @last_frame_time = Gosu.milliseconds-1
26
+ @last_frame_time = Gosu.milliseconds - 1
24
27
  @current_frame_time = Gosu.milliseconds
25
28
  self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
26
29
 
27
30
  @states = []
31
+ @exit_on_opengl_error = false
28
32
 
29
33
  setup if defined?(setup)
30
34
  end
@@ -37,7 +41,7 @@ module CyberarmEngine
37
41
  Stats.clear
38
42
 
39
43
  current_state.update if current_state
40
- @last_frame_time = Gosu.milliseconds-@current_frame_time
44
+ @last_frame_time = Gosu.milliseconds - @current_frame_time
41
45
  @current_frame_time = Gosu.milliseconds
42
46
  end
43
47
 
@@ -46,7 +50,15 @@ module CyberarmEngine
46
50
  end
47
51
 
48
52
  def dt
49
- @last_frame_time/1000.0
53
+ @last_frame_time / 1000.0
54
+ end
55
+
56
+ def aspect_ratio
57
+ width / height.to_f
58
+ end
59
+
60
+ def exit_on_opengl_error?
61
+ @exit_on_opengl_error
50
62
  end
51
63
 
52
64
  def button_down(id)
@@ -59,21 +71,23 @@ module CyberarmEngine
59
71
  current_state.button_up(id) if current_state
60
72
  end
61
73
 
62
- def push_state(klass, options={})
63
- options = {setup: true}.merge(options)
74
+ def push_state(klass, options = {})
75
+ options = { setup: true }.merge(options)
64
76
 
65
77
  if klass.instance_of?(klass.class) && defined?(klass.options)
66
78
  @states << klass
67
79
  klass.setup if options[:setup]
80
+ klass.post_setup if options[:setup]
68
81
  else
69
82
  @states << klass.new(options) if child_of?(klass, GameState)
70
83
  @states << klass.new if child_of?(klass, Element::Container)
71
- current_state.setup if current_state.class == klass && options[:setup]
84
+ current_state.setup if current_state.instance_of?(klass) && options[:setup]
85
+ current_state.post_setup if current_state.instance_of?(klass) && options[:setup]
72
86
  end
73
87
  end
74
88
 
75
89
  private def child_of?(input, klass)
76
- input.ancestors.detect {|c| c == klass}
90
+ input.ancestors.detect { |c| c == klass }
77
91
  end
78
92
 
79
93
  def current_state
@@ -81,10 +95,8 @@ module CyberarmEngine
81
95
  end
82
96
 
83
97
  def previous_state
84
- if @states.size > 1 && state = @states[@states.size-2]
85
- return state
86
- else
87
- return nil
98
+ if @states.size > 1 && (state = @states[@states.size - 2])
99
+ state
88
100
  end
89
101
  end
90
102
 
@@ -92,11 +104,16 @@ module CyberarmEngine
92
104
  @states.pop
93
105
  end
94
106
 
107
+ def shift_state
108
+ @states.shift
109
+ end
110
+
95
111
  # Sourced from https://gist.github.com/ippa/662583
96
- def draw_circle(cx,cy,r, z = 9999,color = Gosu::Color::GREEN, step = 10)
112
+ def draw_circle(cx, cy, r, z = 9999, color = Gosu::Color::GREEN, step = 10)
97
113
  0.step(360, step) do |a1|
98
114
  a2 = a1 + step
99
- draw_line(cx + Gosu.offset_x(a1, r), cy + Gosu.offset_y(a1, r), color, cx + Gosu.offset_x(a2, r), cy + Gosu.offset_y(a2, r), color, z)
115
+ draw_line(cx + Gosu.offset_x(a1, r), cy + Gosu.offset_y(a1, r), color, cx + Gosu.offset_x(a2, r),
116
+ cy + Gosu.offset_y(a2, r), color, z)
100
117
  end
101
118
  end
102
119
  end