* weapon.gd added min_knockback and max_knockback members

* player.gd added static method to create a random 2D vector function, and fixed KenneyNL/Starter-Kit-FPS#18
* weapons/blaster-repeater.tres and blaster.tres add min_knockback and max_knockback properties
pull/19/head
gzlock 2025-10-01 02:13:04 +07:00
parent cc46ba7b2b
commit 4e0401df68
3 changed files with 36 additions and 36 deletions

@ -2,7 +2,7 @@ extends CharacterBody3D
@export_subgroup("Properties")
@export var movement_speed = 5
@export_range(0, 100) var number_of_jumps:int = 2
@export_range(0, 100) var number_of_jumps: int = 2
@export var jump_strength = 8
@export_subgroup("Weapons")
@ -21,16 +21,16 @@ var rotation_target: Vector3
var input_mouse: Vector2
var health:int = 100
var health: int = 100
var gravity := 0.0
var previously_floored := false
var jumps_remaining:int
var jumps_remaining: int
var container_offset = Vector3(1.2, -1.1, -2.75)
var tween:Tween
var tween: Tween
signal health_updated
@ -41,21 +41,18 @@ signal health_updated
@onready var sound_footsteps = $SoundFootsteps
@onready var blaster_cooldown = $Cooldown
@export var crosshair:TextureRect
@export var crosshair: TextureRect
# Functions
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
weapon = weapons[weapon_index] # Weapon must never be nil
initiate_change_weapon(weapon_index)
func _process(delta):
# Handle functions
handle_controls(delta)
handle_gravity(delta)
@ -66,7 +63,7 @@ func _process(delta):
movement_velocity = transform.basis * movement_velocity # Move forward
applied_velocity = velocity.lerp(movement_velocity, delta * 10)
applied_velocity.y = -gravity
applied_velocity.y = - gravity
velocity = applied_velocity
move_and_slide()
@ -105,9 +102,7 @@ func _input(event):
handle_rotation(event.relative.x, event.relative.y, false)
func handle_controls(delta):
# Mouse capture
if Input.is_action_just_pressed("mouse_capture"):
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
mouse_captured = true
@ -134,7 +129,6 @@ func handle_controls(delta):
# Jumping
if Input.is_action_just_pressed("jump"):
if jumps_remaining:
action_jump()
@ -162,23 +156,20 @@ func handle_gravity(delta):
gravity += 20 * delta
if gravity > 0 and is_on_floor():
jumps_remaining = number_of_jumps
gravity = 0
# Jumping
func action_jump():
func action_jump():
Audio.play("sounds/jump_a.ogg, sounds/jump_b.ogg, sounds/jump_c.ogg")
gravity = -jump_strength
gravity = - jump_strength
jumps_remaining -= 1
# Shooting
func action_shoot():
if Input.is_action_pressed("shoot"):
if !blaster_cooldown.is_stopped(): return # Cooldown for shooting
Audio.play(weapon.sound_shoot)
@ -196,7 +187,6 @@ func action_shoot():
# Shoot the weapon, amount based on shot count
for n in weapon.shot_count:
raycast.target_position.x = randf_range(-weapon.spread, weapon.spread)
raycast.target_position.y = randf_range(-weapon.spread, weapon.spread)
@ -223,16 +213,19 @@ func action_shoot():
impact_instance.position = raycast.get_collision_point() + (raycast.get_collision_normal() / 10)
impact_instance.look_at(camera.global_transform.origin, Vector3.UP, true)
var knockback = random_vec2(weapon.min_knockback, weapon.max_knockback)
# print('knockback', knockback)
container.position.z += 0.25 # Knockback of weapon visual
camera.rotation.x += 0.025 # Knockback of camera
camera.rotation.x += knockback.x # Knockback of camera
rotation.y += knockback.y
rotation_target.x += knockback.x
rotation_target.y += knockback.y
movement_velocity += Vector3(0, 0, weapon.knockback) # Knockback
# Toggle between available weapons (listed in 'weapons')
func action_weapon_toggle():
if Input.is_action_just_pressed("weapon_toggle"):
weapon_index = wrap(weapon_index + 1, 0, weapons.size())
initiate_change_weapon(weapon_index)
@ -241,7 +234,6 @@ func action_weapon_toggle():
# Initiates the weapon changing animation (tween)
func initiate_change_weapon(index):
weapon_index = index
tween = get_tree().create_tween()
@ -252,7 +244,6 @@ func initiate_change_weapon(index):
# Switches the weapon model (off-screen)
func change_weapon():
weapon = weapons[weapon_index]
# Step 1. Remove previous weapon model(s) from container
@ -279,9 +270,13 @@ func change_weapon():
crosshair.texture = weapon.crosshair
func damage(amount):
health -= amount
health_updated.emit(health) # Update health on HUD
if health < 0:
get_tree().reload_current_scene() # Reset when out of health
# Create a random knockback vector
static func random_vec2(_min: Vector2, _max: Vector2) -> Vector2:
var _sign = -1 if randi() % 2 == 0 else 1
return Vector2(randf_range(_min.x, _max.x), randf_range(_min.y, _max.y) * _sign)

@ -2,21 +2,24 @@ extends Resource
class_name Weapon
@export_subgroup("Model")
@export var model: PackedScene # Model of the weapon
@export var position: Vector3 # On-screen position
@export var rotation: Vector3 # On-screen rotation
@export var muzzle_position: Vector3 # On-screen position of muzzle flash
@export var model: PackedScene # Model of the weapon
@export var position: Vector3 # On-screen position
@export var rotation: Vector3 # On-screen rotation
@export var muzzle_position: Vector3 # On-screen position of muzzle flash
@export_subgroup("Properties")
@export_range(0.1, 1) var cooldown: float = 0.1 # Firerate
@export_range(1, 20) var max_distance: int = 10 # Fire distance
@export_range(0, 100) var damage: float = 25 # Damage per hit
@export_range(0, 5) var spread: float = 0 # Spread of each shot
@export_range(1, 5) var shot_count: int = 1 # Amount of shots
@export_range(0, 50) var knockback: int = 20 # Amount of knockback
@export_range(0.1, 1) var cooldown: float = 0.1 # Firerate
@export_range(1, 20) var max_distance: int = 10 # Fire distance
@export_range(0, 100) var damage: float = 25 # Damage per hit
@export_range(0, 5) var spread: float = 0 # Spread of each shot
@export_range(1, 5) var shot_count: int = 1 # Amount of shots
@export_range(0, 50) var knockback: int = 20 # Amount of knockback
@export var min_knockback: Vector2 = Vector2(0.001, 0.001) # x for vertical knockback, y for horizontal knockback
@export var max_knockback: Vector2 = Vector2(0.0025, 0.002) # x for vertical knockback, y for horizontal knockback
@export_subgroup("Sounds")
@export var sound_shoot: String # Sound path
@export var sound_shoot: String # Sound path
@export_subgroup("Crosshair")
@export var crosshair: Texture2D # Image of crosshair on-screen
@export var crosshair: Texture2D # Image of crosshair on-screen

@ -13,5 +13,7 @@ cooldown = 0.25
spread = 1.0
shot_count = 3
knockback = 40
min_knockback = Vector2(0.025, 0.025)
max_knockback = Vector2(0.045, 0.04)
sound_shoot = "sounds/blaster.ogg"
crosshair = ExtResource("1_2onsr")