mirror of
https://github.com/cyberarm/i-mic-rts.git
synced 2025-12-13 14:52:35 +00:00
Entities are now definable
This commit is contained in:
@@ -26,7 +26,6 @@ require_relative "lib/states/menus/multiplayer_lobby_menu"
|
|||||||
|
|
||||||
require_relative "lib/zorder"
|
require_relative "lib/zorder"
|
||||||
require_relative "lib/entity"
|
require_relative "lib/entity"
|
||||||
# require_relative "lib/entities/"
|
|
||||||
require_relative "lib/map"
|
require_relative "lib/map"
|
||||||
require_relative "lib/tiled_map"
|
require_relative "lib/tiled_map"
|
||||||
|
|
||||||
|
|||||||
11
lib/entities/construction_worker.rb
Normal file
11
lib/entities/construction_worker.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
IMICRTS::Entity.define_entity(:construction_worker, :unit, 1000, "Constructs buildings") do |entity|
|
||||||
|
entity.radius = 14
|
||||||
|
entity.movement = :ground
|
||||||
|
entity.max_health = 100.0
|
||||||
|
|
||||||
|
entity.body_image = "vehicles/construction_worker/images/construction_worker.png"
|
||||||
|
entity.shell_image = "vehicles/construction_worker/images/construction_worker.png"
|
||||||
|
|
||||||
|
entity.on_tick do
|
||||||
|
end
|
||||||
|
end
|
||||||
34
lib/entities/harvester.rb
Normal file
34
lib/entities/harvester.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
IMICRTS::Entity.define_entity(:harvester, :unit, 1400, "Harvests ore") do |entity, director|
|
||||||
|
entity.radius = 10
|
||||||
|
entity.movement = :ground
|
||||||
|
entity.max_health = 100.0
|
||||||
|
|
||||||
|
entity.body_image = "vehicles/harvester/images/harvester.png"
|
||||||
|
entity.shell_image = "vehicles/harvester/images/harvester.png"
|
||||||
|
|
||||||
|
@capacity = 10.0
|
||||||
|
@bed = 0.0
|
||||||
|
|
||||||
|
entity.on_tick do
|
||||||
|
if @bed >= @capacity
|
||||||
|
entity.seek_refinery
|
||||||
|
else
|
||||||
|
entity.seek_ore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
entity.define_singleton_method(:seek_ore) do
|
||||||
|
ore = director.map.ores.compact.sort_by { |ore| next unless ore; ore.position.distance(entity.position) }.first
|
||||||
|
|
||||||
|
n = (ore.position - entity.position).normalized
|
||||||
|
n.z = 0
|
||||||
|
entity.position += n * 3
|
||||||
|
end
|
||||||
|
|
||||||
|
entity.define_singleton_method(:seek_refinery) do
|
||||||
|
end
|
||||||
|
|
||||||
|
entity.define_singleton_method(:rotate_towards) do |target|
|
||||||
|
entity.angle = Gosu.angle(target.x, target.y, entity.position.x, entity.position.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
15
lib/entities/power_plant.rb
Normal file
15
lib/entities/power_plant.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
IMICRTS::Entity.define_entity(:power_plant, :building, 800, "Generates power") do |entity|
|
||||||
|
entity.radius = 14
|
||||||
|
entity.max_health = 100.0
|
||||||
|
|
||||||
|
entity.body_image = "vehicles/power_plant/images/power_plant.png"
|
||||||
|
entity.shell_image = "vehicles/power_plant/images/power_plant.png"
|
||||||
|
|
||||||
|
entity.on_tick do
|
||||||
|
entity.produce_power
|
||||||
|
end
|
||||||
|
|
||||||
|
define_singleton_method(:produce_power) do
|
||||||
|
@player.power += 10
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,11 +1,27 @@
|
|||||||
class IMICRTS
|
class IMICRTS
|
||||||
class Entity
|
class Entity
|
||||||
attr_reader :player, :id, :position, :angle, :radius, :target, :state
|
Stub = Struct.new(:name, :type, :cost, :description, :setup)
|
||||||
def initialize(player:, id:, manifest: nil, images:, position:, angle:)
|
@entities = {}
|
||||||
|
|
||||||
|
def self.get(name)
|
||||||
|
@entities.dig(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.define_entity(name, type, cost, description, &block)
|
||||||
|
if entity = get(name)
|
||||||
|
raise "#{name.inspect} is already defined!"
|
||||||
|
else
|
||||||
|
@entities[name] = Stub.new(name, type, cost, description, block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :player, :id, :name, :type
|
||||||
|
attr_accessor :position, :angle, :radius, :target, :state,
|
||||||
|
:movement, :health, :max_health,
|
||||||
|
:turret
|
||||||
|
def initialize(name:, player:, id:, position:, angle:, director:)
|
||||||
@player = player
|
@player = player
|
||||||
@id = id
|
@id = id
|
||||||
@manifest = manifest
|
|
||||||
@images = images
|
|
||||||
@position = position
|
@position = position
|
||||||
@angle = angle
|
@angle = angle
|
||||||
|
|
||||||
@@ -13,7 +29,14 @@ class IMICRTS
|
|||||||
@target = nil
|
@target = nil
|
||||||
@state = :idle
|
@state = :idle
|
||||||
|
|
||||||
# process_manifest
|
if entity = Entity.get(name)
|
||||||
|
@name = entity.name
|
||||||
|
@type = entity.type
|
||||||
|
|
||||||
|
entity.setup.call(self, director)
|
||||||
|
else
|
||||||
|
raise "Failed to find entity #{name.inspect} definition"
|
||||||
|
end
|
||||||
|
|
||||||
@goal_color = Gosu::Color.argb(175, 25, 200, 25)
|
@goal_color = Gosu::Color.argb(175, 25, 200, 25)
|
||||||
@target_color = Gosu::Color.argb(175, 200, 25, 25)
|
@target_color = Gosu::Color.argb(175, 200, 25, 25)
|
||||||
@@ -25,6 +48,22 @@ class IMICRTS
|
|||||||
def deserialize
|
def deserialize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def body_image=(image)
|
||||||
|
@body_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def shell_image=(image)
|
||||||
|
@shell_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def turret_body_image=(image)
|
||||||
|
@turret_body_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def turret_shell_image=(image)
|
||||||
|
@turret_shell_image = Gosu::Image.new("#{IMICRTS::ASSETS_PATH}/#{image}", retro: true)
|
||||||
|
end
|
||||||
|
|
||||||
def target=(entity)
|
def target=(entity)
|
||||||
@target = entity
|
@target = entity
|
||||||
end
|
end
|
||||||
@@ -42,11 +81,20 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@images.draw_rot(@position.x, @position.y, @position.z, @angle)
|
@body_image.draw_rot(@position.x, @position.y, @position.z, @angle)
|
||||||
|
@shell_image.draw_rot(@position.x, @position.y, @position.z, @angle, 0.5, 0.5, 1, 1, @player.color)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
rotate_towards(@target) if @target
|
rotate_towards(@target) if @target && @movement
|
||||||
|
end
|
||||||
|
|
||||||
|
def tick(tick_id)
|
||||||
|
@on_tick.call if @on_tick
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_tick(&block)
|
||||||
|
@on_tick = block
|
||||||
end
|
end
|
||||||
|
|
||||||
def selected_draw
|
def selected_draw
|
||||||
@@ -84,4 +132,8 @@ class IMICRTS
|
|||||||
@angle %= 360.0
|
@angle %= 360.0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Dir.glob("#{IMICRTS::GAME_ROOT_PATH}/lib/entities/*.rb").each do |entity|
|
||||||
|
require_relative entity
|
||||||
end
|
end
|
||||||
@@ -2,6 +2,7 @@ class IMICRTS
|
|||||||
class Map
|
class Map
|
||||||
Tile = Struct.new(:position, :color, :image, :state, :type)
|
Tile = Struct.new(:position, :color, :image, :state, :type)
|
||||||
|
|
||||||
|
attr_reader :tiles, :ores
|
||||||
def initialize(map_file:)
|
def initialize(map_file:)
|
||||||
@tiled_map = TiledMap.new(map_file)
|
@tiled_map = TiledMap.new(map_file)
|
||||||
|
|
||||||
@@ -19,6 +20,9 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@tiles.freeze
|
||||||
|
@ores.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_terrain(x, y, tile_id)
|
def add_terrain(x, y, tile_id)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class IMICRTS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tick(tick_id)
|
def tick(tick_id)
|
||||||
|
@entities.each { |ent| ent.tick(tick_id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class IMICRTS
|
|||||||
|
|
||||||
@selected_entities = []
|
@selected_entities = []
|
||||||
|
|
||||||
@debug_info = CyberarmEngine::Text.new("", y: 10, z: Float::INFINITY)
|
@debug_info = CyberarmEngine::Text.new("", y: 10, z: Float::INFINITY, shadow_color: Gosu::Color.rgba(0, 0, 0, 200))
|
||||||
|
|
||||||
@sidebar = stack(height: 1.0) do
|
@sidebar = stack(height: 1.0) do
|
||||||
background [0x55555555, 0x55666666]
|
background [0x55555555, 0x55666666]
|
||||||
@@ -19,18 +19,20 @@ class IMICRTS
|
|||||||
@buttons = stack(width: 75) do
|
@buttons = stack(width: 75) do
|
||||||
@h = button("Harvester", width: 1.0) do
|
@h = button("Harvester", width: 1.0) do
|
||||||
@player.entities << Entity.new(
|
@player.entities << Entity.new(
|
||||||
|
name: :harvester,
|
||||||
|
director: @director,
|
||||||
player: @player,
|
player: @player,
|
||||||
id: @player.next_entity_id,
|
id: @player.next_entity_id,
|
||||||
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/harvester/images/harvester.png", retro: true),
|
|
||||||
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
||||||
angle: rand(360)
|
angle: rand(360)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@c = button("Construction Worker", width: 1.0) do
|
@c = button("Construction Worker", width: 1.0) do
|
||||||
@player.entities << Entity.new(
|
@player.entities << Entity.new(
|
||||||
|
name: :construction_worker,
|
||||||
|
director: @director,
|
||||||
player: @player,
|
player: @player,
|
||||||
id: @player.next_entity_id,
|
id: @player.next_entity_id,
|
||||||
images: Gosu::Image.new("#{ASSETS_PATH}/vehicles/construction_worker/images/construction_worker.png", retro: true),
|
|
||||||
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
position: CyberarmEngine::Vector.new(rand(window.width), rand(window.height), ZOrder::GROUND_VEHICLE),
|
||||||
angle: rand(360)
|
angle: rand(360)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user