cyberarm_engine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +43 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/cyberarm_engine.gemspec +36 -0
  11. data/lib/cyberarm_engine.rb +36 -0
  12. data/lib/cyberarm_engine/background.rb +166 -0
  13. data/lib/cyberarm_engine/common.rb +85 -0
  14. data/lib/cyberarm_engine/engine.rb +95 -0
  15. data/lib/cyberarm_engine/game_object.rb +256 -0
  16. data/lib/cyberarm_engine/game_state.rb +90 -0
  17. data/lib/cyberarm_engine/lib/bounding_box.rb +124 -0
  18. data/lib/cyberarm_engine/lib/vector.rb +97 -0
  19. data/lib/cyberarm_engine/objects/multi_line_text.rb +67 -0
  20. data/lib/cyberarm_engine/objects/text.rb +96 -0
  21. data/lib/cyberarm_engine/objects/timer.rb +23 -0
  22. data/lib/cyberarm_engine/ui/border_canvas.rb +101 -0
  23. data/lib/cyberarm_engine/ui/button.rb +53 -0
  24. data/lib/cyberarm_engine/ui/check_box.rb +52 -0
  25. data/lib/cyberarm_engine/ui/container.rb +154 -0
  26. data/lib/cyberarm_engine/ui/dsl.rb +82 -0
  27. data/lib/cyberarm_engine/ui/edit_line.rb +88 -0
  28. data/lib/cyberarm_engine/ui/element.rb +197 -0
  29. data/lib/cyberarm_engine/ui/event.rb +46 -0
  30. data/lib/cyberarm_engine/ui/flow.rb +15 -0
  31. data/lib/cyberarm_engine/ui/gui_state.rb +119 -0
  32. data/lib/cyberarm_engine/ui/image.rb +42 -0
  33. data/lib/cyberarm_engine/ui/label.rb +34 -0
  34. data/lib/cyberarm_engine/ui/stack.rb +11 -0
  35. data/lib/cyberarm_engine/ui/style.rb +15 -0
  36. data/lib/cyberarm_engine/ui/theme.rb +91 -0
  37. data/lib/cyberarm_engine/ui/toggle_button.rb +49 -0
  38. data/lib/cyberarm_engine/version.rb +4 -0
  39. metadata +137 -0
@@ -0,0 +1,46 @@
1
+ module CyberarmEngine
2
+ module Event # Gets included into Element
3
+ def subscribe(event, method = nil, &block)
4
+ handler = method || block
5
+ @event_handler[event] << handler
6
+
7
+ Subscription.new(self, event, handler)
8
+ end
9
+
10
+ def unsubscribe(subscription)
11
+ end
12
+
13
+ def publish(event, *args)
14
+ raise ArgumentError, "#{self.class} does not handle #{event.inspect}" unless @event_handler.include?(event)
15
+
16
+ return unless enabled?
17
+
18
+ if respond_to?(event)
19
+ return :handled if send(event, self, *args) == :handled
20
+ end
21
+
22
+ @event_handler[event].reverse_each do |handler|
23
+ return :handled if handler.call(self, *args) == :handled
24
+ end
25
+
26
+ return nil
27
+ end
28
+
29
+ def event(event)
30
+ @event_handler ||= Hash.new
31
+ @event_handler[event] ||= []
32
+ end
33
+ end
34
+
35
+ class Subscription
36
+ attr_reader :publisher, :event, :handler
37
+
38
+ def initialize(publisher, event, handler)
39
+ @publisher, @event, @handler = publisher, event, handler
40
+ end
41
+
42
+ def unsubscribe
43
+ @publisher.unsubscribe(self)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ module CyberarmEngine
2
+ class Flow < Container
3
+ include Common
4
+
5
+ def layout
6
+ @children.each do |child|
7
+ if fits_on_line?(child)
8
+ position_on_current_line(child)
9
+ else
10
+ position_on_next_line(child)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,119 @@
1
+ module CyberarmEngine
2
+ class GuiState < GameState
3
+ include Common
4
+ include DSL
5
+
6
+ def initialize(options = {})
7
+ @options = options
8
+ @game_objects = []
9
+ @global_pause = false
10
+
11
+ @down_keys = {}
12
+
13
+ @root_container = Stack.new
14
+ @game_objects << @root_container
15
+ @containers = [@root_container]
16
+
17
+ @focus = nil
18
+ @mouse_over = nil
19
+ @mouse_down_on = {}
20
+ @mouse_down_position = {}
21
+
22
+
23
+ setup
24
+ end
25
+
26
+ # throws :blur event to focused element and sets GuiState focused element
27
+ # Does NOT throw :focus event at element or set element as focused
28
+ def focus=(element)
29
+ @focus.publish(:blur) if @focus and element && @focus != element
30
+ @focus = element
31
+ end
32
+
33
+ def focused
34
+ @focus
35
+ end
36
+
37
+ def update
38
+ super
39
+
40
+ new_mouse_over = @root_container.hit_element?(window.mouse_x, window.mouse_y)
41
+ if new_mouse_over
42
+ new_mouse_over.publish(:enter) if new_mouse_over != @mouse_over
43
+ new_mouse_over.publish(:hover)
44
+ # puts "#{new_mouse_over.class}[#{new_mouse_over.value}]: #{new_mouse_over.x}:#{new_mouse_over.y} #{new_mouse_over.width}:#{new_mouse_over.height}" if new_mouse_over != @mouse_over
45
+ end
46
+ @mouse_over.publish(:leave) if @mouse_over && new_mouse_over != @mouse_over
47
+ @mouse_over = new_mouse_over
48
+
49
+ redirect_holding_mouse_button(:left) if @mouse_over && Gosu.button_down?(Gosu::MsLeft)
50
+ redirect_holding_mouse_button(:middle) if @mouse_over && Gosu.button_down?(Gosu::MsMiddle)
51
+ redirect_holding_mouse_button(:right) if @mouse_over && Gosu.button_down?(Gosu::MsRight)
52
+ end
53
+
54
+ def button_down(id)
55
+ super
56
+
57
+ case id
58
+ when Gosu::MsLeft
59
+ redirect_mouse_button(:left)
60
+ when Gosu::MsMiddle
61
+ redirect_mouse_button(:middle)
62
+ when Gosu::MsRight
63
+ redirect_mouse_button(:right)
64
+ end
65
+ end
66
+
67
+ def button_up(id)
68
+ super
69
+
70
+ case id
71
+ when Gosu::MsLeft
72
+ redirect_released_mouse_button(:left)
73
+ when Gosu::MsMiddle
74
+ redirect_released_mouse_button(:middle)
75
+ when Gosu::MsRight
76
+ redirect_released_mouse_button(:right)
77
+ when Gosu::MsWheelUp
78
+ redirect_mouse_wheel(:up)
79
+ when Gosu::MsWheelDown
80
+ redirect_mouse_wheel(:down)
81
+ end
82
+ end
83
+
84
+ def redirect_mouse_button(button)
85
+ if @focus && @mouse_over != @focus
86
+ @focus.publish(:blur)
87
+ @focus = nil
88
+ end
89
+
90
+ if @mouse_over
91
+ @mouse_down_position[button] = Vector.new(window.mouse_x, window.mouse_y)
92
+ @mouse_down_on[button] = @mouse_over
93
+
94
+ @mouse_over.publish(:"#{button}_mouse_button", window.mouse_x, window.mouse_y)
95
+ else
96
+ @mouse_down_position[button] = nil
97
+ @mouse_down_on[button] = nil
98
+ end
99
+ end
100
+
101
+ def redirect_released_mouse_button(button)
102
+ if @mouse_over
103
+ @mouse_over.publish(:"released_#{button}_mouse_button", window.mouse_x, window.mouse_y)
104
+ @mouse_over.publish(:"clicked_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over == @mouse_down_on[button]
105
+ end
106
+
107
+ @mouse_down_position[button] = nil
108
+ @mouse_down_on[button] = nil
109
+ end
110
+
111
+ def redirect_holding_mouse_button(button)
112
+ @mouse_over.publish(:"holding_#{button}_mouse_button", window.mouse_x, window.mouse_y) if @mouse_over
113
+ end
114
+
115
+ def redirect_mouse_wheel(button)
116
+ @mouse_over.publish(:"mouse_wheel_#{button}", window.mouse_x, window.mouse_y) if @mouse_over
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,42 @@
1
+ module CyberarmEngine
2
+ class Image < Element
3
+ def initialize(path, options = {}, block = nil)
4
+ super(options, block)
5
+ @path = path
6
+
7
+ @image = Gosu::Image.new(path, retro: @options[:image_retro])
8
+ if @options[:width] && @options[:height]
9
+ @scale_x = @options[:width].to_f / @image.width
10
+ @scale_y = @options[:height].to_f / @image.height
11
+ elsif @options[:width]
12
+ @scale_x = @options[:width].to_f / @image.width
13
+ @scale_y = @scale_x
14
+ elsif @options[:height]
15
+ @scale_y = @options[:height].to_f / @image.height
16
+ @scale_x = @scale_y
17
+ else
18
+ @scale_x, @scale_y = 1, 1
19
+ end
20
+
21
+ raise "Scale X" unless @scale_x.is_a?(Numeric)
22
+ raise "Scale Y" unless @scale_y.is_a?(Numeric)
23
+ end
24
+
25
+ def render
26
+ @image.draw(@border_thickness_left + @padding_left + @x, @border_thickness_top + @padding_top + @y, @z + 2, @scale_x, @scale_y) # TODO: Add color support?
27
+ end
28
+
29
+ def clicked_left_mouse_button(sender, x, y)
30
+ @block.call(self) if @block
31
+ end
32
+
33
+ def recalculate
34
+ @width = @image.width * @scale_x
35
+ @height = @image.height * @scale_y
36
+ end
37
+
38
+ def value
39
+ @path
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,34 @@
1
+ module CyberarmEngine
2
+ class Label < Element
3
+ def initialize(text, options = {}, block = nil)
4
+ super(options, block)
5
+
6
+ @text = Text.new(text, font: @options[:font], z: @z, color: @options[:color], size: @options[:text_size], shadow: @options[:text_shadow])
7
+
8
+ return self
9
+ end
10
+
11
+ def render
12
+ @text.draw
13
+ end
14
+
15
+ def clicked_left_mouse_button(sender, x, y)
16
+ @block.call(self) if @block
17
+ end
18
+
19
+ def recalculate
20
+ @width = @text.width.round
21
+ @height= @text.height.round
22
+
23
+ @text.x = @border_thickness_left + @padding_left + @x
24
+ @text.y = @border_thickness_top + @padding_top + @y
25
+ @text.z = @z + 3
26
+
27
+ update_background
28
+ end
29
+
30
+ def value
31
+ @text.text
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ module CyberarmEngine
2
+ class Stack < Container
3
+ include Common
4
+
5
+ def layout
6
+ @children.each do |child|
7
+ move_to_next_line(child)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module CyberarmEngine
2
+ class Style
3
+ def initialize(hash)
4
+ @hash = hash
5
+ end
6
+
7
+ def hash
8
+ @hash
9
+ end
10
+
11
+ def set(hash)
12
+ @hash.merge!(hash)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,91 @@
1
+ module CyberarmEngine
2
+ module Theme
3
+ def default(*args)
4
+ value = @options
5
+ args.each do |arg|
6
+ value = value.dig(arg)
7
+ end
8
+
9
+ value
10
+ end
11
+
12
+ def theme_defaults
13
+ raise "Error" unless self.class.ancestors.include?(CyberarmEngine::Element)
14
+
15
+ hash = {}
16
+ class_names = self.class.ancestors
17
+ class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! {|c| c.to_s.split("::").last.to_sym}.reverse!
18
+
19
+ class_names.each do |klass|
20
+ next unless data = THEME.dig(klass)
21
+ data.each do |key, value|
22
+ hash.merge!(data)
23
+ end
24
+ end
25
+
26
+ hash
27
+ end
28
+
29
+ THEME = {
30
+ Element: {
31
+ x: 0,
32
+ y: 0,
33
+ z: 30,
34
+
35
+ width: nil,
36
+ height: nil,
37
+ color: Gosu::Color::WHITE,
38
+ background: Gosu::Color::NONE,
39
+ margin: 0,
40
+ padding: 0,
41
+ border_thickness: 0,
42
+ border_color: Gosu::Color::NONE,
43
+ border_radius: 0,
44
+ },
45
+
46
+ Button: { # < Label
47
+ margin: 1,
48
+ padding: 4,
49
+ border_thickness: 4,
50
+ border_color: ["ffd59674".hex, "ffff8746".hex],
51
+ border_radius: 0,
52
+ background: ["ffc75e61".to_i(16), "ffe26623".to_i(16)],
53
+
54
+ hover: {
55
+ color: Gosu::Color.rgb(200,200,200),
56
+ background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)],
57
+ },
58
+
59
+ active: {
60
+ color: Gosu::Color::BLACK,
61
+ background: ["ffB23E41".to_i(16)]
62
+ }
63
+ },
64
+
65
+ EditLine: { # < Button
66
+ type: :text,
67
+ width: 200,
68
+ password_character: "•",
69
+ caret_width: 2,
70
+ caret_color: Gosu::Color::WHITE,
71
+ caret_interval: 500,
72
+ },
73
+
74
+ Image: {
75
+ retro: false
76
+ },
77
+
78
+ Label: { # < Element
79
+ text_size: 28,
80
+ text_shadow: false,
81
+ font: "Arial",
82
+ margin: 0,
83
+ padding: 2
84
+ },
85
+
86
+ ToggleButton: { # < Button
87
+ checkmark: "√"
88
+ }
89
+ }
90
+ end
91
+ end
@@ -0,0 +1,49 @@
1
+ module CyberarmEngine
2
+ class ToggleButton < Button
3
+ attr_reader :toggled
4
+
5
+ def initialize(options, block = nil)
6
+ super(options[:checkmark], options, block)
7
+ @toggled = options[:toggled] || false
8
+ if @toggled
9
+ @text.text = @options[:checkmark]
10
+ else
11
+ @text.text = ""
12
+ end
13
+
14
+ return self
15
+ end
16
+
17
+ def toggled=(boolean)
18
+ @toggled = !boolean
19
+ toggle
20
+ end
21
+
22
+ def clicked_left_mouse_button(sender, x, y)
23
+ toggle
24
+
25
+ @block.call(self) if @block
26
+ end
27
+
28
+ def toggle
29
+ if @toggled
30
+ @toggled = false
31
+ @text.text = ""
32
+ else
33
+ @toggled = true
34
+ @text.text = @options[:checkmark]
35
+ end
36
+ end
37
+
38
+ def recalculate
39
+ super
40
+
41
+ @width = @text.textobject.text_width(@options[:checkmark])
42
+ update_background
43
+ end
44
+
45
+ def value
46
+ @toggled
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,4 @@
1
+ module CyberarmEngine
2
+ NAME = "InDev"
3
+ VERSION = "0.1.0"
4
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cyberarm_engine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cyberarm
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-03-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gosu
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.14.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description: Yet another game making framework around gosu
70
+ email:
71
+ - matthewlikesrobots@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/setup
84
+ - cyberarm_engine.gemspec
85
+ - lib/cyberarm_engine.rb
86
+ - lib/cyberarm_engine/background.rb
87
+ - lib/cyberarm_engine/common.rb
88
+ - lib/cyberarm_engine/engine.rb
89
+ - lib/cyberarm_engine/game_object.rb
90
+ - lib/cyberarm_engine/game_state.rb
91
+ - lib/cyberarm_engine/lib/bounding_box.rb
92
+ - lib/cyberarm_engine/lib/vector.rb
93
+ - lib/cyberarm_engine/objects/multi_line_text.rb
94
+ - lib/cyberarm_engine/objects/text.rb
95
+ - lib/cyberarm_engine/objects/timer.rb
96
+ - lib/cyberarm_engine/ui/border_canvas.rb
97
+ - lib/cyberarm_engine/ui/button.rb
98
+ - lib/cyberarm_engine/ui/check_box.rb
99
+ - lib/cyberarm_engine/ui/container.rb
100
+ - lib/cyberarm_engine/ui/dsl.rb
101
+ - lib/cyberarm_engine/ui/edit_line.rb
102
+ - lib/cyberarm_engine/ui/element.rb
103
+ - lib/cyberarm_engine/ui/event.rb
104
+ - lib/cyberarm_engine/ui/flow.rb
105
+ - lib/cyberarm_engine/ui/gui_state.rb
106
+ - lib/cyberarm_engine/ui/image.rb
107
+ - lib/cyberarm_engine/ui/label.rb
108
+ - lib/cyberarm_engine/ui/stack.rb
109
+ - lib/cyberarm_engine/ui/style.rb
110
+ - lib/cyberarm_engine/ui/theme.rb
111
+ - lib/cyberarm_engine/ui/toggle_button.rb
112
+ - lib/cyberarm_engine/version.rb
113
+ homepage: https://github.com/cyberarm/cyberarm_engine
114
+ licenses:
115
+ - MIT
116
+ metadata:
117
+ allowed_push_host: https://rubygems.org
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.0.3
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Make games quickly and easily with gosu
137
+ test_files: []