mirror of
https://github.com/cyberarm/cyberarm_engine.git
synced 2025-12-16 21:22:33 +00:00
Compare commits
10 Commits
a4d02038c3
...
v0.21.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 97296b080c | |||
| ca73a2d8e8 | |||
| 0a62e5180a | |||
| 31e909eb30 | |||
| 300e7c4e59 | |||
| be98fe47ad | |||
| a75afaf47a | |||
| d81df5f4e2 | |||
| f2ea0d9942 | |||
| 08d068f156 |
@@ -24,6 +24,7 @@ require_relative "cyberarm_engine/transform"
|
||||
require_relative "cyberarm_engine/ray"
|
||||
require_relative "cyberarm_engine/background"
|
||||
require_relative "cyberarm_engine/background_nine_slice"
|
||||
require_relative "cyberarm_engine/background_image"
|
||||
require_relative "cyberarm_engine/animator"
|
||||
|
||||
require_relative "cyberarm_engine/text"
|
||||
|
||||
93
lib/cyberarm_engine/background_image.rb
Normal file
93
lib/cyberarm_engine/background_image.rb
Normal file
@@ -0,0 +1,93 @@
|
||||
module CyberarmEngine
|
||||
class BackgroundImage
|
||||
include CyberarmEngine::Common
|
||||
attr_accessor :x, :y, :z, :mode
|
||||
attr_reader :image, :width, :height, :color
|
||||
|
||||
def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :fill, color: Gosu::Color::WHITE)
|
||||
@image_path = image_path
|
||||
@image = get_image(image_path) if image_path
|
||||
|
||||
@x = x
|
||||
@y = y
|
||||
@z = z
|
||||
@width = width
|
||||
@height = height
|
||||
|
||||
@mode = mode
|
||||
|
||||
@color = color
|
||||
|
||||
@cached_tiling = nil
|
||||
end
|
||||
|
||||
def image=(image_path)
|
||||
@cached_tiling = nil if image_path != @image_path
|
||||
@image_path = image_path
|
||||
@image = image_path ? get_image(image_path) : image_path
|
||||
end
|
||||
|
||||
def width=(n)
|
||||
@cached_tiling = nil if @width != n
|
||||
@width = n
|
||||
end
|
||||
|
||||
def height=(n)
|
||||
@cached_tiling = nil if @height != n
|
||||
@height = n
|
||||
end
|
||||
|
||||
def color=(c)
|
||||
@cached_tiling = nil if @color != c
|
||||
@color = c
|
||||
end
|
||||
|
||||
def width_scale
|
||||
(@width.to_f / @image.width).abs
|
||||
end
|
||||
|
||||
def height_scale
|
||||
(@height.to_f / @image.height).abs
|
||||
end
|
||||
|
||||
def draw
|
||||
return unless @image
|
||||
|
||||
Gosu.clip_to(@x, @y, @width, @height) do
|
||||
send(:"draw_#{mode}")
|
||||
end
|
||||
end
|
||||
|
||||
def draw_stretch
|
||||
@image.draw(@x, @y, @z, width_scale, height_scale, @color)
|
||||
end
|
||||
|
||||
def draw_tiled
|
||||
@cached_tiling ||= Gosu.record(@width, @height) do
|
||||
height_scale.ceil.times do |y|
|
||||
width_scale.ceil.times do |x|
|
||||
@image.draw(x * @image.width, y * @image.height, @z, 1, 1, @color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@cached_tiling.draw(@x, @y, @z)
|
||||
end
|
||||
|
||||
def draw_fill
|
||||
if @width * width_scale > height * height_scale
|
||||
draw_fill_width
|
||||
else
|
||||
draw_fill_height
|
||||
end
|
||||
end
|
||||
|
||||
def draw_fill_width
|
||||
@image.draw(@x, @y, @z, width_scale, width_scale, @color)
|
||||
end
|
||||
|
||||
def draw_fill_height
|
||||
@image.draw(@x, @y, @z, height_scale, height_scale, @color)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -95,7 +95,7 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def window
|
||||
$window
|
||||
CyberarmEngine::Window.instance
|
||||
end
|
||||
|
||||
def control_down?
|
||||
|
||||
@@ -7,7 +7,7 @@ module CyberarmEngine
|
||||
attr_reader :alpha
|
||||
|
||||
def initialize(options = {})
|
||||
$window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
|
||||
window.current_state.add_game_object(self) if options[:auto_manage] || options[:auto_manage].nil?
|
||||
|
||||
@options = options
|
||||
@image = options[:image] ? image(options[:image]) : nil
|
||||
@@ -55,9 +55,9 @@ module CyberarmEngine
|
||||
|
||||
if $debug
|
||||
show_debug_heading
|
||||
$window.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
|
||||
Gosu.draw_circle(@position.x, @position.y, radius, 9999, @debug_color)
|
||||
if @debug_text.text != ""
|
||||
$window.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
|
||||
Gosu.draw_rect(@debug_text.x - 10, (@debug_text.y - 10), @debug_text.width + 20, @debug_text.height + 20,
|
||||
Gosu::Color.rgba(0, 0, 0, 200), 9999)
|
||||
@debug_text.draw
|
||||
end
|
||||
@@ -102,13 +102,13 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def _x_visible
|
||||
x.between?(($window.width / 2) - @world_center_point.x, ($window.width / 2) + @world_center_point.x) ||
|
||||
x.between?((@world_center_point.x - $window.width / 2), ($window.width / 2) + @world_center_point.x)
|
||||
x.between?((window.width / 2) - @world_center_point.x, (window.width / 2) + @world_center_point.x) ||
|
||||
x.between?((@world_center_point.x - window.width / 2), (window.width / 2) + @world_center_point.x)
|
||||
end
|
||||
|
||||
def _y_visible
|
||||
y.between?(($window.height / 2) - @world_center_point.y, ($window.height / 2) + @world_center_point.y) ||
|
||||
y.between?(@world_center_point.y - ($window.height / 2), ($window.height / 2) + @world_center_point.y)
|
||||
y.between?((window.height / 2) - @world_center_point.y, (window.height / 2) + @world_center_point.y) ||
|
||||
y.between?(@world_center_point.y - (window.height / 2), (window.height / 2) + @world_center_point.y)
|
||||
end
|
||||
|
||||
def heading(ahead_by = 100, _object = nil, angle_only = false)
|
||||
@@ -153,10 +153,6 @@ module CyberarmEngine
|
||||
@color = Gosu::Color.rgba(@color.red, @color.green, @color.blue, int)
|
||||
end
|
||||
|
||||
def draw_rect(x, y, width, height, color, z = 0)
|
||||
$window.draw_rect(x, y, width, height, color, z)
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
end
|
||||
|
||||
@@ -190,12 +186,12 @@ module CyberarmEngine
|
||||
# Duplication... so DRY.
|
||||
def each_circle_collision(object, _resolve_with = :width, &block)
|
||||
if object.class != Class && object.instance_of?(object.class)
|
||||
$window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
|
||||
window.current_state.game_objects.select { |i| i.instance_of?(object.class) }.each do |o|
|
||||
distance = Gosu.distance(x, y, object.x, object.y)
|
||||
block.call(o, object) if distance <= radius + object.radius && block
|
||||
end
|
||||
else
|
||||
list = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||
list = window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||
list.each do |o|
|
||||
next if self == o
|
||||
|
||||
@@ -206,9 +202,9 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def destroy
|
||||
if $window.current_state
|
||||
$window.current_state.game_objects.each do |o|
|
||||
$window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
|
||||
if window.current_state
|
||||
window.current_state.game_objects.each do |o|
|
||||
window.current_state.game_objects.delete(o) if o.is_a?(self.class) && o == self
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -220,13 +216,13 @@ module CyberarmEngine
|
||||
|
||||
def self.each_circle_collision(object, _resolve_with = :width, &block)
|
||||
if object.class != Class && object.instance_of?(object.class)
|
||||
$window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
|
||||
window.current_state.game_objects.select { |i| i.instance_of?(self) }.each do |o|
|
||||
distance = Gosu.distance(o.x, o.y, object.x, object.y)
|
||||
block.call(o, object) if distance <= o.radius + object.radius && block
|
||||
end
|
||||
else
|
||||
lista = $window.current_state.game_objects.select { |i| i.instance_of?(self) }
|
||||
listb = $window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||
lista = window.current_state.game_objects.select { |i| i.instance_of?(self) }
|
||||
listb = window.current_state.game_objects.select { |i| i.instance_of?(object) }
|
||||
lista.product(listb).each do |o, o2|
|
||||
next if o == o2
|
||||
|
||||
@@ -238,9 +234,9 @@ module CyberarmEngine
|
||||
|
||||
def self.destroy_all
|
||||
INSTANCES.clear
|
||||
if $window.current_state
|
||||
$window.current_state.game_objects.each do |o|
|
||||
$window.current_state.game_objects.delete(o) if o.is_a?(self.class)
|
||||
if window.current_state
|
||||
window.current_state.game_objects.each do |o|
|
||||
window.current_state.game_objects.delete(o) if o.is_a?(self.class)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ module CyberarmEngine
|
||||
@options = options
|
||||
@game_objects = []
|
||||
@global_pause = false
|
||||
$window.text_input = nil unless options[:preserve_text_input]
|
||||
window.text_input = nil unless options[:preserve_text_input]
|
||||
|
||||
@down_keys = {}
|
||||
end
|
||||
@@ -30,48 +30,23 @@ module CyberarmEngine
|
||||
@game_objects.each(&:update)
|
||||
end
|
||||
|
||||
def draw_bounding_box(box)
|
||||
x = box.x
|
||||
y = box.y
|
||||
max_x = box.max_x
|
||||
max_y = box.max_y
|
||||
|
||||
color = Gosu::Color.rgba(255, 127, 64, 240)
|
||||
|
||||
# pipe = 4
|
||||
# Gosu.draw_rect(x-width, y-height, x+(width*2), y+(height*2), color, Float::INFINITY)
|
||||
# puts "BB render: #{x}:#{y} w:#{x.abs+width} h:#{y.abs+height}"
|
||||
# Gosu.draw_rect(x, y, x.abs+width, y.abs+height, color, Float::INFINITY)
|
||||
|
||||
# TOP LEFT to BOTTOM LEFT
|
||||
$window.draw_line(
|
||||
x, y, color,
|
||||
x, max_y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# BOTTOM LEFT to BOTTOM RIGHT
|
||||
$window.draw_line(
|
||||
x, max_y, color,
|
||||
max_x, max_y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# BOTTOM RIGHT to TOP RIGHT
|
||||
$window.draw_line(
|
||||
max_x, max_y, color,
|
||||
max_x, y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# TOP RIGHT to TOP LEFT
|
||||
$window.draw_line(
|
||||
max_x, y, color,
|
||||
x, y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
def needs_redraw?
|
||||
true
|
||||
end
|
||||
|
||||
def destroy
|
||||
@options.clear
|
||||
@game_objects.clear
|
||||
def drop(filename)
|
||||
end
|
||||
|
||||
def gamepad_connected(index)
|
||||
end
|
||||
|
||||
def gamepad_disconnected(index)
|
||||
end
|
||||
|
||||
def gain_focus
|
||||
end
|
||||
|
||||
def lose_focus
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
@@ -90,6 +65,54 @@ module CyberarmEngine
|
||||
end
|
||||
end
|
||||
|
||||
def close
|
||||
window.close!
|
||||
end
|
||||
|
||||
def draw_bounding_box(box)
|
||||
x = box.x
|
||||
y = box.y
|
||||
max_x = box.max_x
|
||||
max_y = box.max_y
|
||||
|
||||
color = Gosu::Color.rgba(255, 127, 64, 240)
|
||||
|
||||
# pipe = 4
|
||||
# Gosu.draw_rect(x-width, y-height, x+(width*2), y+(height*2), color, Float::INFINITY)
|
||||
# puts "BB render: #{x}:#{y} w:#{x.abs+width} h:#{y.abs+height}"
|
||||
# Gosu.draw_rect(x, y, x.abs+width, y.abs+height, color, Float::INFINITY)
|
||||
|
||||
# TOP LEFT to BOTTOM LEFT
|
||||
Gosu.draw_line(
|
||||
x, y, color,
|
||||
x, max_y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# BOTTOM LEFT to BOTTOM RIGHT
|
||||
Gosu.draw_line(
|
||||
x, max_y, color,
|
||||
max_x, max_y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# BOTTOM RIGHT to TOP RIGHT
|
||||
Gosu.draw_line(
|
||||
max_x, max_y, color,
|
||||
max_x, y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
# TOP RIGHT to TOP LEFT
|
||||
Gosu.draw_line(
|
||||
max_x, y, color,
|
||||
x, y, color,
|
||||
Float::INFINITY
|
||||
)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@options.clear
|
||||
@game_objects.clear
|
||||
end
|
||||
|
||||
def add_game_object(object)
|
||||
@game_objects << object
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ module CyberarmEngine
|
||||
|
||||
def initialize
|
||||
@bounding_box_renderer = BoundingBoxRenderer.new
|
||||
@opengl_renderer = OpenGLRenderer.new(width: $window.width, height: $window.height)
|
||||
@opengl_renderer = OpenGLRenderer.new(width: CyberarmEngine::Window.instance.width, height: CyberarmEngine::Window.instance.height)
|
||||
end
|
||||
|
||||
def draw(camera, lights, entities)
|
||||
|
||||
@@ -43,9 +43,9 @@ module CyberarmEngine
|
||||
when :left
|
||||
@x = 0 + BUTTON_PADDING
|
||||
when :center
|
||||
@x = ($window.width / 2) - (@textobject.text_width(@text) / 2)
|
||||
@x = (CyberarmEngine::Window.instance.width / 2) - (@textobject.text_width(@text) / 2)
|
||||
when :right
|
||||
@x = $window.width - BUTTON_PADDING - @textobject.text_width(@text)
|
||||
@x = CyberarmEngine::Window.instance.width - BUTTON_PADDING - @textobject.text_width(@text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,7 +116,7 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
private def element_parent
|
||||
$__current_container__
|
||||
CyberarmEngine::Element::Container.current_container
|
||||
end
|
||||
|
||||
private def container(klass, options = {}, &block)
|
||||
@@ -126,12 +126,12 @@ module CyberarmEngine
|
||||
_container = klass.new(options, block)
|
||||
|
||||
old_parent = element_parent
|
||||
$__current_container__ = _container
|
||||
CyberarmEngine::Element::Container.current_container = _container
|
||||
|
||||
_container.build
|
||||
_container.parent.add(_container)
|
||||
|
||||
$__current_container__ = old_parent
|
||||
CyberarmEngine::Element::Container.current_container = old_parent
|
||||
|
||||
_container
|
||||
end
|
||||
|
||||
@@ -38,6 +38,7 @@ module CyberarmEngine
|
||||
|
||||
@style.background_canvas = Background.new
|
||||
@style.background_nine_slice_canvas = BackgroundNineSlice.new
|
||||
@style.background_image_canvas = BackgroundImage.new
|
||||
@style.border_canvas = BorderCanvas.new(element: self)
|
||||
|
||||
@style_event = :default
|
||||
@@ -60,6 +61,7 @@ module CyberarmEngine
|
||||
|
||||
set_background
|
||||
set_background_nine_slice
|
||||
set_background_image
|
||||
|
||||
set_border_thickness
|
||||
set_border_color
|
||||
@@ -104,6 +106,14 @@ module CyberarmEngine
|
||||
@style.background_nine_slice_bottom = safe_style_fetch(:background_nine_slice_bottom) || @style.background_nine_slice_from_edge
|
||||
end
|
||||
|
||||
def set_background_image
|
||||
@style.background_image = safe_style_fetch(:background_image)
|
||||
@style.background_image_mode = safe_style_fetch(:background_image_mode) || :stretch
|
||||
@style.background_image_color = safe_style_fetch(:background_image_color) || Gosu::Color::WHITE
|
||||
@style.background_image_canvas.mode = @style.background_image_mode
|
||||
@style.background_image_canvas.color = @style.background_image_color
|
||||
end
|
||||
|
||||
def set_border_thickness
|
||||
@style.border_thickness = safe_style_fetch(:border_thickness)
|
||||
|
||||
@@ -288,6 +298,7 @@ module CyberarmEngine
|
||||
|
||||
@style.background_canvas.draw
|
||||
@style.background_nine_slice_canvas.draw
|
||||
@style.background_image_canvas.draw
|
||||
@style.border_canvas.draw
|
||||
|
||||
render
|
||||
@@ -429,11 +440,34 @@ module CyberarmEngine
|
||||
def dimensional_size(size, dimension)
|
||||
raise "dimension must be either :width or :height" unless %i[width height].include?(dimension)
|
||||
|
||||
if size.is_a?(Numeric) && size.between?(0.0, 1.0)
|
||||
(@parent.send(:"content_#{dimension}") * size).round - send(:"noncontent_#{dimension}").round
|
||||
new_size = if size.is_a?(Numeric) && size.between?(0.0, 1.0)
|
||||
(@parent.send(:"content_#{dimension}") * size).floor - send(:"noncontent_#{dimension}").floor
|
||||
else
|
||||
size
|
||||
end
|
||||
|
||||
if @parent && @style.fill # Handle fill behavior
|
||||
fill_siblings = @parent.children.select { |c| c.style.fill }.count.to_f # include self since we're dividing
|
||||
|
||||
if dimension == :width && @parent.is_a?(Flow)
|
||||
space_available_width = ((@parent.content_width - (@parent.children.reject { |c| c.style.fill }).map(&:outer_width).sum) / fill_siblings)
|
||||
space_available_width = space_available_width.nan? ? 0 : space_available_width.floor # The parent element might not have its dimensions, yet.
|
||||
|
||||
return space_available_width - noncontent_width
|
||||
|
||||
elsif dimension == :height && @parent.is_a?(Stack)
|
||||
space_available_height = ((@parent.content_height - (@parent.children.reject { |c| c.style.fill }).map(&:outer_height).sum) / fill_siblings)
|
||||
space_available_height = space_available_height.nan? ? 0 : space_available_height.floor # The parent element might not have its dimensions, yet.
|
||||
|
||||
return space_available_height - noncontent_height
|
||||
end
|
||||
|
||||
else # Handle min_width/height and max_width/height
|
||||
return @style.send(:"min_#{dimension}") if @style.send(:"min_#{dimension}") && new_size < @style.send(:"min_#{dimension}")
|
||||
return @style.send(:"max_#{dimension}") if @style.send(:"max_#{dimension}") && new_size > @style.send(:"max_#{dimension}")
|
||||
end
|
||||
|
||||
new_size
|
||||
end
|
||||
|
||||
def background=(_background)
|
||||
@@ -450,6 +484,7 @@ module CyberarmEngine
|
||||
|
||||
@style.background_canvas.update
|
||||
update_background_nine_slice
|
||||
update_background_image
|
||||
@style.border_canvas.update
|
||||
end
|
||||
|
||||
@@ -477,6 +512,24 @@ module CyberarmEngine
|
||||
@style.background_nine_slice_canvas.image = @style.background_nine_slice
|
||||
end
|
||||
|
||||
def background_image=(image_path)
|
||||
@style.background_image = image_path.is_a?(Gosu::Image) ? image_path : get_image(image_path)
|
||||
update_background_image
|
||||
end
|
||||
|
||||
def update_background_image
|
||||
@style.background_image_canvas.x = @x
|
||||
@style.background_image_canvas.y = @y
|
||||
@style.background_image_canvas.z = @z
|
||||
@style.background_image_canvas.width = width
|
||||
@style.background_image_canvas.height = height
|
||||
|
||||
@style.background_image_canvas.mode = @style.background_image_mode
|
||||
@style.background_image_canvas.color = @style.background_image_color
|
||||
|
||||
@style.background_image_canvas.image = @style.background_image
|
||||
end
|
||||
|
||||
def root
|
||||
return self if is_root?
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ module CyberarmEngine
|
||||
@scale_y = 1
|
||||
end
|
||||
|
||||
@width = _width || @image.width.round * @scale_x
|
||||
@height = _height || @image.height.round * @scale_y
|
||||
@width = _width || @image.width.floor * @scale_x
|
||||
@height = _height || @image.height.floor * @scale_y
|
||||
|
||||
update_background
|
||||
else
|
||||
|
||||
@@ -6,6 +6,16 @@ module CyberarmEngine
|
||||
attr_accessor :stroke_color, :fill_color
|
||||
attr_reader :children, :gui_state, :scroll_position
|
||||
|
||||
def self.current_container
|
||||
@@current_container
|
||||
end
|
||||
|
||||
def self.current_container=(container)
|
||||
raise ArgumentError, "Expected container to an an instance of CyberarmEngine::Element::Container, got #{container.class}" unless container.is_a?(CyberarmEngine::Element::Container)
|
||||
|
||||
@@current_container = container
|
||||
end
|
||||
|
||||
def initialize(options = {}, block = nil)
|
||||
@gui_state = options.delete(:gui_state)
|
||||
super
|
||||
@@ -35,23 +45,23 @@ module CyberarmEngine
|
||||
def clear(&block)
|
||||
@children.clear
|
||||
|
||||
old_container = $__current_container__
|
||||
old_container = CyberarmEngine::Element::Container.current_container
|
||||
|
||||
$__current_container__ = self
|
||||
CyberarmEngine::Element::Container.current_container = self
|
||||
block.call(self) if block
|
||||
|
||||
$__current_container__ = old_container
|
||||
CyberarmEngine::Element::Container.current_container = old_container
|
||||
|
||||
root.gui_state.request_recalculate
|
||||
end
|
||||
|
||||
def append(&block)
|
||||
old_container = $__current_container__
|
||||
old_container = CyberarmEngine::Element::Container.current_container
|
||||
|
||||
$__current_container__ = self
|
||||
CyberarmEngine::Element::Container.current_container = self
|
||||
block.call(self) if block
|
||||
|
||||
$__current_container__ = old_container
|
||||
CyberarmEngine::Element::Container.current_container = old_container
|
||||
|
||||
root.gui_state.request_recalculate
|
||||
end
|
||||
@@ -122,29 +132,8 @@ module CyberarmEngine
|
||||
_width = dimensional_size(@style.width, :width)
|
||||
_height = dimensional_size(@style.height, :height)
|
||||
|
||||
@width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).round
|
||||
@height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).round
|
||||
|
||||
# min width/height
|
||||
@width = @style.min_width if @style.min_width && @width < @style.min_width
|
||||
@height = @style.min_height if @style.min_height && @height < @style.min_height
|
||||
|
||||
# max width/height
|
||||
@width = @style.max_width if @style.max_width && @width > @style.max_width
|
||||
@height = @style.max_height if @style.max_height && @height > @style.max_height
|
||||
|
||||
# FIXME: Detect if other siblings (parents children) also want to fill and share space with them
|
||||
if @parent && @style.fill
|
||||
fill_siblings = @parent.children.select { |c| c.style.fill }.count.to_f # include self since we're dividing
|
||||
|
||||
space_available_width = ((@parent.content_width - (@parent.children.map(&:outer_width).sum - outer_width)) / fill_siblings).floor
|
||||
space_available_height = ((@parent.content_height - (@parent.children.map(&:outer_height).sum - outer_height)) / fill_siblings).floor
|
||||
|
||||
@width = space_available_width - inner_width if @parent.is_a?(Flow)
|
||||
@height = space_available_height - inner_height if @parent.is_a?(Stack)
|
||||
|
||||
# pp ["siblings: #{fill_siblings}", "parent is flow: #{@parent.is_a?(Flow)}", "parent is stack: #{@parent.is_a?(Stack)}", [@parent.content_width, space_available_width, @width, outer_width], [@parent.content_height, space_available_height, @height, outer_height]]
|
||||
end
|
||||
@width = _width || (@children.map { |c| c.x + c.outer_width }.max || 0).floor
|
||||
@height = _height || (@children.map { |c| c.y + c.outer_height }.max || 0).floor
|
||||
end
|
||||
|
||||
# Move child to parent after positioning
|
||||
|
||||
@@ -98,7 +98,7 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def row_at(y)
|
||||
((y - @text.y) / @text.textobject.height).round
|
||||
((y - @text.y) / @text.textobject.height).floor
|
||||
end
|
||||
|
||||
def column_at(x, y)
|
||||
|
||||
@@ -45,8 +45,8 @@ module CyberarmEngine
|
||||
@scale_y = 1
|
||||
end
|
||||
|
||||
@width = _width || @image.width.round * @scale_x
|
||||
@height = _height || @image.height.round * @scale_y
|
||||
@width = _width || @image.width.floor * @scale_x
|
||||
@height = _height || @image.height.floor * @scale_y
|
||||
|
||||
update_background
|
||||
end
|
||||
|
||||
@@ -17,6 +17,8 @@ module CyberarmEngine
|
||||
@menu.define_singleton_method(:recalculate_menu) do
|
||||
@x = @__list_box.x
|
||||
@y = @__list_box.y + @__list_box.height
|
||||
|
||||
@y = @__list_box.y - height if @y + height > window.height
|
||||
end
|
||||
@menu.instance_variable_set(:"@__list_box", self)
|
||||
|
||||
@@ -29,6 +31,13 @@ module CyberarmEngine
|
||||
self.choose = @choose
|
||||
end
|
||||
|
||||
def render
|
||||
super
|
||||
|
||||
w = @text.textobject.text_width("▼")
|
||||
@text.textobject.draw_text("▼", @x + content_width - w, @y + @style.padding_top, @z, 1, 1, @text.color)
|
||||
end
|
||||
|
||||
def choose=(item)
|
||||
valid = @items.detect { |i| i == item }
|
||||
raise "Invalid value '#{item}' for choose, valid options were: #{@items.map { |i| "#{i.inspect}" }.join(", ")}" unless valid
|
||||
|
||||
@@ -18,7 +18,14 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def render
|
||||
@text.draw
|
||||
# Gosu.clip_to is too expensive to always use so check if we actually need it.
|
||||
if @text.width > width || @text.height > height
|
||||
Gosu.clip_to(@x, @y, width, height) do
|
||||
@text.draw
|
||||
end
|
||||
else
|
||||
@text.draw
|
||||
end
|
||||
end
|
||||
|
||||
def recalculate
|
||||
@@ -36,8 +43,8 @@ module CyberarmEngine
|
||||
|
||||
handle_text_wrapping(_width)
|
||||
|
||||
@width = _width || @text.width.round
|
||||
@height = _height || @text.height.round
|
||||
@width = _width || @text.width.floor
|
||||
@height = _height || @text.height.floor
|
||||
|
||||
@text.y = @style.border_thickness_top + @style.padding_top + @y
|
||||
@text.z = @z + 3
|
||||
|
||||
@@ -12,7 +12,7 @@ module CyberarmEngine
|
||||
|
||||
@root_container = Element::Stack.new(gui_state: self)
|
||||
@game_objects << @root_container
|
||||
$__current_container__ = @root_container
|
||||
CyberarmEngine::Element::Container.current_container = @root_container
|
||||
|
||||
@active_width = window.width
|
||||
@active_height = window.height
|
||||
@@ -90,6 +90,8 @@ module CyberarmEngine
|
||||
@menu&.update
|
||||
super
|
||||
|
||||
return unless window.has_focus?
|
||||
|
||||
new_mouse_over = @menu.hit_element?(window.mouse_x, window.mouse_y) if @menu
|
||||
new_mouse_over ||= @root_container.hit_element?(window.mouse_x, window.mouse_y)
|
||||
|
||||
@@ -135,10 +137,6 @@ module CyberarmEngine
|
||||
@active_height = window.height
|
||||
end
|
||||
|
||||
def tool_tip_delay
|
||||
250 # ms
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
super
|
||||
|
||||
@@ -175,6 +173,10 @@ module CyberarmEngine
|
||||
@focus.button_up(id) if @focus.respond_to?(:button_up)
|
||||
end
|
||||
|
||||
def tool_tip_delay
|
||||
@tip.style.delay || 250 # ms
|
||||
end
|
||||
|
||||
def redirect_mouse_button(button)
|
||||
hide_menu unless @menu && (@menu == @mouse_over) || (@mouse_over&.parent == @menu)
|
||||
|
||||
|
||||
@@ -154,6 +154,7 @@ module CyberarmEngine
|
||||
},
|
||||
|
||||
ToolTip: { # < TextBlock
|
||||
delay: 100, # ms
|
||||
color: Gosu::Color::WHITE,
|
||||
padding_top: 4,
|
||||
padding_bottom: 4,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module CyberarmEngine
|
||||
NAME = "InDev".freeze
|
||||
VERSION = "0.20.0".freeze
|
||||
VERSION = "0.21.0".freeze
|
||||
end
|
||||
|
||||
@@ -8,21 +8,33 @@ module CyberarmEngine
|
||||
|
||||
attr_accessor :show_cursor
|
||||
attr_writer :exit_on_opengl_error
|
||||
attr_reader :last_frame_time
|
||||
attr_reader :last_frame_time, :states
|
||||
|
||||
def self.now
|
||||
Gosu.milliseconds
|
||||
end
|
||||
|
||||
def self.dt
|
||||
$window.last_frame_time / 1000.0
|
||||
instance.last_frame_time / 1000.0
|
||||
end
|
||||
|
||||
def self.instance=(window)
|
||||
raise ArgumentError, "Expected window to be a subclass of CyberarmEngine::Window, got: #{window.class}" unless window.is_a?(CyberarmEngine::Window)
|
||||
|
||||
@@instance = window
|
||||
end
|
||||
|
||||
def self.instance
|
||||
@@instance
|
||||
end
|
||||
|
||||
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
|
||||
@show_cursor = false
|
||||
@has_focus = false
|
||||
|
||||
super(width, height, fullscreen: fullscreen, update_interval: update_interval, resizable: resizable, borderless: borderless)
|
||||
$window = self
|
||||
Window.instance = self
|
||||
|
||||
@last_frame_time = Gosu.milliseconds - 1
|
||||
@current_frame_time = Gosu.milliseconds
|
||||
self.caption = "CyberarmEngine #{CyberarmEngine::VERSION} #{Gosu.language}"
|
||||
@@ -34,13 +46,14 @@ module CyberarmEngine
|
||||
end
|
||||
|
||||
def draw
|
||||
current_state.draw if current_state
|
||||
current_state&.draw
|
||||
end
|
||||
|
||||
def update
|
||||
Stats.clear
|
||||
|
||||
current_state.update if current_state
|
||||
current_state&.update
|
||||
|
||||
@last_frame_time = Gosu.milliseconds - @current_frame_time
|
||||
@current_frame_time = Gosu.milliseconds
|
||||
end
|
||||
@@ -49,6 +62,48 @@ module CyberarmEngine
|
||||
@show_cursor
|
||||
end
|
||||
|
||||
def needs_redraw?
|
||||
current_state ? current_state.needs_redraw? : true
|
||||
end
|
||||
|
||||
def drop(filename)
|
||||
current_state&.drop(filename)
|
||||
end
|
||||
|
||||
def gamepad_connected(index)
|
||||
current_state&.gamepad_connected(index)
|
||||
end
|
||||
|
||||
def gamepad_disconnected(index)
|
||||
current_state&.gamepad_disconnected(index)
|
||||
end
|
||||
|
||||
def gain_focus
|
||||
@has_focus = true
|
||||
|
||||
current_state&.gain_focus
|
||||
end
|
||||
|
||||
def lose_focus
|
||||
@has_focus = false
|
||||
|
||||
current_state&.lose_focus
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
super
|
||||
current_state&.button_down(id)
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
super
|
||||
current_state&.button_up(id)
|
||||
end
|
||||
|
||||
def close
|
||||
current_state ? current_state.close : super
|
||||
end
|
||||
|
||||
def dt
|
||||
@last_frame_time / 1000.0
|
||||
end
|
||||
@@ -61,16 +116,6 @@ module CyberarmEngine
|
||||
@exit_on_opengl_error
|
||||
end
|
||||
|
||||
def button_down(id)
|
||||
super
|
||||
current_state.button_down(id) if current_state
|
||||
end
|
||||
|
||||
def button_up(id)
|
||||
super
|
||||
current_state.button_up(id) if current_state
|
||||
end
|
||||
|
||||
def push_state(klass, options = {})
|
||||
options = { setup: true }.merge(options)
|
||||
|
||||
@@ -108,6 +153,10 @@ module CyberarmEngine
|
||||
@states.shift
|
||||
end
|
||||
|
||||
def has_focus?
|
||||
@has_focus
|
||||
end
|
||||
|
||||
# Sourced from https://gist.github.com/ippa/662583
|
||||
def draw_circle(cx, cy, r, z = 9999, color = Gosu::Color::GREEN, step = 10)
|
||||
0.step(360, step) do |a1|
|
||||
|
||||
Reference in New Issue
Block a user