Compare commits

...

18 Commits

Author SHA1 Message Date
a1513be709 Get rvx bundle exec rake release functional... 2026-10-04 23:43:02 -05:00
d0d5bbac3a Bump version 2026-10-04 23:39:37 -05:00
0ae3ecc145 Fix up some errors with BFS and pathfinding grid 2026-10-04 19:30:58 -05:00
afa8a9dbb6 Add asset textures for nine sliced rounded corners and the like 2026-09-28 19:13:56 -05:00
0ec55bef55 Fixed typo in BFS file name, require pathfinding bits. 2026-09-28 19:13:25 -05:00
904ac78d89 More work on pathfinding support 2026-09-28 15:22:42 -05:00
70d270688f Added .idea to gitignore, first pass at adding intregrated pathfindiing support using redblobgames.com tutorials as reference 2026-09-28 09:35:45 -05:00
685c94bd1b Fixed using this instead of self for slider and check box 2026-09-27 18:16:47 -05:00
d6d3c07bbc First pass at adding fixed update support 2026-09-27 18:06:13 -05:00
2cc1382696 Fixed Text border color not getting set correctly due to misnamed color parameter, generate Text border image with true white text since we draw it with the requested color later. 2026-09-20 16:10:10 -05:00
9fca64b643 Added render mode to BackgroundNineSlice 2026-09-19 19:10:39 -05:00
abe99ce949 Ignore sibling elements that aren't visible from fill mode space considerations 2026-09-17 12:25:48 -05:00
66fb136c83 Make elements sizing by like css' border-box box-sizing instead of like content-box for elements with specific width/height that isn't a ratio, tweaks to gui debug display, make F12 key toggle gui debug display for convenience 2026-09-11 13:05:08 -05:00
b23e5c2a42 Fix pending element recalculate requests apparently not getting processed properly... 2026-09-10 18:32:01 -05:00
747822aa61 Fixed flow containers not correctly positioning their children on the x axis when they wrap to the the next line, fix up containers vertical and horizontal alignment 2026-09-10 18:31:19 -05:00
140e7a3619 Make elements publish the :size_changed event when they change their size 2026-09-09 22:30:19 -05:00
349222f387 Flip flop Element#resolution_scaled 2026-09-04 10:31:30 -05:00
9d4bc89174 Fix Widget element unable to find children element tooltips if the widget's parent(s) had been scrolled 2026-09-04 10:31:02 -05:00
36 changed files with 314 additions and 61 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/.idea
/.bundle/
/.yardoc
/_yardoc/

View File

@@ -1,25 +1,37 @@
PATH
remote: .
specs:
cyberarm_engine (0.24.5)
cyberarm_engine (0.30.0)
gosu (~> 1.1)
GEM
remote: https://rubygems.org/
specs:
gosu (1.4.6)
minitest (5.25.5)
rake (13.2.1)
ffi (1.17.4-x86_64-linux-gnu)
ffi (1.17.4-x86_64-linux-musl)
gosu (1.5.0-x86_64-linux)
ffi (~> 1.12)
minitest (5.27.0)
rake (13.4.2)
PLATFORMS
x64-mingw-ucrt
x86_64-linux
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
bundler (~> 2.2)
bundler (~> 4)
cyberarm_engine!
minitest (~> 5.0)
rake (~> 13.0)
CHECKSUMS
bundler (4.1.0.beta1) sha256=8a2dac8ca276ff4eff5efc2c6457b0044080fc1e431534ad7c5cc6187232b800
cyberarm_engine (0.30.0)
ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
gosu (1.5.0-x86_64-linux)
minitest (5.27.0) sha256=2d3b17f8a36fe7801c1adcffdbc38233b938eb0b4966e97a6739055a45fa77d5
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
BUNDLED WITH
2.6.8
4.1.0.beta1

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

View File

@@ -28,9 +28,8 @@ Gem::Specification.new do |spec|
spec.require_paths = %w[lib assets]
spec.add_dependency "gosu", "~> 1.1"
# spec.add_dependency "ffi", :platforms => [:mswin, :mingw] # Required by Clipboard on Windows
spec.add_development_dependency "bundler", "~> 2.2"
spec.add_development_dependency "bundler", "~> 4"
spec.add_development_dependency "minitest", "~> 5.0"
spec.add_development_dependency "rake", "~> 13.0"
end

View File

@@ -42,6 +42,13 @@ require_relative "cyberarm_engine/console/command"
require_relative "cyberarm_engine/console/subcommand"
require_relative "cyberarm_engine/console/commands/help_command"
require_relative "cyberarm_engine/pathfinding/graph"
require_relative "cyberarm_engine/pathfinding/graphs/grid"
require_relative "cyberarm_engine/pathfinding/graph_search"
require_relative "cyberarm_engine/pathfinding/graph_searches/breadth_first_search"
require_relative "cyberarm_engine/pathfinding/graph_searches/dijkstra_search"
require_relative "cyberarm_engine/pathfinding/graph_searches/astar_search"
require_relative "cyberarm_engine/ui/dsl"
require_relative "cyberarm_engine/ui/theme"

View File

@@ -4,10 +4,10 @@ module CyberarmEngine
CACHE = {}
attr_accessor :x, :y, :z, :width, :height, :mode, :color
attr_accessor :x, :y, :z, :width, :height, :mode, :color, :render_mode
attr_reader :image, :left, :top, :right, :bottom
def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE)
def initialize(image_path: nil, x: 0, y: 0, z: 0, width: 0, height: 0, mode: :tiled, left: 1, top: 1, right: 1, bottom: 1, color: Gosu::Color::WHITE, render_mode: :default)
@image = get_image(image_path) if image_path
@x = x
@@ -25,6 +25,7 @@ module CyberarmEngine
@bottom = bottom
@color = color
@render_mode = render_mode
nine_slice if @image
end
@@ -121,58 +122,58 @@ module CyberarmEngine
end
def draw_stretched
@segment_top_left.draw(@x, @y, @z, 1, 1, @color)
@segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color) # SCALE X
@segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
@segment_top_left.draw(@x, @y, @z, 1, 1, @color, @render_mode)
@segment_top.draw(@x + @segment_top_left.width, @y, @z, width_scale, 1, @color, @render_mode) # SCALE X
@segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color, @render_mode)
@segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color) # SCALE Y
@segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
@segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color) # SCALE X
@segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
@segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color) # SCALE Y
@segment_right.draw((@x + @width) - @segment_right.width, @y + @top, @z, 1, height_scale, @color, @render_mode) # SCALE Y
@segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color, @render_mode)
@segment_bottom.draw(@x + @segment_bottom_left.width, (@y + @height) - @segment_bottom.height, @z, width_scale, 1, @color, @render_mode) # SCALE X
@segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color, @render_mode)
@segment_left.draw(@x, @y + @top, @z, 1, height_scale, @color, @render_mode) # SCALE Y
@segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color) # SCALE X and SCALE Y
@segment_middle.draw(@x + @segment_top_left.width, @y + @segment_top.height, @z, width_scale, height_scale, @color, @render_mode) # SCALE X and SCALE Y
end
def draw_tiled
@segment_top_left.draw(@x, @y, @z, 1, 1, @color)
@segment_top_left.draw(@x, @y, @z, 1, 1, @color, @render_mode)
# p [width_scale, height_scale]
Gosu.clip_to(@x + @segment_top_left.width, @y, @segment_top.width * width_scale, @segment_top.height) do
width_scale.ceil.times do |i|
@segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color) # SCALE X
@segment_top.draw(@x + @segment_top_left.width + (@segment_top.width * i), @y, @z, 1, 1, @color, @render_mode) # SCALE X
end
end
@segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color)
@segment_top_right.draw((@x + @width) - @segment_top_right.width, @y, @z, 1, 1, @color, @render_mode)
Gosu.clip_to(@x + @width - @segment_top_right.width, @y + @top, @segment_right.width, @segment_right.height * height_scale) do
height_scale.ceil.times do |i|
@segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color) # SCALE Y
@segment_right.draw((@x + @width) - @segment_right.width, @y + @top + (@segment_right.height * i), @z, 1, 1, @color, @render_mode) # SCALE Y
end
end
@segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color)
@segment_bottom_right.draw((@x + @width) - @segment_bottom_right.width, @y + @height - @segment_bottom_right.height, @z, 1, 1, @color, @render_mode)
Gosu.clip_to(@x + @segment_top_left.width, @y + @height - @segment_bottom.height, @segment_top.width * width_scale, @segment_bottom.height) do
width_scale.ceil.times do |i|
@segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color) # SCALE X
@segment_bottom.draw(@x + @segment_bottom_left.width + (@segment_bottom.width * i), (@y + @height) - @segment_bottom.height, @z, 1, 1, @color, @render_mode) # SCALE X
end
end
@segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color)
@segment_bottom_left.draw(@x, (@y + @height) - @segment_bottom_left.height, @z, 1, 1, @color, @render_mode)
Gosu.clip_to(@x, @y + @top, @segment_left.width, @segment_left.height * height_scale) do
height_scale.ceil.times do |i|
@segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color) # SCALE Y
@segment_left.draw(@x, @y + @top + (@segment_left.height * i), @z, 1, 1, @color, @render_mode) # SCALE Y
end
end
Gosu.clip_to(@x + @segment_top_left.width, @y + @segment_top.height, @width - (@segment_left.width + @segment_right.width), @height - (@segment_top.height + @segment_bottom.height)) do
height_scale.ceil.times do |y|
width_scale.ceil.times do |x|
@segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color) # SCALE X and SCALE Y
@segment_middle.draw(@x + @segment_top_left.width + (@segment_middle.width * x), @y + @segment_top.height + (@segment_middle.height * y), @z, 1, 1, @color, @render_mode) # SCALE X and SCALE Y
end
end
end

View File

@@ -1,4 +1,6 @@
module CyberarmEngine
GUI_DEBUG = false
module Common
ImageBlob = Data.define(:to_blob, :columns, :rows)

View File

@@ -33,6 +33,9 @@ module CyberarmEngine
@timers.delete_if(&:dead?)
end
def fixed_update(dt)
end
def needs_redraw?
true
end

View File

@@ -0,0 +1,64 @@
module CyberarmEngine
module Pathfinding
class Graph
class Node
KEY_FORMAT = "%s:%s:%s".freeze
attr_reader :x, :y, :z, :cost, :key, :edge_nodes
def initialize(x:, y:, z: 0, cost: 0)
@x = x
@y = y
@z = z
@cost = cost
@key = format(KEY_FORMAT, @x, @y, @z).freeze
@edge_nodes = []
end
def add_edge_node(node)
index = @edge_nodes.find_index { |n| n.key == node.key }
return if index
@edge_nodes.push(node)
end
def remove_edge_node(node)
index = @edge_nodes.find_index { |n| n.key == node.key }
return unless index
@edge_nodes.delete(index)
end
def inspect
format "#<%<class>s:%<id>#018x @key=%<key>s @cost=%<cost>s @edge_nodes=%<edge_nodes>s>",
class: self.class,
id: object_id << 1,
key: key.inspect,
cost: cost.inspect,
edge_nodes: edge_nodes.map { |n| n&.key }
end
end
def initialize(nodes: {})
@nodes = nodes
end
def node(key)
@nodes[key]
end
def node_at(x, y, z = 0)
key = format(Node::KEY_FORMAT, x, y, z)
@nodes[key]
end
def neighbors(node)
node.edge_nodes
end
end
end
end

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
module Pathfinding
class GraphSearch
end
end
end

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
module Pathfinding
class AStarSearch < GraphSearch
end
end
end

View File

@@ -0,0 +1,27 @@
module CyberarmEngine
module Pathfinding
class BreadthFirstSearch < GraphSearch
def self.search(graph:, start:, goal: nil)
frontier = []
came_from = {}
frontier.push(start)
came_from[start.key] = start
while(current = frontier.shift)
# early exit if we reach our goal
break if current == goal
graph.neighbors(current).each do |neighbor|
next if came_from[neighbor.key]
frontier.push(neighbor)
came_from[neighbor.key] = current
end
end
came_from
end
end
end
end

View File

@@ -0,0 +1,6 @@
module CyberarmEngine
module Pathfinding
class DijkstraSearch < GraphSearch
end
end
end

View File

@@ -0,0 +1,52 @@
module CyberarmEngine
module Pathfinding
class Grid < Graph
def add_node(x:, y:, z: 0, cost: 0, replace: false)
key = format(Node::KEY_FORMAT, x, y, z)
node = @nodes[key]
raise "Node at: #{key} already exists! (#{node})" if node && !replace
node = Node.new(x: x, y: y, z: z, cost: cost)
@nodes[key] = node
update_node_edge_nodes(node)
node
end
def remove_node(node)
update_node_edge_nodes(node, remove_node: true)
@nodes.delete(node.key)
end
def update_node_edge_nodes(node, remove_node: false)
x = node.x
y = node.y
z = node.z
# add node to neighbors
# 2D
left = @nodes[format(Node::KEY_FORMAT, x - 1, y, z)]
right = @nodes[format(Node::KEY_FORMAT, x + 1, y, z)]
top = @nodes[format(Node::KEY_FORMAT, x, y - 1, z)]
bottom = @nodes[format(Node::KEY_FORMAT, x, y + 1, z)]
# 3D
front = @nodes[format(Node::KEY_FORMAT, x, y, z - 1)]
back = @nodes[format(Node::KEY_FORMAT, x, y, z + 1)]
possible_edge_nodes = [left, right, top, bottom, front, back]
if remove_node
possible_edge_nodes.each { |n| n&.remove_edge_node(node) }
else
possible_edge_nodes.each { |n| n&.add_edge_node(node) }
end
end
def update_edge_nodes
@nodes.each { |k, n| update_node_edge_nodes(n) }
end
end
end
end

View File

@@ -149,7 +149,7 @@ module CyberarmEngine
@border_alpha = n
end
def border_color=(n)
def border_color=(color)
old_color = @border_color
if color
@@ -208,17 +208,17 @@ module CyberarmEngine
img = Gosu::Image.send(:"from_#{method.to_s.split("_").last}", @text, @size, font: @font)
@cached_text_border_image = Gosu.render((_width + (@border_size * 2)).ceil, (height + (@border_size * 2)).ceil) do
img.draw(-_x, 0, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(-_x, -_y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(-_x, 0, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(-_x, -_y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(0, -_y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(_x, -_y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(0, -_y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(_x, -_y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(_x, 0, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(_x, _y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(_x, 0, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(_x, _y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(0, _y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(-_x, _y, @z, @factor_x, @factor_y, @border_color, @mode)
img.draw(0, _y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
img.draw(-_x, _y, @z, @factor_x, @factor_y, Gosu::Color::WHITE, @mode)
end
end
@@ -256,7 +256,7 @@ module CyberarmEngine
@textobject.send(method, @text, _x + @border_size, _y + @border_size, @z, @factor_x, @factor_y, white, @mode)
end
@cached_text_border_image.draw(@x - @border_size, @y - @border_size, @z, @factor_x, @factor_y, border_color)
@cached_text_border_image.draw(@x - @border_size, @y - @border_size, @z, @factor_x, @factor_y, border_color, @mode)
end
if @shadow

View File

@@ -18,7 +18,7 @@ module CyberarmEngine
@visible = !@options.key?(:visible) ? true : @options[:visible]
@tip = @options[:tip] || ""
@debug = @options[:debug] || CyberarmEngine.const_defined?("GUI_DEBUG") && CyberarmEngine::GUI_DEBUG || false
@debug = @options[:debug].nil? ? nil : @options[:debug]
@debug_color = @options[:debug_color].nil? ? Gosu::Color::RED : @options[:debug_color]
@style = Style.new(options)
@@ -56,7 +56,7 @@ module CyberarmEngine
def resolution_scaled(n)
return n unless @style.design_width
((@style.design_width / Gosu.screen_width(window).to_f) * n).floor
((Gosu.screen_width(window).to_f / @style.design_width) * n).floor
end
def stylize
@@ -215,6 +215,7 @@ module CyberarmEngine
event(:blur)
event(:changed)
event(:size_changed)
end
def enter(_sender)
@@ -339,7 +340,7 @@ module CyberarmEngine
end
def debug_draw
return unless @debug # allow elements to opt out of debug drawing, makes debugging some things easier.
return if @debug == false || !CyberarmEngine::GUI_DEBUG # allow elements to opt out of debug drawing, makes debugging some things easier.
return if CyberarmEngine.const_defined?("GUI_DEBUG_ONLY_ELEMENT") && self.class == GUI_DEBUG_ONLY_ELEMENT
Gosu.draw_line(
@@ -393,7 +394,7 @@ module CyberarmEngine
def width
if visible?
inner_width + @width
inner_width + content_width
else
0
end
@@ -417,7 +418,7 @@ module CyberarmEngine
def height
if visible?
inner_height + @height
inner_height + content_height
else
0
end
@@ -487,6 +488,8 @@ module CyberarmEngine
new_size = if size.is_a?(Float) && size.between?(0.0, 1.0)
(@parent.send(:"content_#{dimension}") * size).floor - send(:"noncontent_#{dimension}").floor
elsif size.is_a?(Numeric)
(size - send(:"noncontent_#{dimension}")).floor
else
size
end
@@ -515,7 +518,7 @@ module CyberarmEngine
def space_available_height
# TODO: This may get expensive if there are a lot of children, probably should cache it somehow
fill_siblings = @parent.children.select { |c| c.styled(:fill) }.count.to_f # include self since we're dividing
fill_siblings = @parent.children.select { |c| c.styled(:fill) && c.visible? }.count.to_f # include self since we're dividing
available_space = ((@parent.content_height - (@parent.children.reject { |c| c.styled(:fill) }).map(&:outer_height).sum) / fill_siblings)
(available_space.nan? || available_space.infinite?) ? 0 : available_space.floor # The parent element might not have its dimensions, yet.
@@ -576,6 +579,8 @@ module CyberarmEngine
@old_width = width
@old_height = height
publish(:size_changed)
end
end

View File

@@ -46,7 +46,7 @@ module CyberarmEngine
end
def value=(bool)
old_value = this.value
old_value = self.value
@toggle_button.value = bool
publish(:changed, bool) if bool != old_value

View File

@@ -88,17 +88,20 @@ module CyberarmEngine
Gosu.translate(@scroll_position.x, @scroll_position.y) do
@children.each(&:draw)
@children.each do |child|
next unless child.visible?
child.debug_draw
end
end
end
@children.each(&:debug_draw)
debug_draw
end
def debug_draw
super
@children.each(&:debug_draw)
end
def update
@@ -203,9 +206,9 @@ module CyberarmEngine
case styled(:v_align)
when :center
@y = parent.y + parent.styled(:margin_top) + parent.height / 2 - height / 2
@y = parent.y + parent.outer_height / 2 - outer_height / 2
when :bottom
@y = parent.y + parent.styled(:margin_top) + parent.height - height
@y = parent.y + parent.outer_height - outer_height
end
end
@@ -214,9 +217,9 @@ module CyberarmEngine
case styled(:h_align)
when :center
@x = parent.x + parent.styled(:margin_left) + parent.width / 2 - width / 2
@x = parent.x + parent.outer_width / 2 - outer_width / 2
when :right
@x = parent.x + parent.styled(:margin_left) + parent.width - width
@x = parent.x + parent.outer_width - outer_width
end
end
@@ -285,7 +288,7 @@ module CyberarmEngine
end
def position_on_next_line(element) # Flow
@current_position.x = 0
@current_position.x = styled(:margin_left) + styled(:padding_left)
@current_position.y += tallest_neighbor(element, @current_position.y).outer_height
element.x = @current_position.x

View File

@@ -94,7 +94,7 @@ module CyberarmEngine
end
def value=(n)
old_value = this.value
old_value = self.value
@value = n
position_handle

View File

@@ -24,7 +24,16 @@ module CyberarmEngine
# Enable child elements to display their tooltips
# but fall back to the Widget if no hit element has a tip
def tip
elements = hit_element?(window.mouse_x, window.mouse_y)
parent_scroll_position = CyberarmEngine::Vector.new
element = self
while (parent_element = element.parent)
parent_scroll_position += parent_element.scroll_position
element = parent_element
end
elements = hit_element?(window.mouse_x - parent_scroll_position.x, window.mouse_y - parent_scroll_position.y)
return @tip unless elements

View File

@@ -98,7 +98,15 @@ module CyberarmEngine
Stats.frame.start_timing(:gui_element_recalculate_requests)
# puts "PENDING REQUESTS: #{@pending_element_recalculate_requests.size}" if @pending_element_recalculate_requests.size.positive?
@pending_element_recalculate_requests.shift(&:recalculate)
while (e = @pending_element_recalculate_requests.shift)
# its pointless to recalculate individual elements when we've been asked to recalculate the whole gui
if @pending_recalculate_request
@pending_element_recalculate_requests.clear
break
end
e.recalculate
end
Stats.frame.end_timing(:gui_element_recalculate_requests)
@@ -231,6 +239,9 @@ module CyberarmEngine
redirect_mouse_button(:right)
when Gosu::KB_F5
request_recalculate
when Gosu::KB_F12
CyberarmEngine.const_set(:GUI_DEBUG, !CyberarmEngine::GUI_DEBUG)
request_repaint
end
@focus.button_down(id) if @focus.respond_to?(:button_down)

View File

@@ -1,4 +1,4 @@
module CyberarmEngine
NAME = "InDev".freeze
VERSION = "0.25.1".freeze
VERSION = "0.30.0".freeze
end

View File

@@ -6,6 +6,9 @@ module CyberarmEngine
SAMPLES = {}
SONGS = {}
FixedUpdateProperties = Data.define(:fixed_timestep, :fixed_timestep_int_ms, :max_timestep)
FixedUpdate = Struct.new(:milliseconds, :accumulator, :interpolation, :alpha)
attr_accessor :show_cursor, :show_stats_plotter
attr_writer :exit_on_opengl_error
attr_reader :last_frame_time, :delta_time, :states
@@ -28,7 +31,7 @@ module CyberarmEngine
@@instance
end
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false)
def initialize(width: 800, height: 600, fullscreen: false, update_interval: 1000.0 / 60, resizable: false, borderless: false, fixed_update_timestep: 1.0 / 125, fixed_update_timestep_int_ms: 8, fixed_max_timestep: 1.0 / 60)
@show_cursor = false
@has_focus = false
@show_stats_plotter = false
@@ -46,6 +49,9 @@ module CyberarmEngine
preload_default_shaders if respond_to?(:preload_default_shaders)
@stats_plotter = Stats::StatsPlotter.new(2, 28) # FIXME: Make positioning easy
@fixed_timestep_data = FixedUpdateProperties.new(1.0 / 125, 8, 1.0 / 60)
@fixed_update = FixedUpdate.new(0, 0.0, 0.0, 1.0)
setup
end
@@ -79,11 +85,44 @@ module CyberarmEngine
Stats.frame.start_timing(:update)
current_state&.update
Stats.frame.start_timing(:fixed_update)
fixed_update
Stats.frame.end_timing(:fixed_update)
Stats.frame.end_timing(:update)
Stats.frame.start_timing(:interframe_sleep) unless needs_redraw?
end
def fixed_update
@delta_time = @fixed_timestep_data.max_timestep if @delta_time > @fixed_timestep_data.max_timestep
@fixed_update.accumulator += @delta_time
while @fixed_update.accumulator >= @fixed_timestep_data.fixed_timestep
@fixed_update.accumulator -= @fixed_timestep_data.fixed_timestep
@fixed_update.alpha = @fixed_update.accumulator / @fixed_timestep_data.fixed_timestep
@fixed_update.milliseconds += @fixed_timestep_data.fixed_timestep_int_ms
current_state&.fixed_update(@fixed_timestep_data.fixed_timestep)
end
end
def fixed_update_milliseconds
@fixed_update.milliseconds
end
def fixed_update_accumulator
@fixed_update.accumulator
end
def fixed_update_interpolation
@fixed_update.interpolation
end
def fixed_update_alpha
@fixed_update.alpha
end
def needs_cursor?
@show_cursor
end