From 80027086951de361137e4e8e38bf82aeafea9820 Mon Sep 17 00:00:00 2001 From: cyberarm Date: Mon, 19 Apr 2021 19:13:15 +0000 Subject: [PATCH] Updated Animator to be usable, added logo texture/image, 'finished' Intro state, added Window#shift_state --- assets/textures/logo.png | Bin 0 -> 28971 bytes lib/cyberarm_engine/animator.rb | 16 +-- lib/cyberarm_engine/builtin/intro_state.rb | 115 +++++++++++++++++---- lib/cyberarm_engine/common.rb | 4 + lib/cyberarm_engine/text.rb | 1 + lib/cyberarm_engine/window.rb | 6 +- 6 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 assets/textures/logo.png diff --git a/assets/textures/logo.png b/assets/textures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..588d340a020252bef7f406344efeec403f4b44bf GIT binary patch literal 28971 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 literal 0 HcmV?d00001 diff --git a/lib/cyberarm_engine/animator.rb b/lib/cyberarm_engine/animator.rb index 6440d9e..5be93df 100644 --- a/lib/cyberarm_engine/animator.rb +++ b/lib/cyberarm_engine/animator.rb @@ -1,11 +1,11 @@ module CyberarmEngine class Animator - DEFAULT_TWEEN = :linear - def initialize(start_time:, duration:, from:, to:, &block) + def initialize(start_time:, duration:, from:, to:, tween: :linear, &block) @start_time = start_time @duration = duration @from = from.dup @to = to.dup + @tween = tween @block = block end @@ -14,18 +14,18 @@ module CyberarmEngine end def progress - (@start_time.to_f + (Gosu.milliseconds - @start_time)) / (@start_time + @duration.to_f) + ((Gosu.milliseconds - @start_time) / @duration.to_f).clamp(0.0, 1.0) end def complete? progress >= 1.0 end - def transition(from, to, tween = DEFAULT_TWEEN) + def transition(from = @from, to = @to, tween = @tween) from + (to - from) * send("tween_#{tween}", progress) end - def color_transition(from, to, _tween = DEFAULT_TWEEN) + def color_transition(from = @from, to = @to, _tween = @tween) r = transition(from.red, to.red) g = transition(from.green, to.green) b = transition(from.blue, to.blue) @@ -34,7 +34,7 @@ module CyberarmEngine Gosu::Color.rgba(r, g, b, a) end - def color_hsv_transition(from, to, tween = DEFAULT_TWEEN) + def color_hsv_transition(from = @from, to = @to, tween = @tween) hue = transition(from.hue, to.hue, tween) saturation = transition(from.saturation, to.saturation, tween) value = transition(from.value, to.value, tween) @@ -49,8 +49,8 @@ module CyberarmEngine t end - def tween_sine(t) - Math.sin(t) * t + def tween_ease_in_out(t) + (-0.5 * (Math.cos(Math::PI * t) - 1)) end end end diff --git a/lib/cyberarm_engine/builtin/intro_state.rb b/lib/cyberarm_engine/builtin/intro_state.rb index 83f4702..4258ea9 100644 --- a/lib/cyberarm_engine/builtin/intro_state.rb +++ b/lib/cyberarm_engine/builtin/intro_state.rb @@ -1,53 +1,126 @@ module CyberarmEngine class IntroState < CyberarmEngine::GameState def setup + @display_width = 800 + @display_height = 600 + @title_size = 56 @caption_size = 24 - @title = CyberarmEngine::Text.new("", size: @title_size) - @caption = CyberarmEngine::Text.new("", size: @caption_size) + @title = CyberarmEngine::Text.new("", size: @title_size, shadow_color: 0xaa_222222) + @caption = CyberarmEngine::Text.new("", size: @caption_size, shadow_color: 0xaa_222222) @spacer_width = 256 + @spacer_height = 6 + @padding = 6 - @cyberarm_engine_logo = generate_proxy("CyberarmEngine", "Powered By") + @cyberarm_engine_logo = get_image "#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/logo.png" - @gosu_logo = generate_proxy("Gosu", "Game Library") - @ruby_logo = generate_proxy("Ruby", "Programming Language") - @sdl2_logo = generate_proxy("SDL2", "Simple DirectMedia Layer") + @gosu_logo = generate_proxy("Gosu", "Game Library", 0xff_111111) + @ruby_logo = generate_proxy("Ruby", "Programming Language", 0xff_880000) + @opengl_logo = generate_proxy("OpenGL", "Graphics API", 0xff_5586a4) if defined?(OpenGL) + + base_time = Gosu.milliseconds + + @animators = [ + Animator.new(start_time: base_time += 1000, duration: 100, from: 0.0, to: 1.0, tween: :ease_in_out), + Animator.new(start_time: base_time += -500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out), + Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out), + Animator.new(start_time: base_time += 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out), + Animator.new(start_time: base_time + 500, duration: 1_000, from: 0.0, to: 1.0, tween: :ease_in_out), + + Animator.new(start_time: Gosu.milliseconds + 250, duration: 500, from: 0.0, to: 1.0, tween: :ease_in_out) # CyberarmEngine LOGO + ] + + @born_time = Gosu.milliseconds + @continue_after = 5_000 end def draw Gosu.draw_rect(0, 0, window.width, window.height, 0xff_222222) - @cyberarm_engine_logo.draw(window.width / 2 - @cyberarm_engine_logo.width / 2, window.height / 2 - @cyberarm_engine_logo.height, 2) + scale = (@display_width - @padding * 2).to_f / @cyberarm_engine_logo.width * @animators.last.transition - @gosu_logo.draw(6, window.height - @gosu_logo.height - 6, 2) - @ruby_logo.draw(window.width / 2 - @ruby_logo.width / 2, window.height - @ruby_logo.height - 6, 2) - @sdl2_logo.draw(window.width - (@sdl2_logo.width + 6), window.height - @sdl2_logo.height - 6, 2) + @cyberarm_engine_logo.draw_rot( + window.width / 2, + (window.height) / 2 - @cyberarm_engine_logo.height / 2 - @padding * 2, + 2, + 0, + 0.5, + 0.5, + scale, + scale + ) + + Gosu.draw_rect( + window.width / 2 - (@display_width / 2 + @padding), + window.height / 2 - @spacer_height / 2, + @display_width + @padding, + @spacer_height * @animators[0].transition, + Gosu::Color::WHITE + ) + + @title.x = window.width / 2 - @title.width / 2 + @title.y = (window.height / 2 + (@spacer_height / 2) + @padding) * @animators[1].transition + @title.text = "Powered By" + + Gosu.clip_to(0, window.height / 2 + (@spacer_height / 2), window.width, @title.height) do + @title.draw + end + + y = @title.y + @title.height * 2 + + Gosu.clip_to(0, y, window.width, @gosu_logo.height) do + Gosu.translate(@opengl_logo.nil? ? @ruby_logo.width / 2 : 0, 0) do + @gosu_logo.draw( + window.width.to_f / 2 - @ruby_logo.width / 2 - (@ruby_logo.width - @padding), + y * @animators[2].transition, + 2 + ) + @ruby_logo.draw( + window.width.to_f / 2 - @ruby_logo.width / 2, + y * @animators[3].transition, + 2 + ) + @opengl_logo&.draw( + window.width.to_f / 2 - @ruby_logo.width / 2 + (@ruby_logo.width - @padding), + y * @animators[4].transition, + 2 + ) + end + end end def update + @animators.each(&:update) + + return unless Gosu.milliseconds - @born_time >= @continue_after + + pop_state + push_state(@options[:forward], @options[:forward_options] || {}) if @options[:forward] end - def generate_proxy(title, caption) + def button_down(_id) + @continue_after = 0 + end + + def generate_proxy(title, caption, color_hint) @title.text = title @caption.text = caption - padding = 6 - spacer_height = 6 - - width = @spacer_width + 2 * padding - height = @title_size + @caption_size + spacer_height + 2 * padding + spacer_height + width = @spacer_width + 2 * @padding + height = @title_size + @caption_size + @spacer_height + 2 * @padding + @spacer_height Gosu.record(width.ceil, height.ceil) do - @title.x = (width - padding * 2) / 2 - @title.width / 2 - @title.y = padding + @title.x = (width - @padding * 2) / 2 - @title.width / 2 + @title.y = @padding @title.draw - Gosu.draw_rect(0, padding + @title_size + padding, @spacer_width, spacer_height, Gosu::Color::WHITE) + Gosu.draw_rect(0, @padding + @title_size + @padding, @spacer_width, @spacer_height, Gosu::Color::WHITE) + Gosu.draw_rect(1, @padding + @title_size + @padding + 1, @spacer_width - 2, @spacer_height - 2, color_hint) - @caption.x = (width - padding * 2) / 2 - @caption.width / 2 - @caption.y = padding + @title_size + padding + spacer_height + padding + @caption.x = (width - @padding * 2) / 2 - @caption.width / 2 + @caption.y = @padding + @title_size + @padding + @spacer_height + @padding @caption.draw end end diff --git a/lib/cyberarm_engine/common.rb b/lib/cyberarm_engine/common.rb index 6e1ed30..ca3dece 100644 --- a/lib/cyberarm_engine/common.rb +++ b/lib/cyberarm_engine/common.rb @@ -16,6 +16,10 @@ module CyberarmEngine window.pop_state end + def shift_state + window.shift_state + end + def show_cursor window.show_cursor end diff --git a/lib/cyberarm_engine/text.rb b/lib/cyberarm_engine/text.rb index c10ca01..70cada6 100644 --- a/lib/cyberarm_engine/text.rb +++ b/lib/cyberarm_engine/text.rb @@ -149,6 +149,7 @@ module CyberarmEngine @textobject.send(method, @text, _x + @shadow_size, _y, @z, @factor_x, @factor_y, white, :add) @textobject.send(method, @text, _x + @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add) end + @rendered_shadow.draw(@x - @shadow_size, @y - @shadow_size, @z, @factor_x, @factor_y, shadow_color) end diff --git a/lib/cyberarm_engine/window.rb b/lib/cyberarm_engine/window.rb index cf4a929..67d4441 100644 --- a/lib/cyberarm_engine/window.rb +++ b/lib/cyberarm_engine/window.rb @@ -95,7 +95,7 @@ module CyberarmEngine end def previous_state - if @states.size > 1 && state = @states[@states.size - 2] + if @states.size > 1 && (state = @states[@states.size - 2]) state end end @@ -104,6 +104,10 @@ module CyberarmEngine @states.pop end + def shift_state + @states.shift + 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|