Compare commits

...

9 Commits

Author SHA1 Message Date
Kenney 7a9122f6c5 Update player.gd 2023-10-16 10:22:09 +07:00
Kenney 75b487e579
Merge pull request #9 from idbrii/gamepad
Work with gamepads (and some cleanup)
2023-10-16 09:57:58 +07:00
David Briscoe a10a5c56bf Use circular movement deadzone
get_vector is a circular deadzone, but two get_axis will be a
cross-shaped one.
https://docs.godotengine.org/en/stable/tutorials/inputs/controllers_gamepads_joysticks.html#which-input-singleton-method-should-i-use
https://github.com/godotengine/godot-docs/issues/5378#issuecomment-1635899278
2023-10-15 00:34:54 +07:00
David Briscoe b2c60a56e3 Always have a valid weapon
Fix crash when you're shooting when you die or when you start the game.
Since weapon is nil (waiting for anim to finish before assigning it),
the game crashes trying on Audio.play(weapon.sound_shoot).
2023-10-15 00:34:48 +07:00
David Briscoe 28fc66d961 Tune up jump to reach platforms
Increase jump power so you can jump to all platforms with enemies.
2023-10-15 00:34:21 +07:00
David Briscoe cb5d697704 Whitespace: Remove trailing and adjust spacing
Used gdformat from godot-gdscript-toolkit to automatically clean up
formatting to be consistent across the project.

One exception: there's a long line in player.gd that it split across
multiple lines that seemed worse than before.
2023-10-15 00:34:01 +07:00
David Briscoe 9bd817d9e4 Jump with gamepad A
Use more conventional jump button.
2023-10-15 00:34:01 +07:00
David Briscoe a36ae6e38a Rework camera to work with gamepad
Fix camera moves 180 degrees every frame when using gamepad.

Store a rotation delta and use rotate_toward to move with a max speed
instead of a lerp. Has the same general feel with mouse, but now gamepad
feels reasonable.
2023-10-15 00:33:58 +07:00
David Briscoe 4113e975a7 Remove accidentally added temp file
It's just a copy of project.godot from a failed save. See issue 82270.

Add that pattern to gitignore.
2023-10-14 23:23:02 +07:00
9 changed files with 58 additions and 168 deletions

4
.gitignore vendored

@ -15,4 +15,6 @@ data_*/
mono_crash.*.json
# Kenney ignores
build/
build/
# https://github.com/godotengine/godot/issues/82270
*~*.TMP

@ -1,6 +1,6 @@
extends Node3D
@export var player:Node3D
@export var player: Node3D
@onready var raycast = $RayCast
@onready var muzzle_a = $MuzzleA
@ -8,66 +8,67 @@ extends Node3D
var health := 100
var time := 0.0
var target_position:Vector3
var target_position: Vector3
var destroyed := false
# When ready, save the initial position
func _ready():
target_position = position
func _process(delta):
self.look_at(player.position + Vector3(0, 0.5, 0), Vector3.UP, true) # Look at player
target_position.y += (cos(time * 5) * 1) * delta # Sine movement (up and down)
self.look_at(player.position + Vector3(0, 0.5, 0), Vector3.UP, true) # Look at player
target_position.y += (cos(time * 5) * 1) * delta # Sine movement (up and down)
time += delta
position = target_position
# Take damage from player
func damage(amount):
Audio.play("sounds/enemy_hurt.ogg")
health -= amount
if health <= 0 and !destroyed:
destroy()
# Destroy the enemy when out of health
func destroy():
Audio.play("sounds/enemy_destroy.ogg")
destroyed = true
queue_free()
# Shoot when timer hits 0
func _on_timer_timeout():
raycast.force_raycast_update()
if raycast.is_colliding():
var collider = raycast.get_collider()
if collider.has_method("damage"): # Raycast collides with player
if collider.has_method("damage"): # Raycast collides with player
# Play muzzle flash animation(s)
muzzle_a.frame = 0
muzzle_a.play("default")
muzzle_a.rotation_degrees.z = randf_range(-45, 45)
muzzle_b.frame = 0
muzzle_b.play("default")
muzzle_b.rotation_degrees.z = randf_range(-45, 45)
Audio.play("sounds/enemy_attack.ogg")
collider.damage(5) # Apply damage to player
collider.damage(5) # Apply damage to player

@ -2,5 +2,6 @@ extends AnimatedSprite3D
# Remove this impact effect after the animation has completed
func _on_animation_finished():
queue_free()

@ -2,7 +2,7 @@ extends CharacterBody3D
@export_subgroup("Properties")
@export var movement_speed = 5
@export var jump_strength = 7
@export var jump_strength = 8
@export_subgroup("Weapons")
@export var weapons: Array[Weapon] = []
@ -11,12 +11,13 @@ var weapon: Weapon
var weapon_index := 0
var mouse_sensitivity = 700
var gamepad_sensitivity := 0.075
var mouse_captured := true
var movement_velocity: Vector3
var rotation_target: Vector3
var input: Vector3
var input_mouse: Vector2
var health:int = 100
@ -48,6 +49,7 @@ func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
weapon = weapons[weapon_index] # Weapon must never be nil
initiate_change_weapon(weapon_index)
func _physics_process(delta):
@ -127,19 +129,15 @@ func handle_controls(_delta):
# Movement
input.x = Input.get_axis("move_left", "move_right")
input.z = Input.get_axis("move_forward", "move_back")
var input := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
movement_velocity = input.normalized() * movement_speed
movement_velocity = Vector3(input.x, 0, input.y).normalized() * movement_speed
# Rotation
var rotation_input := Vector3.ZERO
rotation_input.y = Input.get_axis("camera_left", "camera_right")
rotation_input.x = Input.get_axis("camera_up", "camera_down") / 2
var rotation_input := Input.get_vector("camera_right", "camera_left", "camera_down", "camera_up")
rotation_target -= rotation_input.limit_length(1.0) * 5
rotation_target -= Vector3(-rotation_input.y, -rotation_input.x, 0).limit_length(1.0) * gamepad_sensitivity
rotation_target.x = clamp(rotation_target.x, deg_to_rad(-90), deg_to_rad(90))
# Shooting

@ -61,7 +61,7 @@ move_back={
jump={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
]
}
camera_left={

@ -1,112 +0,0 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Starter Kit FPS"
config/tags=PackedStringArray("starterkit")
run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.1", "Forward Plus")
boot_splash/bg_color=Color(0.92549, 0.92549, 0.960784, 1)
boot_splash/image="res://splash-screen.png"
config/icon="res://icon.png"
[autoload]
Audio="*res://scripts/audio.gd"
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
[editor]
movie_writer/mjpeg_quality=1.0
movie_writer/movie_file="D:/Godot/test.avi"
[input]
move_right={
"deadzone": 0.25,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
]
}
move_left={
"deadzone": 0.25,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
]
}
move_forward={
"deadzone": 0.25,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
]
}
move_back={
"deadzone": 0.25,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
]
}
jump={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
]
}
camera_left={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null)
]
}
camera_right={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null)
]
}
camera_up={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null)
]
}
camera_down={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null)
]
}
mouse_capture={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
mouse_capture_exit={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null)
]
}
shoot={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(92, 12),"global_position":Vector2(96, 55),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
]
}
weapon_toggle={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":true,"script":null)
]
}
[rendering]
anti_aliasing/quality/screen_space_aa=1

@ -8,14 +8,14 @@ var bus = "master"
var available = [] # The available players.
var queue = [] # The queue of sounds to play.
func _ready():
func _ready():
for i in num_players:
var p = AudioStreamPlayer.new()
add_child(p)
available.append(p)
p.volume_db = -10
p.finished.connect(_on_stream_finished.bind(p))
p.bus = bus
@ -24,16 +24,16 @@ func _ready():
func _on_stream_finished(stream):
available.append(stream)
func play(sound_path): # Path (or multiple, separated by commas)
func play(sound_path): # Path (or multiple, separated by commas)
var sounds = sound_path.split(",")
queue.append("res://" + sounds[randi() % sounds.size()].strip_edges())
func _process(_delta):
func _process(_delta):
if not queue.is_empty() and not available.is_empty():
available[0].stream = load(queue.pop_front())
available[0].play()
available[0].pitch_scale = randf_range(0.9, 1.1)
available.pop_front()

@ -1,5 +1,5 @@
extends CanvasLayer
func _on_health_updated(health):
$Health.text = str(health) + "%"

@ -2,21 +2,21 @@ 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_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