From abc4305656d845429d7d85189d22af9b6d2655ba Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Tue, 1 Oct 2019 14:54:35 -0500 Subject: [PATCH] Basic unit selection implemented --- lib/camera.rb | 8 +++++--- lib/entity.rb | 30 +++++++++++++++++++++++++++++- lib/states/game.rb | 36 +++++++++++++++++++++++++++++------- lib/zorder.rb | 9 ++++++++- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/lib/camera.rb b/lib/camera.rb index 82bdb91..b2411bf 100644 --- a/lib/camera.rb +++ b/lib/camera.rb @@ -18,8 +18,8 @@ class IMICRTS def draw(&block) if block + center_point = center Gosu.translate(@position.x, @position.y) do - center_point = center Gosu.scale(@zoom, @zoom, center.x, center.y) do block.call end @@ -28,6 +28,8 @@ class IMICRTS end def update + @zoom = 1.0 + move @velocity *= @drag @@ -35,9 +37,9 @@ class IMICRTS end def mouse_pick(x, y) - mouse = CyberarmEngine::Vector.new(x, y) / @zoom + mouse = CyberarmEngine::Vector.new(x, y) - worldspace = (mouse - @position) + worldspace = (mouse - @position) / @zoom worldspace.x = worldspace.x.floor worldspace.y = worldspace.y.floor diff --git a/lib/entity.rb b/lib/entity.rb index 114682e..7e78c3b 100644 --- a/lib/entity.rb +++ b/lib/entity.rb @@ -1,13 +1,41 @@ class IMICRTS class Entity - def initialize(images:, position:, angle:) + attr_reader :position, :angle + def initialize(manifest: nil, images:, position:, angle:) + @manifest = manifest @images = images @position = position @angle = angle + + @radius = 32 / 2 + end + + def hit?(x_or_vector, y = nil) + vector = nil + if x_or_vector.is_a?(CyberarmEngine::Vector) + vector = x_or_vector + else + raise "Y cannot be nil!" if y.nil? + vector = CyberarmEngine::Vector.new(x_or_vector, y) + end + + @position.distance(vector) < @radius + 1 end def draw @images.draw_rot(@position.x, @position.y, @position.z, @angle) end + + def selected_draw + draw_bounding_box + draw_gizmos + end + + def draw_bounding_box + end + + def draw_gizmos + Gosu.draw_rect(@position.x - @radius, @position.y - (@radius + 2), @radius * 2, 2, Gosu::Color::GREEN, ZOrder::ENTITY_GIZMOS) + end end end \ No newline at end of file diff --git a/lib/states/game.rb b/lib/states/game.rb index 221fea2..6c642d8 100644 --- a/lib/states/game.rb +++ b/lib/states/game.rb @@ -2,6 +2,7 @@ class IMICRTS class Game < CyberarmEngine::GuiState def setup @units = [] + @selected_entities = [] @camera = Camera.new @mouse_pos = CyberarmEngine::Text.new("X: 0\nY: 0", x: 500, y: 10, z: Float::INFINITY) @@ -42,12 +43,13 @@ class IMICRTS @camera.draw do @units.each(&:draw) + @selected_entities.each(&:selected_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) + # draw_rect(@camera.center.x - 10, @camera.center.y - 10, 20, 20, Gosu::Color::BLACK, Float::INFINITY) - mouse = @camera.mouse_pick(window.mouse_x, window.mouse_y) - draw_rect(mouse.x - 10, mouse.y - 10, 20, 20, Gosu::Color::YELLOW, Float::INFINITY) + # mouse = @camera.mouse_pick(window.mouse_x, window.mouse_y) + # draw_rect(mouse.x - 10, mouse.y - 10, 20, 20, Gosu::Color::YELLOW, Float::INFINITY) + Gosu.draw_rect(@box.min.x, @box.min.y, @box.width, @box.height, Gosu::Color.rgba(50, 50, 50, 150), Float::INFINITY) if @box end @mouse_pos.draw @@ -58,8 +60,8 @@ class IMICRTS @camera.update - if @anchor - @camera.center_around(@anchor, 0.9) + if @selection_start + select_entities end mouse = @camera.mouse_pick(window.mouse_x, window.mouse_y) @@ -72,7 +74,7 @@ class IMICRTS case id when Gosu::MS_LEFT unless @sidebar.hit?(window.mouse_x, window.mouse_y) - @anchor = @camera.mouse_pick(window.mouse_x, window.mouse_y) + @selection_start = CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @camera.position end when Gosu::MS_RIGHT @anchor = nil @@ -83,9 +85,29 @@ class IMICRTS def button_up(id) super + case id + when Gosu::MS_LEFT + @box = nil + @selection_start = nil + end + @camera.button_up(id) end + def select_entities + @box = CyberarmEngine::BoundingBox.new(@selection_start, CyberarmEngine::Vector.new(window.mouse_x, window.mouse_y) - @camera.position) + + selected_entities = @units.select do |ent| + @box.point?(ent.position) + end + + if Gosu.button_down?(Gosu::KB_LEFT_SHIFT) || Gosu.button_down?(Gosu::KB_RIGHT_SHIFT) + @selected_entities = @selected_entities.union(selected_entities) + else + @selected_entities = selected_entities + end + end + def finalize # TODO: Release bound objects/remove self from Window.states array end diff --git a/lib/zorder.rb b/lib/zorder.rb index 9bb3e1e..7f7d2a2 100644 --- a/lib/zorder.rb +++ b/lib/zorder.rb @@ -2,7 +2,14 @@ class IMICRTS class ZOrder base_z = 5 enum = [ - :GROUND_VEHICLE + :TILE, + :DECORATION, + :GROUND_VEHICLE, + :BUILDING, + :AIR_VEHICLE, + + :ENTITY_BOUNDING_BOX, + :ENTITY_GIZMOS, # Health bar and the like ] enum.each_with_index do |constant, index|