the_tower/player/Player.gd
2020-06-11 12:23:35 +02:00

211 lines
4.8 KiB
GDScript

extends KinematicBody
var camera_angle : float = 0
var mouse_sensitivity : float = 0.3
var camera_change : Vector2
var velocity : Vector3
var direction : Vector3
#flying
const FLY_SPEED = 10
const FLY_ACCEL = 8
var flying : bool = false
#waling
var gravity : float = -9.8 * 4
const MAX_SPEED = 10
const MAX_RUNNING_SPEED = 16
const ACCEL = 14
const DEACCEL = 14
#jumping
var jump_height = 12
var has_contact : bool = false
var double_jumped : bool = false
var jump_height_modifier : float = 1
var gravity_modifier : float = 1
var walk_speed_modifier : float = 1
var run_speed_modifier : float = 1
var accel_modifier : float = 1
#audio player
const WALK_STEP_TIME = 0.5
const MIN_SOUND_TIME_LIMIT = 0.3
var foot_audio : AudioStreamPlayer3D
var step_timer : float = 0
var foot : bool = false
var last_sound_timer : float = 0
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
foot_audio = $foot as AudioStreamPlayer3D
func _process(delta):
if Input.is_action_just_pressed("ui_cancel"):
if not $Menu.visible:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
$Menu.show()
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
$Menu.hide()
if Input.is_action_just_pressed("restart"):
if get_node("../../").has_method("reload"):
get_node("../../").reload()
func _physics_process(delta):
aim()
last_sound_timer += delta
if flying:
fly(delta)
else:
walk(delta)
func fly(delta):
direction = Vector3()
var aim : Basis = $Head/Camera.global_transform.basis
if Input.is_action_pressed("move_forward"):
direction -= aim.z
if Input.is_action_pressed("move_backward"):
direction += aim.z
if Input.is_action_pressed("move_left"):
direction -= aim.x
if Input.is_action_pressed("move_right"):
direction += aim.x
if Input.is_action_pressed("move_jump"):
direction.y += 1
direction = direction.normalized()
var target : Vector3 = direction * FLY_SPEED * run_speed_modifier
velocity = velocity.linear_interpolate(target, FLY_ACCEL * delta)
move_and_slide(velocity)
func walk(delta):
direction = Vector3()
var aim : Basis = $Head/Camera.global_transform.basis
if Input.is_action_pressed("move_forward"):
direction -= aim.z
if Input.is_action_pressed("move_backward"):
direction += aim.z
if Input.is_action_pressed("move_left"):
direction -= aim.x
if Input.is_action_pressed("move_right"):
direction += aim.x
direction = direction.normalized()
if is_on_floor():
has_contact = true
else:
if !$Contact.is_colliding():
has_contact = false
if has_contact and !is_on_floor():
move_and_collide(Vector3(0, -1, 0))
velocity.y += gravity * delta * gravity_modifier
var temp_velocity : Vector3 = velocity
temp_velocity.y = 0
var speed : float
var accel_multiplier : float = 1
if Input.is_action_pressed("move_sprint"):
accel_multiplier = 1.2
speed = MAX_RUNNING_SPEED * run_speed_modifier
else:
speed = MAX_SPEED * walk_speed_modifier
var accel : float
if direction.dot(temp_velocity) > 0:
accel = ACCEL * accel_multiplier
else:
accel = DEACCEL * accel_multiplier
var target : Vector3 = direction * speed
temp_velocity = temp_velocity.linear_interpolate(target, ACCEL * delta)
velocity.x = temp_velocity.x
velocity.z = temp_velocity.z
if not has_contact and not double_jumped and Input.is_action_just_pressed("move_jump"):
double_jumped = true
velocity.y = jump_height * jump_height_modifier
if has_contact and Input.is_action_just_pressed("move_jump"):
velocity.y = jump_height * jump_height_modifier
has_contact = false
double_jumped = false
if not foot_audio.playing and last_sound_timer >= MIN_SOUND_TIME_LIMIT:
foot_audio.play()
last_sound_timer = 0
step_timer = 0
velocity = move_and_slide(velocity, Vector3(0, 1, 0), true)
if not has_contact and is_on_floor():
if not foot_audio.playing and last_sound_timer >= MIN_SOUND_TIME_LIMIT:
foot_audio.play()
last_sound_timer = 0
step_timer = 0
var v : Vector3 = velocity
v.y = 0
if has_contact and v.length() > 1:
step_timer += delta
if step_timer >= WALK_STEP_TIME:
step_timer = 0
if not foot_audio.playing and last_sound_timer >= MIN_SOUND_TIME_LIMIT:
foot_audio.play()
last_sound_timer = 0
func _unhandled_input(event):
if event is InputEventMouseMotion:
camera_change = event.relative
func aim():
if camera_change.length() > 0:
$Head.rotate_y(deg2rad(-camera_change.x * mouse_sensitivity))
var change : float = -camera_change.y * mouse_sensitivity
if camera_angle + change > -90 and camera_angle + change < 90:
$Head/Camera.rotate_x(deg2rad(change))
camera_angle += change
camera_change = Vector2()
func ladder_area_entered(ladder):
flying = true
func ladder_area_exited(ladder):
flying = false
func is_player():
return true