finally built the crosshair of my dreams

This commit is contained in:
derek
2025-03-18 15:27:31 -05:00
parent 891ae8a7f2
commit 95a2c9da95
11 changed files with 212 additions and 160 deletions

40
assets/crosshair.tscn Normal file
View File

@@ -0,0 +1,40 @@
[gd_scene load_steps=5 format=3 uid="uid://8kmjybgrobj1"]
[ext_resource type="Texture2D" uid="uid://dumgg4fq1ngbj" path="res://assets/UI/Crosshair/SVG/reticle_outer.svg" id="1_5bf65"]
[ext_resource type="Texture2D" uid="uid://cpe2ehq1vtj25" path="res://assets/UI/Crosshair/SVG/reticle_inner.svg" id="2_yawbq"]
[ext_resource type="Texture2D" uid="uid://h2tp42xntorm" path="res://assets/UI/Crosshair/SVG/Stamina_White.svg" id="3_spf5y"]
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_ytfhs"]
[node name="Crosshair" type="Control"]
layout_mode = 3
anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="Crosshair" type="TextureRect" parent="." groups=["hud"]]
layout_mode = 0
offset_right = 396.0
offset_bottom = 396.0
texture = ExtResource("1_5bf65")
expand_mode = 3
stretch_mode = 4
[node name="CrosshairCenter" type="TextureRect" parent="." groups=["hud"]]
layout_mode = 0
offset_right = 396.0
offset_bottom = 396.0
scale = Vector2(0.02, 0.02)
texture = ExtResource("2_yawbq")
expand_mode = 3
stretch_mode = 4
[node name="StaminaBar" type="TextureProgressBar" parent="."]
material = SubResource("CanvasItemMaterial_ytfhs")
layout_mode = 0
offset_right = 370.0
offset_bottom = 370.0
scale = Vector2(0.3, 0.3)
value = 49.0
fill_mode = 5
texture_progress = ExtResource("3_spf5y")

View File

@@ -40,7 +40,7 @@ class_name gamemode
func apply_weapon_penalty():
for i in GameGlobals.ammo_reserve:
GameGlobals.ammo_reserve[i] *= ammo_drop_percentage
GameGlobals.ammo_reserve[i] = int(GameGlobals.ammo_reserve[i] * ammo_drop_percentage)
match weapon_penalty:
0: #Drop All
GameGlobals.held_guns = []

View File

@@ -1,10 +1,8 @@
[gd_scene load_steps=9 format=3 uid="uid://br882tlh3cfwu"]
[gd_scene load_steps=6 format=3 uid="uid://br882tlh3cfwu"]
[ext_resource type="Script" uid="uid://dfv2m81iew3ia" path="res://scripts/hud.gd" id="1_7hukm"]
[ext_resource type="Theme" uid="uid://clek42ofxr45f" path="res://DefaultTheme.tres" id="1_22trs"]
[ext_resource type="Texture2D" uid="uid://dumgg4fq1ngbj" path="res://assets/UI/Crosshair/SVG/reticle_outer.svg" id="3_mgrwc"]
[ext_resource type="Texture2D" uid="uid://cpe2ehq1vtj25" path="res://assets/UI/Crosshair/SVG/reticle_inner.svg" id="4_61fkt"]
[ext_resource type="Texture2D" uid="uid://h2tp42xntorm" path="res://assets/UI/Crosshair/SVG/Stamina_White.svg" id="4_ooaul"]
[ext_resource type="Script" uid="uid://cfou02ggxj80n" path="res://scripts/dynamic_crosshair.gd" id="5_1xsix"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_2hn4h"]
bg_color = Color(1, 1, 1, 0.129412)
@@ -20,8 +18,6 @@ expand_margin_bottom = 10.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_axtce"]
bg_color = Color(1, 1, 1, 0.498039)
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_ytfhs"]
[node name="HUD" type="Control"]
light_mask = 2
visibility_layer = 2
@@ -39,53 +35,20 @@ anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="StaminaBar2" type="ProgressBar" parent="StaticItems"]
custom_minimum_size = Vector2(30, 10)
[node name="DynamicCrosshair" type="Control" parent="StaticItems"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = 606.0
offset_top = 331.0
offset_right = 661.0
offset_bottom = 341.0
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
rotation = -1.5708
theme = ExtResource("1_22trs")
theme_override_styles/background = SubResource("StyleBoxFlat_2hn4h")
theme_override_styles/fill = SubResource("StyleBoxFlat_axtce")
value = 35.29
show_percentage = false
[node name="Crosshair" type="TextureRect" parent="StaticItems" groups=["hud"]]
layout_mode = 0
offset_right = 396.0
offset_bottom = 396.0
texture = ExtResource("3_mgrwc")
expand_mode = 3
stretch_mode = 4
[node name="CrosshairCenter" type="TextureRect" parent="StaticItems" groups=["hud"]]
layout_mode = 0
offset_right = 396.0
offset_bottom = 396.0
scale = Vector2(0.02, 0.02)
texture = ExtResource("4_61fkt")
expand_mode = 3
stretch_mode = 4
[node name="StaminaBar" type="TextureProgressBar" parent="StaticItems"]
material = SubResource("CanvasItemMaterial_ytfhs")
layout_mode = 0
offset_right = 370.0
offset_bottom = 370.0
scale = Vector2(0.3, 0.3)
value = 49.0
fill_mode = 5
texture_progress = ExtResource("4_ooaul")
script = ExtResource("5_1xsix")
[node name="WobbleItems" type="Control" parent="."]
layout_mode = 1

View File

@@ -23,6 +23,7 @@ SignalBus="*res://scripts/signal_bus.gd"
RigidbodyGeneric="*res://scripts/rigidbody_generic.gd"
GameGlobals="*res://scripts/game_globals.gd"
HelperFuncs="*res://scripts/HelperFuncs.gd"
ColorSwatch="*res://scripts/ColorSwatch.gd"
[display]

7
scripts/ColorSwatch.gd Normal file
View File

@@ -0,0 +1,7 @@
extends Node
const FULL_WHITE = Color(1, 1, 1, 1)
const TRANSPARENT = Color(1, 1, 1, 0)
const RED_COLOR = Color(1, 0, 0)
const ORANGE_COLOR = Color(0.822, 0.318, 0.086)
const GREEN_COLOR = Color(0.643, 0.82, 0.0)

View File

@@ -0,0 +1 @@
uid://bakejlk87jsp6

View File

@@ -0,0 +1,94 @@
extends Control
@onready var hud: Control = $"../.."
@onready var player = get_tree().current_scene.player
#INNER RING
var inner_ring_radius : float = 5
#OUTER RING
const OUTER_RING_START_RADIUS = 40
const SIZE_SNAP_AMT = 20
const SIZE_RETURN_AMT = 2
var outer_ring_radius : float = 50
var outer_ring_width : float = 4
var crosshair_color = ColorSwatch.FULL_WHITE
#STAMINA WHEEL
const STAMINA_RING_WIDTH = 15
var stamina_bar_color = ColorSwatch.FULL_WHITE
var stamina_alpha : float = 1.0
var crosshair_target : float = 0.0
func _ready() -> void:
SignalBus.shot_fired.connect(crosshair_size_change)
SignalBus.player_hit.connect(player_hit)
func _process(delta: float) -> void:
if hud.player != null:
position = hud.viewportCenter
var velocity_adjust = clamp(hud.player.velocity.length() * .1,1,3)
# Crosshair
outer_ring_radius = lerp(outer_ring_radius,(OUTER_RING_START_RADIUS + crosshair_target) * velocity_adjust,delta * SIZE_SNAP_AMT)
crosshair_target = lerp(crosshair_target,0.0,delta * SIZE_RETURN_AMT)
#if stamina is 25%, change colors to red
var crosshair_alpha = outer_ring_fade()
crosshair_color = lerp(crosshair_color,Color(crosshair_color_target().r,crosshair_color_target().g,crosshair_color_target().b,crosshair_alpha),(delta * 5)/Engine.time_scale)
stamina_alpha = lerp(stamina_alpha,stamina_fade(),(delta * 5)/Engine.time_scale)
stamina_bar_color = Color(crosshair_color.r,crosshair_color.g,crosshair_color.b,stamina_alpha)
queue_redraw()
func _draw() -> void:
#INNER RING
draw_circle(Vector2.ZERO, inner_ring_radius, crosshair_color)
#OUTER RING
draw_circle(Vector2.ZERO, outer_ring_radius, crosshair_color,false,outer_ring_width,true)
if hud.player != null:
#STAMINA WHEEL
var stam_offset = -TAU * .25
var stam_start_angle = 0 + stam_offset
var stam_end_angle = TAU * (hud.player.remaining_stamina/hud.level_control.gamemode.max_stamina) + stam_offset
draw_arc(Vector2(0,0),outer_ring_radius,stam_start_angle,stam_end_angle,100,stamina_bar_color,STAMINA_RING_WIDTH,true)
func outer_ring_fade() -> float:
#fades the outer ring when the gun cannot fire or there is no gun
if hud.player.gun == null:
return 0.0
else :
if hud.player.gun.can_fire():
return 1.0
else:
return .5
func stamina_fade() -> float:
var stam_percent = hud.player.remaining_stamina/hud.level_control.gamemode.max_stamina
if stam_percent >= .99:
return 0.0
else:
return 1.0
func crosshair_color_target():
var stam_percent = hud.player.remaining_stamina/hud.level_control.gamemode.max_stamina
if stam_percent <= .1:
return ColorSwatch.RED_COLOR
else:
return ColorSwatch.FULL_WHITE
func crosshair_size_change():
crosshair_target += 10
func player_hit():
crosshair_size_change()

View File

@@ -0,0 +1 @@
uid://cfou02ggxj80n

View File

@@ -5,8 +5,8 @@ extends Control
## VIEWPORT
var viewportWidth
var viewportHeight
var viewportCenter
var current_stam_bar
var stam_bar_visible : bool = false
var interact_visible : bool = false
var health_bar_start_pos
@@ -16,8 +16,6 @@ var crosshair_target
@onready var level_control = get_tree().current_scene
@onready var player = level_control.player
@onready var stamina_bar: TextureProgressBar = $StaticItems/StaminaBar
@onready var stamina_bar_2: ProgressBar = $StaticItems/StaminaBar2
@onready var health_bar: ProgressBar = $WobbleItems/HealthBar
@onready var ammo_counter: HBoxContainer = $WobbleItems/GunInfo/VBoxContainer/AmmoCounter
@onready var gun_name: Label = $"WobbleItems/GunInfo/VBoxContainer/Gun Name"
@@ -25,34 +23,27 @@ var crosshair_target
@onready var ammo_reserve: Label = $WobbleItems/GunInfo/VBoxContainer/AmmoCounter/AmmoReserve
@onready var gun_info: MarginContainer = $WobbleItems/GunInfo
@onready var money: Label = $WobbleItems/Money
@onready var crosshair: TextureRect = $StaticItems/Crosshair
@onready var crosshair_center: TextureRect = $StaticItems/CrosshairCenter
@onready var pickup_item_indicator = preload("res://assets/pickup_item_indicator.tscn")
@onready var wobble_items: Control = $WobbleItems
const FULL_WHITE = Color(1, 1, 1, 1)
const TRANSPARENT = Color(1, 1, 1, 0)
const RED_COLOR = Color(1, 0, 0)
const ORANGE_COLOR = Color(0.822, 0.318, 0.086)
const GREEN_COLOR = Color(0, 0.608, 0.172)
const STAM_BAR_MAX_OPACITY = 1.0
const CROSSHAIR_SIZE = Vector2(40,40)
var pickup_notifs = []
var can_spawn = true
var dir_clamped = Vector2.ZERO
#HUD WOBBLE
var offset_dir = Vector2.ZERO
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
# Get Viewport size
viewportWidth = get_viewport().size.x
viewportHeight = get_viewport().size.y
viewportCenter = Vector2(viewportWidth/2,viewportHeight/2)
SignalBus.player_hit.connect(player_hit)
SignalBus.shot_fired.connect(crosshair_size_change)
money_count = GameGlobals.money
@@ -62,77 +53,50 @@ func _ready() -> void:
crosshair_target = CROSSHAIR_SIZE
if radial_stamina:
current_stam_bar = stamina_bar
stamina_bar_2.visible = false
else:
current_stam_bar = stamina_bar_2
stamina_bar.visible = false
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
player = level_control.player
if player != null:
# Crosshair
var velocity_adjust = clamp(player.velocity.length() * .1,1,3)
crosshair_target = lerp(crosshair_target,CROSSHAIR_SIZE,delta * 5)
crosshair.size = lerp(crosshair.size, crosshair_target * velocity_adjust,delta * 20)
crosshair.position = Vector2(viewportWidth/2,viewportHeight/2) + (crosshair.size/-2)
crosshair_center.position = Vector2(viewportWidth/2,viewportHeight/2) + (crosshair_center.scale * crosshair_center.size/-2)
stamina_bar.scale = (crosshair.size/CROSSHAIR_SIZE) * Vector2(.185,.185)
stamina_bar.position = Vector2(viewportWidth/2,viewportHeight/2) + (stamina_bar.scale * stamina_bar.size/-2)
#hide crosshair and ammo when no gun
if player.gun == null:
crosshair.visible = false
gun_info.visible = false
else:
crosshair.visible = true
gun_info.visible = true
#HEALTH
health_bar.value = GameGlobals.health
if GameGlobals.health <= 2:
change_color(health_bar,RED_COLOR,10,delta)
change_color(health_bar,ColorSwatch.RED_COLOR,10,delta)
health_bar.position = health_bar_start_pos + shake_element(15)
elif GameGlobals.health < ((level_control.gamemode.start_health / 2) + 1):
change_color(health_bar,ORANGE_COLOR,10,delta)
change_color(health_bar,ColorSwatch.ORANGE_COLOR,10,delta)
else:
change_color(health_bar,FULL_WHITE,10,delta)
change_color(health_bar,ColorSwatch.FULL_WHITE,10,delta)
#MONEY
if money_count < int(GameGlobals.money):
money_count += 1
change_color(money,GREEN_COLOR,10,delta)
change_color(money,ColorSwatch.GREEN_COLOR,10,delta)
elif money_count > int(GameGlobals.money):
change_color(money,RED_COLOR,10,delta)
change_color(money,ColorSwatch.RED_COLOR,10,delta)
money_count -= 1
else:
change_color(money,FULL_WHITE,10,delta)
change_color(money,ColorSwatch.FULL_WHITE,10,delta)
money.text = "$" + str(money_count)
if player.remaining_stamina/level_control.gamemode.max_stamina >= .99:
stam_bar_visible = false
else:
stam_bar_visible = true
current_stam_bar.value = player.remaining_stamina
if player.gun != null and player.gun.weapon_info.weapon_type == 0:
if GameGlobals.gun_ammo.has(player.gun.weapon_info.gun_name) and GameGlobals.gun_ammo[player.gun.weapon_info.gun_name] != null:
ammo_counter.visible = true
ammo_current.text = str(GameGlobals.gun_ammo[player.gun.weapon_info.gun_name]).pad_zeros(2)
lerp_color(ammo_current,RED_COLOR,FULL_WHITE,GameGlobals.gun_ammo[player.gun.weapon_info.gun_name],player.gun.weapon_info.max_ammo,.5)
lerp_color(ammo_current,ColorSwatch.RED_COLOR,ColorSwatch.FULL_WHITE,GameGlobals.gun_ammo[player.gun.weapon_info.gun_name],player.gun.weapon_info.max_ammo,.5)
else:
ammo_counter.visible = false
if GameGlobals.ammo_reserve.has(str(player.gun.weapon_info.bullet.ammo_type)):
ammo_reserve.text = str(GameGlobals.ammo_reserve[str(player.gun.weapon_info.bullet.ammo_type)]).pad_zeros(3)
lerp_color(ammo_reserve,RED_COLOR,FULL_WHITE,GameGlobals.ammo_reserve[str(player.gun.weapon_info.bullet.ammo_type)],player.gun.weapon_info.max_ammo*2,.5)
lerp_color(ammo_reserve,ColorSwatch.RED_COLOR,ColorSwatch.FULL_WHITE,GameGlobals.ammo_reserve[str(player.gun.weapon_info.bullet.ammo_type)],player.gun.weapon_info.max_ammo*2,.5)
else:
ammo_reserve.text = "-"
else:
fade_in_out(ammo_current,1,false,10,delta)
fade_in_out(ammo_reserve,1,false,10,delta)
fade_in_out(crosshair,1,false,10,delta)
if player.gun != null:
gun_name.text = player.gun.weapon_info.gun_name
gun_name.visible = true
@@ -140,12 +104,6 @@ func _process(delta: float) -> void:
gun_name.visible = false
if player.remaining_stamina < 25:
change_color(current_stam_bar,RED_COLOR,10,delta)
change_color(crosshair,RED_COLOR,10,delta)
else:
change_color(current_stam_bar,FULL_WHITE,10,delta)
change_color(crosshair,FULL_WHITE,10,delta)
if player.interact_ray.is_colliding():
if player.interact_ray.get_collider() != null:
@@ -156,32 +114,11 @@ func _process(delta: float) -> void:
else:
interact_visible = false
if interact_visible == true:
change_color(crosshair,GREEN_COLOR,10,delta)
else:
change_color(crosshair,FULL_WHITE,10,delta)
if player.ads:
if player.gun != null:
if player.gun.weapon_info.ads:
fade_in_out(crosshair,1,false,5,delta)
fade_in_out(current_stam_bar,.001,true,5,delta)
else:
fade_in_out(crosshair,1,true,5,delta)
else:
fade_in_out(crosshair,1,true,5,delta)
## FADE ELEMENTS IN AND OUT
fade_in_out(current_stam_bar,STAM_BAR_MAX_OPACITY,stam_bar_visible,5,delta)
## SPAWN NOTIFICATIONS
spawn_notifs()
wobble_items.position = hud_wobble(delta)
func crosshair_size_change():
crosshair_target += Vector2(20,20)
wobble_items.position = hud_wobble(delta/Engine.time_scale)
func shake_element(amount):
@@ -224,12 +161,12 @@ func spawn_notifs():
can_spawn = true
func player_hit():
crosshair_size_change()
pass
func hud_wobble(delta):
var viewport_height_adj = (get_viewport().size.y/1080)
var HUD_WOBBLE_MAX : float = 4 * viewport_height_adj
var HUD_WOBBLE_MAX : float = 40 * viewport_height_adj
var MOUSE_AMT = 1 * viewport_height_adj
var VELOCITY_AMT = 100 * viewport_height_adj
var HUD_MOVE_SPEED = 1 * viewport_height_adj
@@ -241,9 +178,9 @@ func hud_wobble(delta):
var dir_velocity = Vector2(-velocity_dir_transformed.x * velocity_lengh_clamped,velocity_dir_transformed.y * velocity_lengh_clamped)
#add movement
dir_clamped += clamp(dir_mouse + dir_velocity,Vector2(-HUD_WOBBLE_MAX,-HUD_WOBBLE_MAX),Vector2(HUD_WOBBLE_MAX,HUD_WOBBLE_MAX))
offset_dir += dir_mouse + dir_velocity
#return to zero over time
dir_clamped = lerp(dir_clamped,Vector2.ZERO,delta * HUD_RETURN_SPEED)
offset_dir = lerp(offset_dir,Vector2.ZERO,delta * HUD_RETURN_SPEED)
#apply offset
return dir_clamped
return offset_dir

View File

@@ -453,6 +453,7 @@ func _physics_process(delta):
if Input.is_action_just_pressed("interact"):
if held_item != null:
release_moveable()
else:
if interact_ray.is_colliding():
var body = interact_ray.get_collider()
if interact_ray.get_collider().get_class() == "RigidBody3D":

View File

@@ -103,6 +103,7 @@ func reload_finished():
func shoot():
if GameGlobals.gun_ammo.has(weapon_info.gun_name):
if weapon_info.weapon_type == 0:
if GameGlobals.gun_ammo[weapon_info.gun_name] > 0 and cycle_count > 0:
if !anim_player.is_playing():
@@ -276,6 +277,12 @@ func bullet_fire():
SignalBus.emit_signal("shot_fired")
func can_fire():
if anim_player.is_playing() and anim_player.current_animation == "reload":
return false
else:
return true
func hitscan_fire():
# Fire hitscan
pass