diff --git a/lib/game_objects/entities/editor.rb b/lib/game_objects/entities/editor.rb new file mode 100644 index 0000000..5af890e --- /dev/null +++ b/lib/game_objects/entities/editor.rb @@ -0,0 +1,83 @@ +class IMICFPS + class Editor < Entity + + attr_accessor :speed + attr_reader :bound_model, :first_person_view + + def setup + bind_model + @speed = 2.5 # meter's per second + @running_speed = 5.0 # meter's per second + @turn_speed = 50.0 + @old_speed = @speed + @mass = 72 # kg + @first_person_view = true + @visible = false + @drag = 0.9 + + end + + def update + super + + @position += @velocity * window.dt + @velocity *= @drag + end + + def relative_speed + InputMapper.down?(:sprint) ? @running_speed : @speed + end + + def relative_y_rotation + @orientation.y * -1 + end + + def forward + @velocity.z += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.y -= Math.sin(@orientation.x * Math::PI / 180) * relative_speed + @velocity.x -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + end + + def backward + @velocity.z -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + end + + def strife_left + @velocity.z += Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x += Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + end + + def strife_right + @velocity.z -= Math.sin(relative_y_rotation * Math::PI / 180) * relative_speed + @velocity.x -= Math.cos(relative_y_rotation * Math::PI / 180) * relative_speed + end + + def turn_left + @orientation.y += @turn_speed * delta_time + end + + def turn_right + @orientation.y -= @turn_speed * delta_time + end + + def ascend + @velocity.y += 1 * delta_time + end + alias :jump :ascend + + def descend + @velocity.y -= 1 * delta_time + end + + def toggle_first_person_view + @first_person_view = !@first_person_view + @visible = !@first_person_view + end + + def turn_180 + @orientation.y = @orientation.y + 180 + @orientation.y %= 360 + end + end +end diff --git a/lib/hud/widget.rb b/lib/hud/widget.rb index 044c47a..8350481 100644 --- a/lib/hud/widget.rb +++ b/lib/hud/widget.rb @@ -2,19 +2,31 @@ class IMICFPS class HUD class Widget include CommonMethods - attr_reader :options + # Widget margin from screen edge + # or how much widget is pushed in + def self.margin + @@margin ||= 10 + end + + def self.padding=(n) + @@padding = n + end + + # Widget element padding + def self.padding + @@margin ||= 10 + end + + def self.padding=(n) + @@padding = n + end + + attr_reader :options def initialize(options = {}) @options = options @player = options[:player] - # Widget margin from screen edge - # or how much widget is pushed in - @margin = 10 - - # Widget element padding - @padding = 10 - setup end diff --git a/lib/hud/widgets/ammo.rb b/lib/hud/widgets/ammo.rb index 87b6155..ce24d5e 100644 --- a/lib/hud/widgets/ammo.rb +++ b/lib/hud/widgets/ammo.rb @@ -8,8 +8,8 @@ class IMICFPS def draw Gosu.draw_rect( - @text.x - @padding, @text.y - @padding, - @text.width + @padding * 2, @text.height + @padding * 2, + @text.x - Widget.padding, @text.y - Widget.padding, + @text.width + Widget.padding * 2, @text.height + Widget.padding * 2, @background ) @text.draw @@ -21,8 +21,8 @@ class IMICFPS @text.text = "#{random}/999" end - @text.x = window.width - (@margin + @text.width + @padding) - @text.y = window.height - (@margin + @text.height + @padding) + @text.x = window.width - (Widget.margin + @text.width + Widget.padding) + @text.y = window.height - (Widget.margin + @text.height + Widget.padding) end end end diff --git a/lib/hud/widgets/chat_history.rb b/lib/hud/widgets/chat_history.rb index 6afaf76..b38a4fe 100644 --- a/lib/hud/widgets/chat_history.rb +++ b/lib/hud/widgets/chat_history.rb @@ -7,7 +7,7 @@ class IMICFPS @text = CyberarmEngine::Text.new( "", size: 16, - x: @margin, y: @margin, z: 45, + x: Widget.margin, y: Widget.margin, z: 45, shadow_size: 0.5, shadow_alpha: 0, shadow_color: Gosu::Color::WHITE, diff --git a/lib/hud/widgets/health.rb b/lib/hud/widgets/health.rb index b60cf94..f52baee 100644 --- a/lib/hud/widgets/health.rb +++ b/lib/hud/widgets/health.rb @@ -17,10 +17,10 @@ class IMICFPS def draw @text.draw fill_quad( - window.width / 2 - @width / 2, @spacer + @margin, # TOP LEFT - window.width / 2 + @width / 2, @spacer + @margin, # TOP RIGHT - window.width / 2 + @width / 2 - @slant, @spacer + @margin + @height, # BOTTOM RIGHT - window.width / 2 - @width / 2 + @slant, @spacer + @margin + @height, # BOTTOM LEFT + window.width / 2 - @width / 2, @spacer + Widget.margin, # TOP LEFT + window.width / 2 + @width / 2, @spacer + Widget.margin, # TOP RIGHT + window.width / 2 + @width / 2 - @slant, @spacer + Widget.margin + @height, # BOTTOM RIGHT + window.width / 2 - @width / 2 + @slant, @spacer + Widget.margin + @height, # BOTTOM LEFT @color ) @@ -31,10 +31,10 @@ class IMICFPS # Current Health fill_quad( - window.width / 2 - @width / 2, @spacer + @margin, # TOP LEFT - (window.width / 2 - @width / 2) + @width * @health, @spacer + @margin, # TOP RIGHT - bottom_right, @spacer + @margin + @height, # BOTTOM RIGHT - window.width / 2 - @width / 2 + @slant, @spacer + @margin + @height, # BOTTOM LEFT + window.width / 2 - @width / 2, @spacer + Widget.margin, # TOP LEFT + (window.width / 2 - @width / 2) + @width * @health, @spacer + Widget.margin, # TOP RIGHT + bottom_right, @spacer + Widget.margin + @height, # BOTTOM RIGHT + window.width / 2 - @width / 2 + @slant, @spacer + Widget.margin + @height, # BOTTOM LEFT @shield ) end @@ -43,7 +43,7 @@ class IMICFPS percentage = "#{(@health * 100).round}".rjust(3, "0") @text.text = "[Health #{percentage}%]" @text.x = window.width / 2 - @text.width / 2 - @text.y = @spacer + @margin + @height / 2 - @text.height / 2 + @text.y = @spacer + Widget.margin + @height / 2 - @text.height / 2 @health += 0.1 * window.dt @health = 0 if @health > 1.0 diff --git a/lib/hud/widgets/radar.rb b/lib/hud/widgets/radar.rb index a7426d0..e821d51 100644 --- a/lib/hud/widgets/radar.rb +++ b/lib/hud/widgets/radar.rb @@ -8,31 +8,31 @@ class IMICFPS @text = Text.new("RADAR", size: 18, mode: :add, font: MONOSPACE_FONT) @image = Gosu::Image.new("#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/default.png", retro: true) - @scale = (@size - @padding * 2.0) / @image.width + @scale = (@size - Widget.padding * 2.0) / @image.width end def draw Gosu.draw_rect( - @margin, window.height - (@size + @margin), + Widget.margin, window.height - (@size + Widget.margin), @size, @size, @border_color ) Gosu.draw_rect( - @margin + @padding, window.height - (@size + @margin) + @padding, - @size - @padding * 2, @size - @padding * 2, + Widget.margin + Widget.padding, window.height - (@size + Widget.margin) + Widget.padding, + @size - Widget.padding * 2, @size - Widget.padding * 2, @radar_color ) - - @image.draw(@margin + @padding, window.height - (@size + @margin) + @padding, 46, @scale, @scale, 0x88ffffff) + + @image.draw(Widget.margin + Widget.padding, window.height - (@size + Widget.margin) + Widget.padding, 46, @scale, @scale, 0x88ffffff) @text.draw end def update @text.text = "RADAR: X #{@player.position.x.round(1)} Y #{@player.position.y.round(1)} Z #{@player.position.z.round(1)}" - @text.x = @margin + @size / 2 - @text.width / 2 - @text.y = window.height - (@margin + @size + @text.height) + @text.x = Widget.margin + @size / 2 - @text.width / 2 + @text.y = window.height - (Widget.margin + @size + @text.height) end end end diff --git a/lib/hud/widgets/score_board.rb b/lib/hud/widgets/score_board.rb index 51147fb..e2a3249 100644 --- a/lib/hud/widgets/score_board.rb +++ b/lib/hud/widgets/score_board.rb @@ -7,7 +7,7 @@ class IMICFPS @text = CyberarmEngine::Text.new( "", size: 16, - x: @margin, y: @margin, z: 45, + x: Widget.margin, y: Widget.margin, z: 45, shadow: true, shadow_size: 0.5, shadow_alpha: 30, @@ -24,7 +24,7 @@ class IMICFPS end def update - @text.x = window.width - (@text.width + @margin) + @text.x = window.width - (@text.width + Widget.margin) end def generate_random_data diff --git a/lib/hud/widgets/squad.rb b/lib/hud/widgets/squad.rb index 475c1d5..88c8fbc 100644 --- a/lib/hud/widgets/squad.rb +++ b/lib/hud/widgets/squad.rb @@ -13,8 +13,8 @@ class IMICFPS end def update - @text.x = @margin + @size + @padding - @text.y = window.height - (@margin + @text.height) + @text.x = Widget.margin + @size + Widget.padding + @text.y = window.height - (Widget.margin + @text.height) end end end diff --git a/lib/managers/input_mapper.rb b/lib/managers/input_mapper.rb index 50bb6e3..830c670 100644 --- a/lib/managers/input_mapper.rb +++ b/lib/managers/input_mapper.rb @@ -83,18 +83,13 @@ class IMICFPS end def self.action(key) - answer = nil - @@keymap.detect do |action, value| + @@keymap.select do |action, value| if value.is_a?(Array) - answer = action if value.include?(key) + action if value.include?(key) else - if value == key - answer = action - end + action if value == key end - end - - answer + end.map { |keymap| keymap.first.is_a?(Symbol) ? keymap.first : keymap.first.first } end def self.reset_keys diff --git a/lib/tools/map_editor/lib/editor.rb b/lib/tools/map_editor/lib/editor.rb index 0434486..211662a 100644 --- a/lib/tools/map_editor/lib/editor.rb +++ b/lib/tools/map_editor/lib/editor.rb @@ -10,6 +10,8 @@ class IMICFPS Publisher.new @map = Map.new( map_parser: @options[:map_parser] ) @camera = PerspectiveCamera.new( position: Vector.new, aspect_ratio: window.aspect_ratio ) + @editor = IMICFPS::Editor.new( manifest: Manifest.new(package: "base", name: "editor") ) + @camera_controller = CameraController.new(camera: @camera, entity: @editor) @crosshair = Crosshair.new @map.setup @@ -24,8 +26,26 @@ class IMICFPS def update super Publisher.instance.publish(:tick, Gosu.milliseconds - window.delta_time) + + control_editor + @map.update - @camera.update + @camera_controller.update + end + + def control_editor + InputMapper.keys.each do |key, pressed| + next unless pressed + + actions = InputMapper.action(key) + next unless actions + + actions.each do |action| + @editor.send(action) if @editor.respond_to?(action) + end + end + + @editor.update end def button_down(id) @@ -39,6 +59,8 @@ class IMICFPS InputMapper.keydown(id) Publisher.instance.publish(:button_down, nil, id) + @camera_controller.button_down(id) + @map.entities.each do |entity| entity.button_down(id) if defined?(entity.button_down) end @@ -52,7 +74,7 @@ class IMICFPS entity.button_up(id) if defined?(entity.button_up) end - @camera.button_up(id) + @camera_controller.button_up(id) end end end