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 😂

This commit is contained in:
2020-07-18 15:54:00 -05:00
parent f6e4a509fd
commit 1d7cd19b41
9 changed files with 282 additions and 22 deletions

90
lib/camera_controller.rb Normal file
View File

@@ -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

View File

@@ -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
end

View File

@@ -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

View File

@@ -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
end

21
lib/hud/widgets/squad.rb Normal file
View File

@@ -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

View File

@@ -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)

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="crosshair.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
id="svg140"
version="1.1"
viewBox="0 0 33.866666 33.866668"
height="128"
width="128">
<defs
id="defs134" />
<sodipodi:namedview
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:window-height="1010"
inkscape:window-width="1920"
inkscape:showpageshadow="false"
units="px"
showgrid="true"
inkscape:document-rotation="0"
inkscape:current-layer="layer1"
inkscape:document-units="px"
inkscape:cy="67.12637"
inkscape:cx="91.154586"
inkscape:zoom="5.6"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base">
<inkscape:grid
empspacing="8"
id="grid162"
type="xygrid" />
</sodipodi:namedview>
<metadata
id="metadata137">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
d="M 16.933332,8.46667 A 8.4666841,8.4666841 0 0 0 8.466665,16.93333 8.4666841,8.4666841 0 0 0 16.933332,25.4 8.4666841,8.4666841 0 0 0 25.399998,16.93333 8.4666841,8.4666841 0 0 0 16.933332,8.46667 Z m -0.03824,0.52916 a 7.9375172,7.9375172 0 0 1 0.03824,0 7.9375172,7.9375172 0 0 1 7.9375,7.9375 7.9375172,7.9375172 0 0 1 -7.9375,7.9375 7.9375172,7.9375172 0 0 1 -7.9375,-7.9375 7.9375172,7.9375172 0 0 1 7.89926,-7.9375 z"
style="fill:#ffffff;stroke:none;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
id="path1466" />
<circle
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
r="0.52916473"
cy="16.933329"
cx="16.933331"
id="path1475"
style="fill:#ffffff;stroke:none;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
sodipodi:nodetypes="cc"
id="path1479"
d="M 7.937498,16.93333 H 2.645828"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 31.220839,16.93333 H 25.929168"
id="path1490"
sodipodi:nodetypes="cc" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 10.572318,10.57231 6.830539,6.83054"
id="path1492"
sodipodi:nodetypes="cc" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
sodipodi:nodetypes="cc"
id="path1494"
d="m 27.036128,27.03612 -3.74178,-3.74177"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
sodipodi:nodetypes="cc"
id="path1496"
d="m 16.933338,7.93749 -10e-6,-5.29167"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
style="fill:none;stroke:#ffffff;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 16.933338,31.22084 -10e-6,-5.29167"
id="path1498"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB