From 1d7cd19b4124eaa810c1fcfdc86552e2f462cc73 Mon Sep 17 00:00:00 2001 From: Cyberarm Date: Sat, 18 Jul 2020 15:54:00 -0500 Subject: [PATCH] Added more hud widgets for showing squadmates and crosshair, added crosshair image and source svg, hackish fix to make renderer resize on windows size change, added CameraController camera control is back in :joy: --- lib/camera_controller.rb | 90 ++++++++++++++++++++++++ lib/hud.rb | 7 +- lib/hud/widgets/crosshair.rb | 36 ++++++++++ lib/hud/widgets/radar.rb | 8 ++- lib/hud/widgets/squad.rb | 21 ++++++ lib/states/game_states/game.rb | 22 ++---- lib/window.rb | 2 +- static/crosshairs/crosshair.png | Bin 0 -> 1774 bytes svg/crosshairs/crosshair.svg | 118 ++++++++++++++++++++++++++++++++ 9 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 lib/camera_controller.rb create mode 100644 lib/hud/widgets/crosshair.rb create mode 100644 lib/hud/widgets/squad.rb create mode 100644 static/crosshairs/crosshair.png create mode 100644 svg/crosshairs/crosshair.svg diff --git a/lib/camera_controller.rb b/lib/camera_controller.rb new file mode 100644 index 0000000..45af8c2 --- /dev/null +++ b/lib/camera_controller.rb @@ -0,0 +1,90 @@ +class IMICFPS + class CameraController + include CommonMethods + + def initialize(mode: :fpv, camera:, entity:) + # :fpv - First Person View + # :tpv - Third Person View + @mode = mode + @camera = camera + @entity = entity + + @distance = 4 + @origin_distance = @distance + @constant_pitch = 0 + + window.mouse_x, window.mouse_y = window.width / 2, window.height / 2 + + @true_mouse = Point.new(window.width / 2, window.height / 2) + @mouse_sensitivity = 20.0 # Less is faster, more is slower + @mouse_captured = true + @mouse_checked = 0 + end + + def distance_from_object + @distance + end + + def horizontal_distance_from_object + distance_from_object * Math.cos(@constant_pitch) + end + + def vertical_distance_from_object + distance_from_object * Math.sin(@constant_pitch) + end + + def position_camera + if defined?(@entity.first_person_view) + if @entity.first_person_view + @distance = 0 + else + @distance = @origin_distance + end + end + + x_offset = horizontal_distance_from_object * Math.sin(@entity.orientation.y.degrees_to_radians) + z_offset = horizontal_distance_from_object * Math.cos(@entity.orientation.y.degrees_to_radians) + + eye_height = @entity.bounding_box.max.y + + @camera.position.x = @entity.position.x - x_offset + @camera.position.y = @entity.position.y + eye_height + @camera.position.z = @entity.position.z - z_offset + + @camera.orientation.y = 180 - @entity.orientation.y + end + + def update + position_camera + + if @mouse_captured + delta = Float(@true_mouse.x - self.mouse_x) / (@mouse_sensitivity * @camera.field_of_view) * 70 + @camera.orientation.y -= delta + @camera.orientation.y %= 360.0 + + @camera.orientation.x -= Float(@true_mouse.y - window.mouse_y) / (@mouse_sensitivity * @camera.field_of_view) * 70 + @camera.orientation.x = @camera.orientation.x.clamp(-90.0, 90.0) + + @entity.orientation.y += delta + @entity.orientation.y %= 360.0 + + window.mouse_x = window.width / 2 if window.mouse_x <= 1 || window.mouse_x >= window.width-1 + window.mouse_y = window.height / 2 if window.mouse_y <= 1 || window.mouse_y >= window.height-1 + @true_mouse.x, @true_mouse.y = window.mouse_x, window.mouse_y + end + end + + def button_down(id) + case id + when Gosu::KB_LEFT_ALT, Gosu::KB_RIGHT_ALT + @mouse_captured = false + window.needs_cursor = true + when Gosu::MS_LEFT, Gosu::MS_MIDDLE, Gosu::MS_RIGHT + @mouse_captured = true + window.needs_cursor = false + end + end + + def button_up(id); end + end +end diff --git a/lib/hud.rb b/lib/hud.rb index 83e902a..5592e28 100644 --- a/lib/hud.rb +++ b/lib/hud.rb @@ -6,6 +6,8 @@ class IMICFPS @health = HealthWidget.new({ player: player }) @chat_history = ChatHistoryWidget.new({ player: player }) @score_board = ScoreBoardWidget.new({ player: player }) + @squad = SquadWidget.new( { player: player } ) + @crosshair = CrosshairWidget.new( { player: player } ) @hud_elements = [ @ammo, @@ -13,6 +15,9 @@ class IMICFPS @health, @chat_history, @score_board, + @squad, + + @crosshair, ] end @@ -24,4 +29,4 @@ class IMICFPS @hud_elements.each(&:update) end end -end \ No newline at end of file +end diff --git a/lib/hud/widgets/crosshair.rb b/lib/hud/widgets/crosshair.rb new file mode 100644 index 0000000..95d7cc3 --- /dev/null +++ b/lib/hud/widgets/crosshair.rb @@ -0,0 +1,36 @@ +class IMICFPS + class HUD + class CrosshairWidget < HUD::Widget + def setup + @scale = 0.75 + @color = Gosu::Color.new(0x44ffffff) + + @image = Gosu::Image.new("#{GAME_ROOT_PATH}/static/crosshairs/crosshair.png") + + @last_changed_time = Gosu.milliseconds + @change_interval = 1_500 + + @colors = [0xffffffff, 0xaaffffff, 0x88ffffff, 0x22ffffff] + end + + def draw + @image.draw( + window.width / 2 - (@image.width * @scale) / 2, + window.height / 2 - (@image.height * @scale) / 2, + 46, + @scale, + @scale, + @color + ) + end + + def update + if Gosu.milliseconds - @last_changed_time >= @change_interval + @last_changed_time = Gosu.milliseconds + + @color = @colors.sample + end + end + end + end +end diff --git a/lib/hud/widgets/radar.rb b/lib/hud/widgets/radar.rb index 4387854..a7426d0 100644 --- a/lib/hud/widgets/radar.rb +++ b/lib/hud/widgets/radar.rb @@ -7,6 +7,8 @@ class IMICFPS @radar_color = Gosu::Color.new(0x88212121) @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 end def draw @@ -21,15 +23,17 @@ class IMICFPS @size - @padding * 2, @size - @padding * 2, @radar_color ) + + @image.draw(@margin + @padding, window.height - (@size + @margin) + @padding, 46, @scale, @scale, 0x88ffffff) @text.draw end def update - @text.text = "RADAR: X #{@player.position.x.round(1)} Y #{@player.position.z.round(1)}" + @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) end end end -end \ No newline at end of file +end diff --git a/lib/hud/widgets/squad.rb b/lib/hud/widgets/squad.rb new file mode 100644 index 0000000..475c1d5 --- /dev/null +++ b/lib/hud/widgets/squad.rb @@ -0,0 +1,21 @@ +class IMICFPS + class HUD + class SquadWidget < HUD::Widget + def setup + @size = 288 # RADAR size + @color = Gosu::Color.new(0x8800aa00) + + @text = Text.new("MATE\nTinyTanker\nOther Player Dude\nHuman 0xdeadbeef", size: 18, mode: :add, font: MONOSPACE_FONT, color: @color) + end + + def draw + @text.draw + end + + def update + @text.x = @margin + @size + @padding + @text.y = window.height - (@margin + @text.height) + end + end + end +end diff --git a/lib/states/game_states/game.rb b/lib/states/game_states/game.rb index c684ce2..8d9e3b9 100644 --- a/lib/states/game_states/game.rb +++ b/lib/states/game_states/game.rb @@ -8,17 +8,15 @@ class IMICFPS @player = @map.find_entity_by(name: "character") @camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio ) + @camera_controller = CameraController.new(mode: :first_person, camera: @camera, entity: @player) @director = Networking::Director.new @director.load_map(map_parser: @options[:map_parser]) @connection = Networking::Connection.new(address: "localhost", port: Networking::DEFAULT_SERVER_PORT) @connection.connect - @crosshair = Crosshair.new @hud = HUD.new(@player) - @text = Text.new("Pending...", x: 10, y: 22, z: 1, size: 18, font: "DejaVu Sans", shadow_color: Gosu::Color::BLACK) - if ARGV.join.include?("--playdemo") @demo = Demo.new(camera: @camera, player: @player, demo: "./demo.dat", mode: :play) if File.exist?("./demo.dat") @@ -30,9 +28,7 @@ class IMICFPS def draw @map.render(@camera) - @crosshair.draw @hud.draw - @text.draw end def update @@ -40,17 +36,12 @@ class IMICFPS control_player @hud.update + @camera_controller.update @connection.update @director.tick(window.dt) @map.update - if window.config.get(:debug_options, :stats) - @text.text = update_text - else - @text.text = "" - end - @demo.update if @demo end @@ -60,13 +51,6 @@ OpenGL Vendor: #{glGetString(GL_VENDOR)} OpenGL Renderer: #{glGetString(GL_RENDERER)} OpenGL Version: #{glGetString(GL_VERSION)} OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)} - -Camera Pitch: #{@camera.orientation.x.round(2)} Yaw: #{@camera.orientation.y.round(2)} Roll #{@camera.orientation.z.round(2)} -Camera X: #{@camera.position.x.round(2)} Y: #{@camera.position.y.round(2)} Z: #{@camera.position.z.round(2)} -Camera Field Of View: #{@camera.field_of_view} -Camera Mouse Sesitivity: nil - -Player X: #{@player.position.x.round(2)} Y: #{@player.position.y.round(2)} Z: #{@player.position.z.round(2)}" eos end @@ -88,6 +72,7 @@ eos return end @demo.button_down(id) if @demo + @camera_controller.button_down(id) InputMapper.keydown(id) Publisher.instance.publish(:button_down, nil, id) @@ -99,6 +84,7 @@ eos def button_up(id) @demo.button_up(id) if @demo + @camera_controller.button_up(id) InputMapper.keyup(id) Publisher.instance.publish(:button_up, nil, id) diff --git a/lib/window.rb b/lib/window.rb index e572ded..6e12689 100644 --- a/lib/window.rb +++ b/lib/window.rb @@ -64,7 +64,7 @@ class IMICFPS _canvas_size = Vector.new(self.width, self.height) if @canvas_size != _canvas_size - @renderer.canvas_size_changed + @renderer = Renderer.new#@renderer.canvas_size_changed @canvas_size = _canvas_size end end diff --git a/static/crosshairs/crosshair.png b/static/crosshairs/crosshair.png new file mode 100644 index 0000000000000000000000000000000000000000..12f4b3da8480dc83e382456a8f02665b38e5749a GIT binary patch literal 1774 zcmZ9Nc{m$*8pnT$V+5^ZsZvZtI*xARm?=_SSEG_TmpWpU*pSvyG@&7=R8xjlMN%~* zsH3h`S7@{d*&25oZ7I>TD2OAAUPK?yB+QUT{ zu4OLScLvRyK^y)P8}kjm;$1#g7O6LwfHX_ICUWNHFES8!V$+M0+o=3aRx1jD-wADj1)tqP|RpV&q93Vm=W%M};QogHHZoqxhb86@=$k@FXavkBMqUv=tB zO?Mm87p)p!q=xEsdlw{_4tg{OeL$WV35Kg-{?W*#vll~&yl zwB}&!NOJ)Wbv6$FJvO+Rd(}{Facx|&QF6}^A0i*#U?d`jziu#MNQ)ki)a`5z)rhx( zUB|1i63Nd6!fV%&_fS0>ZHcMrS{hH+(XqTq8Y?KI?@IKqflc`AmFXf$r(=nk55e=} z50Cu!t~H~hi_t5&$Wu#N7mMZ|h+5C6b@5vw`OSN8O}J5&qKVVwLd0L%D_(!=vd46K zS&qB!p8c_2@4H^kvrBGesY)Zfn@FQ$Z>(+K=~2dWO?a1cMW1>1^aAVR zjXMatXBJAG^RKf^c$9L{z4Lz#O(idDE5b_#V7S8(a%@ot1}nI7f~KKbRXSaYi1A7bKL=b3oMI(0^lVD%-;%GwnO7OqIqr5S7fwxjvL z@}@am$a>&qlOLWu4ow`mT`i+7z}b%G0eX$$gdP*nxX~(s;OV2pG$DW8k3(KXJhmZm z8cCwyc8_HnUB7WRol*3KCH}!uMTdkUPYALDh@-ylD57llCVq$n*Fl5r(yDP)+Hjei zssZtN1rmQ`GePV7&9scg7K@PNc2SBW6rN^%LHspyq(vy1oq);GJ{RGNO%jwz#Qrogf*Vq01x@t@hQYmK7K>#Mx%%+Wr{HuoTm?bz}!NqCr% zF1a-0h>og)4%L!viE=xx0X3QWg0$V<`SSV3gV~3tBlC3ahdKC)qoFCLeebQ4iMvnX zV=@&|e}wUyuM*HiaKVh zF53^O2bvA$EG%C~`pTl5oqlA@*Aw?9j-^3uz?@dtp|T{9 zmIpat_2X!QhM*eQT^`+9^6Cq)68hCKMcm4qMT6wMlm0QxQ`n6?Cw@;s>s^5yJY#tv zY=NfylY8Y7sOhb5%U$akdD*{xsLU-AHgUF=Xsm{nJ*onfiVK|)On`*$LzW51$Hv^u zD6~w3#*g5XT0HZ?Ul~vh2eGjyVGaxa2ipJ7@jsG3e5Bj&moINzE!FMze-*$vdte%z H2 + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + +