init
This commit is contained in:
commit
e45f121fb9
89 changed files with 336069 additions and 0 deletions
118
demo/scripts/arcade/player_arcade.gd
Normal file
118
demo/scripts/arcade/player_arcade.gd
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
class_name PlayerArcade
|
||||
extends CharacterBody3D
|
||||
|
||||
# Arcade player: same FPS controller as the demo, plus HP and a melee
|
||||
# attack on left-click. Emits hp_changed and died signals; arcade_scene
|
||||
# listens and updates the HUD / restart logic.
|
||||
|
||||
signal hp_changed(current: int, maximum: int)
|
||||
signal died
|
||||
signal attacked(hit_point: Vector3, hit_body: Node)
|
||||
|
||||
@export var speed := 6.0
|
||||
@export var run_multiplier := 1.8
|
||||
@export var jump_velocity := 6.0
|
||||
@export var gravity := 22.0
|
||||
@export var mouse_sensitivity := 0.002
|
||||
@export var max_hp := 20
|
||||
@export var melee_range := 1.6
|
||||
@export var melee_damage := 6
|
||||
@export var melee_cooldown := 0.35
|
||||
|
||||
@onready var camera: Camera3D = $Camera3D
|
||||
|
||||
var hp := 20
|
||||
var _pitch := 0.0
|
||||
var _captured := false
|
||||
var _melee_timer := 0.0
|
||||
var _alive := true
|
||||
|
||||
func _ready() -> void:
|
||||
hp = max_hp
|
||||
hp_changed.emit(hp, max_hp)
|
||||
_capture()
|
||||
|
||||
func _capture() -> void:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
_captured = true
|
||||
|
||||
func _release() -> void:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
_captured = false
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if not _alive:
|
||||
return
|
||||
if event is InputEventMouseMotion and _captured:
|
||||
var m := event as InputEventMouseMotion
|
||||
rotation.y -= m.relative.x * mouse_sensitivity
|
||||
_pitch -= m.relative.y * mouse_sensitivity
|
||||
_pitch = clamp(_pitch, deg_to_rad(-85.0), deg_to_rad(85.0))
|
||||
camera.rotation.x = _pitch
|
||||
elif event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE:
|
||||
_release()
|
||||
elif event is InputEventMouseButton and event.pressed:
|
||||
if not _captured:
|
||||
_capture()
|
||||
elif event.button_index == MOUSE_BUTTON_LEFT:
|
||||
_try_attack()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not _alive:
|
||||
return
|
||||
if _melee_timer > 0.0:
|
||||
_melee_timer -= delta
|
||||
|
||||
if not is_on_floor():
|
||||
velocity.y -= gravity * delta
|
||||
|
||||
var input := Vector2.ZERO
|
||||
if Input.is_key_pressed(KEY_W): input.y -= 1.0
|
||||
if Input.is_key_pressed(KEY_S): input.y += 1.0
|
||||
if Input.is_key_pressed(KEY_A): input.x -= 1.0
|
||||
if Input.is_key_pressed(KEY_D): input.x += 1.0
|
||||
input = input.normalized()
|
||||
|
||||
var s := speed
|
||||
if Input.is_key_pressed(KEY_SHIFT):
|
||||
s *= run_multiplier
|
||||
|
||||
var forward := -transform.basis.z
|
||||
var right := transform.basis.x
|
||||
var horiz := (forward * -input.y + right * input.x) * s
|
||||
velocity.x = horiz.x
|
||||
velocity.z = horiz.z
|
||||
|
||||
if is_on_floor() and Input.is_key_pressed(KEY_SPACE):
|
||||
velocity.y = jump_velocity
|
||||
|
||||
move_and_slide()
|
||||
|
||||
# Deal damage to any enemy within melee_range in front of the camera.
|
||||
func _try_attack() -> void:
|
||||
if _melee_timer > 0.0:
|
||||
return
|
||||
_melee_timer = melee_cooldown
|
||||
|
||||
var origin := camera.global_position
|
||||
var dir := -camera.global_transform.basis.z
|
||||
var space := get_world_3d().direct_space_state
|
||||
var query := PhysicsRayQueryParameters3D.create(origin, origin + dir * melee_range)
|
||||
query.exclude = [self]
|
||||
var hit := space.intersect_ray(query)
|
||||
if hit.is_empty():
|
||||
return
|
||||
var body := hit.get("collider") as Node
|
||||
if body and body.has_method("take_damage"):
|
||||
body.take_damage(melee_damage, self)
|
||||
attacked.emit(hit.get("position", Vector3.ZERO), body)
|
||||
|
||||
# Called by enemies.
|
||||
func take_damage(amount: int, _source: Node) -> void:
|
||||
if not _alive:
|
||||
return
|
||||
hp = max(0, hp - amount)
|
||||
hp_changed.emit(hp, max_hp)
|
||||
if hp <= 0:
|
||||
_alive = false
|
||||
died.emit()
|
||||
Loading…
Add table
Add a link
Reference in a new issue