mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-15 07:42:34 +00:00
Moved entity selection/order giving into EntityController
This commit is contained in:
@@ -40,6 +40,7 @@ require_relative "lib/order"
|
|||||||
require_relative "lib/friendly_hash"
|
require_relative "lib/friendly_hash"
|
||||||
require_relative "lib/director"
|
require_relative "lib/director"
|
||||||
require_relative "lib/player"
|
require_relative "lib/player"
|
||||||
|
require_relative "lib/entity_controller"
|
||||||
require_relative "lib/connection"
|
require_relative "lib/connection"
|
||||||
|
|
||||||
require_relative "lib/networking/protocol"
|
require_relative "lib/networking/protocol"
|
||||||
|
|||||||
@@ -97,15 +97,13 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def move_to(x, y, zoom)
|
def move_to(x, y, zoom)
|
||||||
|
@velocity *= 0.0
|
||||||
@position.x, @position.y = x, y
|
@position.x, @position.y = x, y
|
||||||
@zoom = zoom
|
@zoom = zoom
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_down(id)
|
def button_down(id)
|
||||||
case id
|
case id
|
||||||
when Gosu::KB_H
|
|
||||||
@position.x, @position.y = 0.0, 0.0
|
|
||||||
@velocity *= 0.0
|
|
||||||
when Gosu::MS_WHEEL_UP
|
when Gosu::MS_WHEEL_UP
|
||||||
@zoom = (@zoom + 0.25).clamp(@min_zoom, @max_zoom)
|
@zoom = (@zoom + 0.25).clamp(@min_zoom, @max_zoom)
|
||||||
when Gosu::MS_WHEEL_DOWN
|
when Gosu::MS_WHEEL_DOWN
|
||||||
|
|||||||
@@ -100,6 +100,18 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def spawn_entity(player_id:, name:, position:)
|
||||||
|
_player = player(player_id)
|
||||||
|
_player.entities << Entity.new(
|
||||||
|
name: name,
|
||||||
|
director: self,
|
||||||
|
player: _player,
|
||||||
|
id: _player.next_entity_id,
|
||||||
|
position: position,
|
||||||
|
angle: 0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def entities
|
def entities
|
||||||
@players.map { |player| player.entities }.flatten
|
@players.map { |player| player.entities }.flatten
|
||||||
|
|||||||
86
lib/entity_controller.rb
Normal file
86
lib/entity_controller.rb
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
class IMICRTS
|
||||||
|
# Handles entity de/selection and order manipulation
|
||||||
|
class EntityController
|
||||||
|
attr_reader :selected_entities
|
||||||
|
def initialize(game:, director:, player:)
|
||||||
|
@game = game
|
||||||
|
@director = director
|
||||||
|
@player = player
|
||||||
|
|
||||||
|
@drag_start = CyberarmEngine::Vector.new
|
||||||
|
@selected_entities = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
Gosu.draw_rect(
|
||||||
|
@box.min.x, @box.min.y,
|
||||||
|
@box.width, @box.height,
|
||||||
|
Gosu::Color.rgba(50, 50, 50, 150), ZOrder::SELECTION_BOX
|
||||||
|
) if @box
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @selection_start
|
||||||
|
select_entities
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_down(id)
|
||||||
|
case id
|
||||||
|
when Gosu::KB_H
|
||||||
|
ent = @player.entities.find { |ent| ent.name == :construction_yard }
|
||||||
|
ent ||= @player.entities.find { |ent| ent.name == :construction_worker }
|
||||||
|
ent ||= @player.starting_position
|
||||||
|
|
||||||
|
@player.camera.move_to(
|
||||||
|
@game.window.width / 2 - ent.position.x,
|
||||||
|
@game.window.height / 2 - ent.position.y,
|
||||||
|
@player.camera.zoom
|
||||||
|
)
|
||||||
|
|
||||||
|
when Gosu::KB_S
|
||||||
|
@director.schedule_order(Order::STOP, @player.id)
|
||||||
|
|
||||||
|
when Gosu::MS_LEFT
|
||||||
|
unless @game.sidebar.hit?(@game.window.mouse_x, @game.window.mouse_y)
|
||||||
|
@selection_start = @player.camera.transform(@game.window.mouse)
|
||||||
|
end
|
||||||
|
when Gosu::MS_RIGHT
|
||||||
|
@director.schedule_order(Order::MOVE, @player.id, @player.camera.transform(@game.window.mouse))
|
||||||
|
|
||||||
|
@game.overlays << Game::Overlay.new(Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/cursors/move.png"), @player.camera.transform(@game.window.mouse), 0, 255)
|
||||||
|
@game.overlays.last.position.z = ZOrder::OVERLAY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def button_up(id)
|
||||||
|
case id
|
||||||
|
when Gosu::MS_RIGHT
|
||||||
|
when Gosu::MS_LEFT
|
||||||
|
@box = nil
|
||||||
|
@selection_start = nil
|
||||||
|
|
||||||
|
diff = (@player.selected_entities - @selected_entities)
|
||||||
|
|
||||||
|
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff)
|
||||||
|
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @selected_entities)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_entities
|
||||||
|
transform = @player.camera.transform(@game.window.mouse)
|
||||||
|
@box = CyberarmEngine::BoundingBox.new(@selection_start.xy, transform.xy)
|
||||||
|
|
||||||
|
selected_entities = @player.entities.select do |ent|
|
||||||
|
@box.point?(ent.position) ||
|
||||||
|
@box.point?(ent.position - ent.radius) || @box.point?(ent.position + ent.radius)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -88,6 +88,5 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
Dir.glob("#{IMICRTS::GAME_ROOT_PATH}/lib/particle_emitters/**/*.rb").each do |emitter|
|
Dir.glob("#{IMICRTS::GAME_ROOT_PATH}/lib/particle_emitters/**/*.rb").each do |emitter|
|
||||||
p emitter
|
|
||||||
require_relative emitter
|
require_relative emitter
|
||||||
end
|
end
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Game < CyberarmEngine::GuiState
|
class Game < CyberarmEngine::GuiState
|
||||||
Overlay = Struct.new(:image, :position, :angle, :alpha)
|
Overlay = Struct.new(:image, :position, :angle, :alpha)
|
||||||
|
|
||||||
|
attr_reader :sidebar, :overlays
|
||||||
def setup
|
def setup
|
||||||
window.show_cursor = true
|
window.show_cursor = true
|
||||||
@options[:networking_mode] ||= :host
|
@options[:networking_mode] ||= :host
|
||||||
|
|
||||||
@player = Player.new(id: 0)
|
@player = Player.new(id: 0)
|
||||||
@director = Director.new(map: Map.new(map_file: "maps/test_map.tmx"), networking_mode: @options[:networking_mode], players: [@player])
|
@director = Director.new(map: Map.new(map_file: "maps/test_map.tmx"), networking_mode: @options[:networking_mode], players: [@player])
|
||||||
|
@entity_controller = EntityController.new(game: self, director: @director, player: @player)
|
||||||
|
|
||||||
@selected_entities = []
|
|
||||||
@overlays = []
|
@overlays = []
|
||||||
|
|
||||||
@debug_info = CyberarmEngine::Text.new("", y: 10, z: Float::INFINITY, shadow_color: Gosu::Color.rgba(0, 0, 0, 200))
|
@debug_info = CyberarmEngine::Text.new("", y: 10, z: Float::INFINITY, shadow_color: Gosu::Color.rgba(0, 0, 0, 200))
|
||||||
@@ -67,62 +69,40 @@ class IMICRTS
|
|||||||
|
|
||||||
# 100.times { |i| [@c, @h, @t].sample.instance_variable_get("@block").call }
|
# 100.times { |i| [@c, @h, @t].sample.instance_variable_get("@block").call }
|
||||||
spawnpoint = @director.map.spawnpoints.last
|
spawnpoint = @director.map.spawnpoints.last
|
||||||
@player.entities << Entity.new(
|
@director.spawn_entity(
|
||||||
name: :construction_yard,
|
player_id: @player.id, name: :construction_yard,
|
||||||
director: @director,
|
position: CyberarmEngine::Vector.new(spawnpoint.x, spawnpoint.y, ZOrder::BUILDING)
|
||||||
player: @player,
|
)
|
||||||
id: @player.next_entity_id,
|
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x, spawnpoint.y, ZOrder::BUILDING),
|
@director.spawn_entity(
|
||||||
angle: 0
|
player_id: @player.id, name: :construction_worker,
|
||||||
)
|
position: CyberarmEngine::Vector.new(spawnpoint.x - 64, spawnpoint.y + 64, ZOrder::GROUND_VEHICLE)
|
||||||
@player.entities << Entity.new(
|
)
|
||||||
name: :construction_worker,
|
|
||||||
director: @director,
|
@director.spawn_entity(
|
||||||
player: @player,
|
player_id: @player.id, name: :power_plant,
|
||||||
id: @player.next_entity_id,
|
position: CyberarmEngine::Vector.new(spawnpoint.x + 64, spawnpoint.y + 64, ZOrder::BUILDING)
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x - 64, spawnpoint.y + 64, ZOrder::GROUND_VEHICLE),
|
)
|
||||||
angle: 0
|
|
||||||
)
|
@director.spawn_entity(
|
||||||
@player.entities << Entity.new(
|
player_id: @player.id, name: :refinery,
|
||||||
name: :power_plant,
|
position: CyberarmEngine::Vector.new(spawnpoint.x + 130, spawnpoint.y + 64, ZOrder::BUILDING)
|
||||||
director: @director,
|
)
|
||||||
player: @player,
|
|
||||||
id: @player.next_entity_id,
|
@director.spawn_entity(
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x + 64, spawnpoint.y + 64, ZOrder::BUILDING),
|
player_id: @player.id, name: :war_factory,
|
||||||
angle: 0
|
position: CyberarmEngine::Vector.new(spawnpoint.x + 130, spawnpoint.y - 64, ZOrder::BUILDING)
|
||||||
)
|
)
|
||||||
@player.entities << Entity.new(
|
|
||||||
name: :refinery,
|
@director.spawn_entity(
|
||||||
director: @director,
|
player_id: @player.id, name: :helipad,
|
||||||
player: @player,
|
position: CyberarmEngine::Vector.new(spawnpoint.x - 32, spawnpoint.y - 96, ZOrder::BUILDING)
|
||||||
id: @player.next_entity_id,
|
)
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x + 130, spawnpoint.y + 64, ZOrder::BUILDING),
|
|
||||||
angle: 0
|
@director.spawn_entity(
|
||||||
)
|
player_id: @player.id, name: :barracks,
|
||||||
@player.entities << Entity.new(
|
position: CyberarmEngine::Vector.new(spawnpoint.x - 32, spawnpoint.y + 128, ZOrder::BUILDING)
|
||||||
name: :war_factory,
|
)
|
||||||
director: @director,
|
|
||||||
player: @player,
|
|
||||||
id: @player.next_entity_id,
|
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x + 130, spawnpoint.y - 64, ZOrder::BUILDING),
|
|
||||||
angle: 0
|
|
||||||
)
|
|
||||||
@player.entities << Entity.new(
|
|
||||||
name: :helipad,
|
|
||||||
director: @director,
|
|
||||||
player: @player,
|
|
||||||
id: @player.next_entity_id,
|
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x - 32, spawnpoint.y - 96, ZOrder::BUILDING),
|
|
||||||
angle: 0
|
|
||||||
)
|
|
||||||
@player.entities << Entity.new(
|
|
||||||
name: :barracks,
|
|
||||||
director: @director,
|
|
||||||
player: @player,
|
|
||||||
id: @player.next_entity_id,
|
|
||||||
position: CyberarmEngine::Vector.new(spawnpoint.x - 32, spawnpoint.y + 128, ZOrder::BUILDING),
|
|
||||||
angle: 0
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@@ -133,7 +113,7 @@ class IMICRTS
|
|||||||
@player.camera.draw do
|
@player.camera.draw do
|
||||||
@director.map.draw(@player.camera)
|
@director.map.draw(@player.camera)
|
||||||
@director.entities.each(&:draw)
|
@director.entities.each(&:draw)
|
||||||
@selected_entities.each(&:selected_draw)
|
@entity_controller.selected_entities.each(&:selected_draw)
|
||||||
|
|
||||||
@overlays.each do |overlay|
|
@overlays.each do |overlay|
|
||||||
overlay.image.draw_rot(overlay.position.x, overlay.position.y, overlay.position.z, overlay.angle, 0.5, 0.5, 1, 1, Gosu::Color.rgba(255, 255, 255, overlay.alpha))
|
overlay.image.draw_rot(overlay.position.x, overlay.position.y, overlay.position.z, overlay.angle, 0.5, 0.5, 1, 1, Gosu::Color.rgba(255, 255, 255, overlay.alpha))
|
||||||
@@ -143,7 +123,7 @@ class IMICRTS
|
|||||||
@overlays.delete(overlay) if overlay.alpha <= 0
|
@overlays.delete(overlay) if overlay.alpha <= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
Gosu.draw_rect(@box.min.x, @box.min.y, @box.width, @box.height, Gosu::Color.rgba(50, 50, 50, 150), ZOrder::SELECTION_BOX) if @box
|
@entity_controller.draw
|
||||||
end
|
end
|
||||||
|
|
||||||
@debug_info.draw if Setting.enabled?(:debug_info_bar)
|
@debug_info.draw if Setting.enabled?(:debug_info_bar)
|
||||||
@@ -154,10 +134,7 @@ class IMICRTS
|
|||||||
|
|
||||||
@director.update
|
@director.update
|
||||||
@player.camera.update
|
@player.camera.update
|
||||||
|
@entity_controller.update
|
||||||
if @selection_start
|
|
||||||
select_entities
|
|
||||||
end
|
|
||||||
|
|
||||||
mouse = @player.camera.transform(window.mouse)
|
mouse = @player.camera.transform(window.mouse)
|
||||||
tile = @director.map.tile_at(mouse.x / @director.map.tile_size, mouse.y / @director.map.tile_size)
|
tile = @director.map.tile_at(mouse.x / @director.map.tile_size, mouse.y / @director.map.tile_size)
|
||||||
@@ -184,57 +161,17 @@ class IMICRTS
|
|||||||
def button_down(id)
|
def button_down(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
case id
|
@entity_controller.button_down(id)
|
||||||
when Gosu::KB_S
|
|
||||||
@director.schedule_order(Order::STOP, @player.id)
|
|
||||||
|
|
||||||
when Gosu::MS_LEFT
|
|
||||||
unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
|
||||||
@selection_start = @player.camera.transform(window.mouse)
|
|
||||||
end
|
|
||||||
when Gosu::MS_RIGHT
|
|
||||||
@director.schedule_order(Order::MOVE, @player.id, @player.camera.transform(window.mouse))
|
|
||||||
|
|
||||||
@overlays << Overlay.new(Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/cursors/move.png"), @player.camera.transform(window.mouse), 0, 255)
|
|
||||||
@overlays.last.position.z = ZOrder::OVERLAY
|
|
||||||
end
|
|
||||||
|
|
||||||
@player.camera.button_down(id) unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
@player.camera.button_down(id) unless @sidebar.hit?(window.mouse_x, window.mouse_y)
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
super
|
super
|
||||||
|
|
||||||
case id
|
@entity_controller.button_up(id)
|
||||||
when Gosu::MS_RIGHT
|
|
||||||
when Gosu::MS_LEFT
|
|
||||||
@box = nil
|
|
||||||
@selection_start = nil
|
|
||||||
|
|
||||||
diff = (@player.selected_entities - @selected_entities)
|
|
||||||
|
|
||||||
@director.schedule_order(Order::DESELECTED_UNITS, @player.id, diff)
|
|
||||||
@director.schedule_order(Order::SELECTED_UNITS, @player.id, @selected_entities)
|
|
||||||
end
|
|
||||||
|
|
||||||
@player.camera.button_up(id)
|
@player.camera.button_up(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def select_entities
|
|
||||||
@box = CyberarmEngine::BoundingBox.new(@selection_start, @player.camera.transform(window.mouse))
|
|
||||||
|
|
||||||
selected_entities = @player.entities.select do |ent|
|
|
||||||
@box.point?(ent.position - ent.radius) ||
|
|
||||||
@box.point?(ent.position + ent.radius)
|
|
||||||
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
|
def finalize
|
||||||
@director.finalize
|
@director.finalize
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user