cyberarm_engine 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cyberarm_engine.gemspec +36 -0
- data/lib/cyberarm_engine.rb +36 -0
- data/lib/cyberarm_engine/background.rb +166 -0
- data/lib/cyberarm_engine/common.rb +85 -0
- data/lib/cyberarm_engine/engine.rb +95 -0
- data/lib/cyberarm_engine/game_object.rb +256 -0
- data/lib/cyberarm_engine/game_state.rb +90 -0
- data/lib/cyberarm_engine/lib/bounding_box.rb +124 -0
- data/lib/cyberarm_engine/lib/vector.rb +97 -0
- data/lib/cyberarm_engine/objects/multi_line_text.rb +67 -0
- data/lib/cyberarm_engine/objects/text.rb +96 -0
- data/lib/cyberarm_engine/objects/timer.rb +23 -0
- data/lib/cyberarm_engine/ui/border_canvas.rb +101 -0
- data/lib/cyberarm_engine/ui/button.rb +53 -0
- data/lib/cyberarm_engine/ui/check_box.rb +52 -0
- data/lib/cyberarm_engine/ui/container.rb +154 -0
- data/lib/cyberarm_engine/ui/dsl.rb +82 -0
- data/lib/cyberarm_engine/ui/edit_line.rb +88 -0
- data/lib/cyberarm_engine/ui/element.rb +197 -0
- data/lib/cyberarm_engine/ui/event.rb +46 -0
- data/lib/cyberarm_engine/ui/flow.rb +15 -0
- data/lib/cyberarm_engine/ui/gui_state.rb +119 -0
- data/lib/cyberarm_engine/ui/image.rb +42 -0
- data/lib/cyberarm_engine/ui/label.rb +34 -0
- data/lib/cyberarm_engine/ui/stack.rb +11 -0
- data/lib/cyberarm_engine/ui/style.rb +15 -0
- data/lib/cyberarm_engine/ui/theme.rb +91 -0
- data/lib/cyberarm_engine/ui/toggle_button.rb +49 -0
- data/lib/cyberarm_engine/version.rb +4 -0
- metadata +137 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class Vector
|
3
|
+
|
4
|
+
def initialize(x = 0, y = 0, z = 0, weight = 0)
|
5
|
+
@x, @y, @z, @weight = x, y, z, weight
|
6
|
+
end
|
7
|
+
|
8
|
+
def x; @x; end
|
9
|
+
def x=(n); @x = n; end
|
10
|
+
|
11
|
+
def y; @y; end
|
12
|
+
def y=(n); @y = n; end
|
13
|
+
|
14
|
+
def z; @z; end
|
15
|
+
def z=(n); @z = n; end
|
16
|
+
|
17
|
+
def weight; @weight; end
|
18
|
+
def weight=(n); @weight = n; end
|
19
|
+
|
20
|
+
# def xy=(nx, ny); @x = nx; @y = ny; end
|
21
|
+
# def xyz=(nx, ny, nz); @x = nx; @y = ny; @z = nz; end
|
22
|
+
# def xyzw=(nx, ny, nz, nw); @x = nx; @y = ny; @z = nz; @weight = nw; end
|
23
|
+
|
24
|
+
def ==(other)
|
25
|
+
if other.is_a?(Numeric)
|
26
|
+
@x == other &&
|
27
|
+
@y == other &&
|
28
|
+
@z == other &&
|
29
|
+
@weight == other
|
30
|
+
else
|
31
|
+
@x == other.x &&
|
32
|
+
@y == other.y &&
|
33
|
+
@z == other.z &&
|
34
|
+
@weight == other.weight
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def +(other)
|
39
|
+
Vector.new(
|
40
|
+
@x + other.x,
|
41
|
+
@y + other.y,
|
42
|
+
@z + other.z,
|
43
|
+
@weight + other.weight
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def -(other)
|
48
|
+
Vector.new(
|
49
|
+
@x - other.x,
|
50
|
+
@y - other.y,
|
51
|
+
@z - other.z,
|
52
|
+
@weight - other.weight
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def *(other)
|
57
|
+
Vector.new(
|
58
|
+
@x * other.x,
|
59
|
+
@y * other.y,
|
60
|
+
@z * other.z,
|
61
|
+
@weight * other.weight
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def /(other)
|
66
|
+
# Endeavors to prevent division by zero
|
67
|
+
Vector.new(
|
68
|
+
@x == 0 || other.x == 0 ? 0 : @x / other.x,
|
69
|
+
@y == 0 || other.y == 0 ? 0 : @y / other.y,
|
70
|
+
@z == 0 || other.z == 0 ? 0 : @z / other.z,
|
71
|
+
@weight == 0 || other.weight == 0 ? 0 : @weight / other.weight
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
# returns magnitude of Vector, ignoring #weight
|
76
|
+
def magnitude
|
77
|
+
Math.sqrt((@x * @x) + (@y * @y) + (@z * @z))
|
78
|
+
end
|
79
|
+
|
80
|
+
def normalized
|
81
|
+
mag = magnitude
|
82
|
+
self / Vector.new(mag, mag, mag)
|
83
|
+
end
|
84
|
+
|
85
|
+
def sum
|
86
|
+
@x + @y + @z + @weight
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_a
|
90
|
+
[@x, @y, @z, @weight]
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
"X: #{@x}, Y: #{@y}, Z: #{@z}, Weight: #{@weight}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class MultiLineText
|
3
|
+
attr_accessor :options, :x, :y, :width, :height
|
4
|
+
|
5
|
+
def initialize(text, options={})
|
6
|
+
@texts = []
|
7
|
+
text.split("\n").each_with_index do |line, i|
|
8
|
+
_options = options
|
9
|
+
_options[:y]+=_options[:size]
|
10
|
+
@texts << Text.new(line, _options)
|
11
|
+
end
|
12
|
+
@options = options
|
13
|
+
@x = @texts.first ? @texts.first.x : 0
|
14
|
+
@y = @texts.first ? @texts.first.y : 0
|
15
|
+
@width = 0
|
16
|
+
@height = 0
|
17
|
+
calculate_boundry
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw
|
21
|
+
@texts.each(&:draw)
|
22
|
+
end
|
23
|
+
|
24
|
+
def text
|
25
|
+
string = ""
|
26
|
+
@texts.each {|t| string << t.text}
|
27
|
+
return string
|
28
|
+
end
|
29
|
+
|
30
|
+
def text=(text)
|
31
|
+
|
32
|
+
if text.lines.count < @texts.count
|
33
|
+
range = ((@texts.count - @text.lines.count)-1)..@texts.count-1
|
34
|
+
p range
|
35
|
+
@texts.slice!(range)
|
36
|
+
end
|
37
|
+
|
38
|
+
text.split("\n").each_with_index do |line, i|
|
39
|
+
if @texts[i]
|
40
|
+
@texts[i].text = line
|
41
|
+
else
|
42
|
+
@texts << Text.new(line, @options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
self.y = @y
|
47
|
+
calculate_boundry
|
48
|
+
end
|
49
|
+
|
50
|
+
def x=(int)
|
51
|
+
@x = int
|
52
|
+
@texts.each {|t| t.x = int}
|
53
|
+
end
|
54
|
+
|
55
|
+
def y=(int)
|
56
|
+
@y = int
|
57
|
+
@texts.each_with_index {|t, i| t.y=int+(i*t.size)}
|
58
|
+
end
|
59
|
+
|
60
|
+
def calculate_boundry
|
61
|
+
@width = 0
|
62
|
+
@height= 0
|
63
|
+
@texts.each {|t| @width = t.width if t.width > @width}
|
64
|
+
@texts.each {|t| @height+=t.height}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class Text
|
3
|
+
CACHE = {}
|
4
|
+
|
5
|
+
attr_accessor :text, :x, :y, :z, :size, :factor_x, :factor_y, :color, :shadow, :shadow_size, :options
|
6
|
+
attr_reader :textobject
|
7
|
+
|
8
|
+
def initialize(text, options={})
|
9
|
+
@text = text || ""
|
10
|
+
@options = options
|
11
|
+
@size = options[:size] || 18
|
12
|
+
@font = options[:font] || "sans-serif"#Gosu.default_font_name
|
13
|
+
@x = options[:x] || 0
|
14
|
+
@y = options[:y] || 0
|
15
|
+
@z = options[:z] || 1025
|
16
|
+
@factor_x = options[:factor_x] || 1
|
17
|
+
@factor_y = options[:factor_y] || 1
|
18
|
+
@color = options[:color] || Gosu::Color::WHITE
|
19
|
+
@alignment= options[:alignment] || nil
|
20
|
+
@shadow = true if options[:shadow] == true
|
21
|
+
@shadow = false if options[:shadow] == false
|
22
|
+
@shadow = true if options[:shadow] == nil
|
23
|
+
@shadow_size = options[:shadow_size] ? options[:shadow_size] : 1
|
24
|
+
@shadow_alpha= options[:shadow_alpha] ? options[:shadow_alpha] : 30
|
25
|
+
@textobject = check_cache(@size, @font)
|
26
|
+
|
27
|
+
if @alignment
|
28
|
+
case @alignment
|
29
|
+
when :left
|
30
|
+
@x = 0+BUTTON_PADDING
|
31
|
+
when :center
|
32
|
+
@x = ($window.width/2)-(@textobject.text_width(@text)/2)
|
33
|
+
when :right
|
34
|
+
@x = $window.width-BUTTON_PADDING-@textobject.text_width(@text)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
return self
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_cache(size, font_name)
|
42
|
+
available = false
|
43
|
+
font = nil
|
44
|
+
|
45
|
+
if CACHE[size]
|
46
|
+
if CACHE[size][font_name]
|
47
|
+
font = CACHE[size][font_name]
|
48
|
+
available = true
|
49
|
+
else
|
50
|
+
available = false
|
51
|
+
end
|
52
|
+
else
|
53
|
+
available = false
|
54
|
+
end
|
55
|
+
|
56
|
+
unless available
|
57
|
+
font = Gosu::Font.new(@size, name: @font)
|
58
|
+
CACHE[@size] = {} unless CACHE[@size].is_a?(Hash)
|
59
|
+
CACHE[@size][@font] = font
|
60
|
+
end
|
61
|
+
|
62
|
+
return font
|
63
|
+
end
|
64
|
+
|
65
|
+
def width
|
66
|
+
textobject.text_width(@text)
|
67
|
+
end
|
68
|
+
|
69
|
+
def height
|
70
|
+
textobject.height
|
71
|
+
end
|
72
|
+
|
73
|
+
def draw
|
74
|
+
if @shadow && !ARGV.join.include?("--no-shadow")
|
75
|
+
_color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, @shadow_alpha) if @shadow_alpha <= @color.alpha
|
76
|
+
_color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, @color.alpha) unless @shadow_alpha <= @color.alpha
|
77
|
+
|
78
|
+
@textobject.draw_markup(@text, @x-@shadow_size, @y, @z, @factor_x, @factor_y, _color)
|
79
|
+
@textobject.draw_markup(@text, @x-@shadow_size, @y-@shadow_size, @z, @factor_x, @factor_y, _color)
|
80
|
+
|
81
|
+
@textobject.draw_markup(@text, @x, @y-@shadow_size, @z, @factor_x, @factor_y, _color)
|
82
|
+
@textobject.draw_markup(@text, @x+@shadow_size, @y-@shadow_size, @z, @factor_x, @factor_y, _color)
|
83
|
+
|
84
|
+
@textobject.draw_markup(@text, @x, @y+@shadow_size, @z, @factor_x, @factor_y, _color)
|
85
|
+
@textobject.draw_markup(@text, @x-@shadow_size, @y+@shadow_size, @z, @factor_x, @factor_y, _color)
|
86
|
+
|
87
|
+
@textobject.draw_markup(@text, @x+@shadow_size, @y, @z, @factor_x, @factor_y, _color)
|
88
|
+
@textobject.draw_markup(@text, @x+@shadow_size, @y+@shadow_size, @z, @factor_x, @factor_y, _color)
|
89
|
+
end
|
90
|
+
|
91
|
+
@textobject.draw_markup(@text, @x, @y, @z, @factor_x, @factor_y, @color)
|
92
|
+
end
|
93
|
+
|
94
|
+
def update; end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class Timer
|
3
|
+
def initialize(interval, looping = true, &block)
|
4
|
+
@interval = interval
|
5
|
+
@looping = looping
|
6
|
+
@block = block
|
7
|
+
|
8
|
+
@last_interval = Gosu.milliseconds
|
9
|
+
@triggered = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def update
|
13
|
+
return if !@looping && @triggered
|
14
|
+
|
15
|
+
if Gosu.milliseconds >= @last_interval + @interval
|
16
|
+
@last_interval = Gosu.milliseconds
|
17
|
+
@triggered = true
|
18
|
+
|
19
|
+
@block.call if @block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class BorderCanvas
|
3
|
+
attr_reader :element, :top, :right, :bottom, :left
|
4
|
+
def initialize(element:)
|
5
|
+
@element = element
|
6
|
+
|
7
|
+
@top = Background.new
|
8
|
+
@right = Background.new
|
9
|
+
@bottom = Background.new
|
10
|
+
@left = Background.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def color=(color)
|
14
|
+
if color.is_a?(Numeric)
|
15
|
+
@top.background = color
|
16
|
+
@right.background = color
|
17
|
+
@bottom.background = color
|
18
|
+
@left.background = color
|
19
|
+
|
20
|
+
elsif color.is_a?(Gosu::Color)
|
21
|
+
@top.background = color
|
22
|
+
@right.background = color
|
23
|
+
@bottom.background = color
|
24
|
+
@left.background = color
|
25
|
+
|
26
|
+
elsif color.is_a?(Array)
|
27
|
+
if color.size == 1
|
28
|
+
color=color.first
|
29
|
+
|
30
|
+
elsif color.size == 2
|
31
|
+
@top.background = color.first
|
32
|
+
@right.background = color.first
|
33
|
+
@bottom.background = color.last
|
34
|
+
@left.background = color.last
|
35
|
+
|
36
|
+
elsif color.size == 4
|
37
|
+
@top.background = color[0]
|
38
|
+
@right.background = color[1]
|
39
|
+
@bottom.background = color[2]
|
40
|
+
@left.background = color[3]
|
41
|
+
else
|
42
|
+
raise ArgumentError, "color array was empty or had wrong number of elements (expected 2 or 4 elements)"
|
43
|
+
end
|
44
|
+
|
45
|
+
elsif color.is_a?(Hash)
|
46
|
+
@top.background = color[:top]
|
47
|
+
@right.background = color[:right]
|
48
|
+
@bottom.background = color[:bottom]
|
49
|
+
@left.background = color[:left]
|
50
|
+
else
|
51
|
+
raise ArgumentError, "color '#{color}' of type '#{color.class}' was not able to be processed"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def draw
|
56
|
+
@top.draw
|
57
|
+
@right.draw
|
58
|
+
@bottom.draw
|
59
|
+
@left.draw
|
60
|
+
end
|
61
|
+
|
62
|
+
def update
|
63
|
+
# TOP
|
64
|
+
@top.x = @element.x# + @element.border_thickness_left
|
65
|
+
@top.y = @element.y
|
66
|
+
@top.z = @element.z
|
67
|
+
|
68
|
+
@top.width = @element.width
|
69
|
+
@top.height = @element.border_thickness_top
|
70
|
+
|
71
|
+
# RIGHT
|
72
|
+
@right.x = @element.x + @element.width
|
73
|
+
@right.y = @element.y + @element.border_thickness_top
|
74
|
+
@right.z = @element.z
|
75
|
+
|
76
|
+
@right.width = -@element.border_thickness_right
|
77
|
+
@right.height = @element.height - @element.border_thickness_top
|
78
|
+
|
79
|
+
# BOTTOM
|
80
|
+
@bottom.x = @element.x
|
81
|
+
@bottom.y = @element.y + @element.height
|
82
|
+
@bottom.z = @element.z
|
83
|
+
|
84
|
+
@bottom.width = @element.width - @element.border_thickness_right
|
85
|
+
@bottom.height = -@element.border_thickness_bottom
|
86
|
+
|
87
|
+
# LEFT
|
88
|
+
@left.x = @element.x
|
89
|
+
@left.y = @element.y
|
90
|
+
@left.z = @element.z
|
91
|
+
|
92
|
+
@left.width = @element.border_thickness_left
|
93
|
+
@left.height = @element.height - @element.border_thickness_bottom
|
94
|
+
|
95
|
+
@top.update
|
96
|
+
@right.update
|
97
|
+
@bottom.update
|
98
|
+
@left.update
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class Button < Label
|
3
|
+
def initialize(text, options = {}, block = nil)
|
4
|
+
super(text, options, block)
|
5
|
+
|
6
|
+
@background_canvas.background = default(:background)
|
7
|
+
end
|
8
|
+
|
9
|
+
def render
|
10
|
+
draw_text
|
11
|
+
end
|
12
|
+
|
13
|
+
def draw_text
|
14
|
+
@text.draw
|
15
|
+
end
|
16
|
+
|
17
|
+
def enter(sender)
|
18
|
+
@focus = false unless window.button_down?(Gosu::MsLeft)
|
19
|
+
|
20
|
+
if @focus
|
21
|
+
@background_canvas.background = default(:active, :background)
|
22
|
+
@text.color = default(:active, :color)
|
23
|
+
else
|
24
|
+
@background_canvas.background = default(:hover, :background)
|
25
|
+
@text.color = default(:hover, :color)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def left_mouse_button(sender, x, y)
|
30
|
+
@focus = true
|
31
|
+
@background_canvas.background = default(:active, :background)
|
32
|
+
window.current_state.focus = self
|
33
|
+
@text.color = default(:active, :color)
|
34
|
+
end
|
35
|
+
|
36
|
+
def released_left_mouse_button(sender,x, y)
|
37
|
+
enter(sender)
|
38
|
+
end
|
39
|
+
|
40
|
+
def clicked_left_mouse_button(sender, x, y)
|
41
|
+
@block.call(self) if @block
|
42
|
+
end
|
43
|
+
|
44
|
+
def leave(sender)
|
45
|
+
@background_canvas.background = default(:background)
|
46
|
+
@text.color = default(:color)
|
47
|
+
end
|
48
|
+
|
49
|
+
def blur(sender)
|
50
|
+
@focus = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CyberarmEngine
|
2
|
+
class CheckBox < Flow
|
3
|
+
def initialize(text, options, block = nil)
|
4
|
+
super({}, block = nil)
|
5
|
+
options[:toggled] = options[:checked]
|
6
|
+
|
7
|
+
@toggle_button = ToggleButton.new(options)
|
8
|
+
@label = Label.new(text, options)
|
9
|
+
|
10
|
+
define_label_singletons
|
11
|
+
|
12
|
+
add(@toggle_button)
|
13
|
+
add(@label)
|
14
|
+
|
15
|
+
@width = @toggle_button.width + @label.width
|
16
|
+
@height = @toggle_button.height + @label.height
|
17
|
+
end
|
18
|
+
|
19
|
+
def text=(text)
|
20
|
+
@label.text = text
|
21
|
+
recalculate
|
22
|
+
end
|
23
|
+
|
24
|
+
def define_label_singletons
|
25
|
+
@label.define_singleton_method(:_toggle_button) do |button|
|
26
|
+
@_toggle_button = button
|
27
|
+
end
|
28
|
+
|
29
|
+
@label._toggle_button(@toggle_button)
|
30
|
+
|
31
|
+
@label.define_singleton_method(:holding_left_mouse_button) do |sender, x, y|
|
32
|
+
@_toggle_button.left_mouse_button(sender, x, y)
|
33
|
+
end
|
34
|
+
|
35
|
+
@label.define_singleton_method(:released_left_mouse_button) do |sender, x, y|
|
36
|
+
@_toggle_button.released_left_mouse_button(sender, x, y)
|
37
|
+
end
|
38
|
+
|
39
|
+
@label.define_singleton_method(:clicked_left_mouse_button) do |sender, x, y|
|
40
|
+
@_toggle_button.clicked_left_mouse_button(sender, x, y)
|
41
|
+
end
|
42
|
+
|
43
|
+
@label.define_singleton_method(:enter) do |sender|
|
44
|
+
@_toggle_button.enter(sender)
|
45
|
+
end
|
46
|
+
|
47
|
+
@label.define_singleton_method(:leave) do |sender|
|
48
|
+
@_toggle_button.leave(sender)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|