diff --git a/i-mic-rts.rb b/i-mic-rts.rb index 588e398..398a8fb 100644 --- a/i-mic-rts.rb +++ b/i-mic-rts.rb @@ -5,6 +5,7 @@ rescue LoadError end require_relative "lib/window" +require_relative "lib/camera" require_relative "lib/states/boot" require_relative "lib/states/game" diff --git a/lib/camera.rb b/lib/camera.rb new file mode 100644 index 0000000..5e11a2b --- /dev/null +++ b/lib/camera.rb @@ -0,0 +1,74 @@ +class IMICRTS + class Camera + attr_reader :position, :velocity, :drag + def initialize(scroll_speed: 10, position: CyberarmEngine::Vector.new(0.0, 0.0)) + @scroll_speed = scroll_speed + @position = position + @velocity = CyberarmEngine::Vector.new(0.0, 0.0) + + @drag = 0.8 + end + + def window; $window; end + + def draw(&block) + if block + Gosu.translate(@position.x, @position.y) do + block.call + end + end + end + + def update + move + @velocity *= @drag + + @position += @velocity * @scroll_speed + end + + def center + CyberarmEngine::Vector.new(window.width / 2, window.height / 2) - @position + end + + def center_around(vector, factor) + @velocity *= 0 + delta = lerp(self.center, vector, factor) + @position += delta * window.dt + end + + def lerp(vec1, vec2, factor) + (vec1 - vec2) * factor.clamp(0.0, 1.0) + end + + def move + @velocity.x += @scroll_speed * window.dt if Gosu.button_down?(Gosu::KB_LEFT) || window.mouse_x < 15 + @velocity.x -= @scroll_speed * window.dt if Gosu.button_down?(Gosu::KB_RIGHT) || window.mouse_x > window.width - 15 + @velocity.y += @scroll_speed * window.dt if Gosu.button_down?(Gosu::KB_UP) || window.mouse_y < 15 + @velocity.y -= @scroll_speed * window.dt if Gosu.button_down?(Gosu::KB_DOWN) || window.mouse_y > window.height - 15 + + if @drag_start + @velocity *= 0.0 + @position = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @drag_start + end + end + + def button_down(id) + case id + when Gosu::KB_H + @position.x, @position.y = 0.0, 0.0 + @velocity *= 0.0 + when Gosu::MS_MIDDLE + @position_start = @position.clone + @drag_start = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @position + end + end + + def button_up(id) + case id + when Gosu::MS_MIDDLE + @position_start = nil + @drag_start = nil + end + end + end +end \ No newline at end of file diff --git a/lib/states/game.rb b/lib/states/game.rb index 740b17c..d464a4d 100644 --- a/lib/states/game.rb +++ b/lib/states/game.rb @@ -2,8 +2,10 @@ class IMICRTS class Game < CyberarmEngine::GuiState def setup @units = [] + @camera = Camera.new + @mouse_pos = CyberarmEngine::Text.new("X: 0\nY: 0", x: 500, y: 10, z: Float::INFINITY) - stack(height: 1.0) do + @sidebar = stack(height: 1.0) do background [0xff555555, Gosu::Color::GRAY] label "SIDEBAR", text_size: 78 @@ -24,7 +26,6 @@ class IMICRTS ) end - label "" button("Leave", width: 1.0) do finalize @@ -35,9 +36,52 @@ class IMICRTS def draw super + Gosu.draw_rect(0, 0, window.width, window.height, Gosu::Color.rgb(10, 175, 35)) - @units.each(&:draw) + @camera.draw do + @units.each(&:draw) + + draw_rect(@anchor.x - 10, @anchor.y - 10, 20, 20, Gosu::Color::RED, Float::INFINITY) if @anchor + # draw_rect(@camera.center.x - 10, @camera.center.y - 10, 20, 20, Gosu::Color::BLACK, Float::INFINITY) + + # mouse_center = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @camera.position + # draw_rect(mouse_center.x - 10, mouse_center.y - 10, 20, 20, Gosu::Color::YELLOW, Float::INFINITY) + end + + @mouse_pos.draw + end + + def update + super + + @camera.update + + if @anchor + @camera.center_around(@anchor, 0.9) + end + + @mouse_pos.text = "X: #{window.mouse_x}\nY: #{window.mouse_y}" + end + + def button_down(id) + super + + case id + when Gosu::MS_LEFT + unless @sidebar.hit?(window.mouse_x, window.mouse_y) + @anchor = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @camera.position + end + when Gosu::MS_RIGHT + @anchor = nil + end + @camera.button_down(id) + end + + def button_up(id) + super + + @camera.button_up(id) end def finalize diff --git a/lib/window.rb b/lib/window.rb index e913463..d270b1c 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -1,11 +1,25 @@ class IMICRTS class Window < CyberarmEngine::Engine def setup - Gosu.milliseconds # Start counter + @last_update_time = Gosu.milliseconds self.caption = "I-MIC RTS (#{Gosu.language})" - push_state(Boot) - # push_state(MainMenu) + # push_state(Boot) + push_state(MainMenu) + end + + def update + super + + @last_update_time = Gosu.milliseconds + end + + def delta_time + Gosu.milliseconds - @last_update_time + end + + def dt + delta_time / 1000.0 end end end \ No newline at end of file