initial commit
This commit is contained in:
commit
79951d8075
22 changed files with 729 additions and 0 deletions
218
player/player.gd
Normal file
218
player/player.gd
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
class_name Player extends CharacterBody3D
|
||||
|
||||
@export var walk_speed = 12
|
||||
@export var jump_power = 32
|
||||
@export var fall_speed = 86
|
||||
|
||||
var health = 100
|
||||
var suspended = false
|
||||
var spawn = Vector3.ZERO
|
||||
var direction = Vector3.ZERO
|
||||
var target_velocity = Vector3.ZERO
|
||||
var initial_gear = null
|
||||
var gear_slots = ["1", "2", "3"]
|
||||
|
||||
func resize_ui():
|
||||
var bpui_h = 200
|
||||
var size = get_viewport().get_visible_rect().size
|
||||
$Message.size.x = size.x
|
||||
$BackpackUI.size.x = size.x
|
||||
$BackpackUI.size.y = bpui_h
|
||||
$BackpackUI.position.x = 0
|
||||
$BackpackUI.position.y = size.y - bpui_h
|
||||
|
||||
func make_backpack_ui():
|
||||
var text = "Holding " + $Pivot/Container/Gear.gear_name()
|
||||
for node in $Backpack.get_children():
|
||||
if not node is Gear:
|
||||
continue
|
||||
text += "\n%s (%s)" % [node.gear_name(), node.name]
|
||||
$BackpackUI.text = text
|
||||
|
||||
func message(string):
|
||||
$Message.text = string
|
||||
$Message.visible = true
|
||||
$Message/VanishTimer.start()
|
||||
|
||||
func die():
|
||||
suspended = true
|
||||
visible = false
|
||||
$BackpackUI.visible = false
|
||||
$RespawnTimer.start()
|
||||
message("Le gone")
|
||||
|
||||
func respawn():
|
||||
position = Vector3(spawn)
|
||||
$CameraGimbal.reset()
|
||||
health = 100
|
||||
visible = true
|
||||
suspended = false
|
||||
$BackpackUI.visible = true
|
||||
|
||||
# Backpack functions
|
||||
|
||||
func find_free_slot():
|
||||
for slot in gear_slots:
|
||||
if not has_node("Backpack/" + slot):
|
||||
return slot
|
||||
return null
|
||||
|
||||
func use_backpack_slot(n):
|
||||
assert(gear_slots.has(n))
|
||||
var gear_node = "Backpack/" + n
|
||||
var old = $Pivot/Container/Gear
|
||||
# check if gear is at slot
|
||||
if not has_node(gear_node):
|
||||
message("Gear not found")
|
||||
return
|
||||
# place current gear in first free slot
|
||||
var slot = find_free_slot()
|
||||
if slot:
|
||||
old.name = slot
|
||||
old.reparent($Backpack, false)
|
||||
get_node(gear_node).reparent($Pivot/Container, false)
|
||||
get_node("Pivot/Container/" + n).name = "Gear"
|
||||
make_backpack_ui()
|
||||
return
|
||||
# couldn't find a free slot, so replace
|
||||
# the new slot with the current gear
|
||||
get_node(gear_node).reparent($Pivot/Container, false)
|
||||
old.reparent($Backpack, false)
|
||||
old.name = n
|
||||
get_node("Pivot/Container/" + n).name = "Gear"
|
||||
make_backpack_ui()
|
||||
return
|
||||
|
||||
func equip(gear: Gear):
|
||||
var gear_name = gear.gear_name()
|
||||
# do we have the gear equipped?
|
||||
if gear_name == $Pivot/Container/Gear.gear_name():
|
||||
return false
|
||||
# do we have the gear in our backpack?
|
||||
for item in $Backpack.get_children():
|
||||
if item.gear_name() == gear_name:
|
||||
use_backpack_slot(item.name)
|
||||
return false
|
||||
# we do not have the gear, so set aside
|
||||
# the current gear and equip the new one
|
||||
var old = $Pivot/Container/Gear
|
||||
var new_gear: Gear
|
||||
# place current gear in first free slot
|
||||
var slot = find_free_slot()
|
||||
if slot:
|
||||
old.name = slot
|
||||
old.reparent($Backpack, false)
|
||||
new_gear = gear.duplicate()
|
||||
new_gear.name = "Gear"
|
||||
$Pivot/Container.add_child(new_gear)
|
||||
make_backpack_ui()
|
||||
message("You picked up a " + gear_name + "!")
|
||||
return true
|
||||
# if no slots are free
|
||||
message("Backpack full")
|
||||
return false
|
||||
|
||||
# Player movement and engine callbacks
|
||||
|
||||
func move_player(x, z):
|
||||
var camera_basis = $CameraGimbal.get_global_transform().basis
|
||||
|
||||
# rotate player
|
||||
get_global_transform().basis = Basis($CameraGimbal.basis)
|
||||
var z_basis = -camera_basis.z
|
||||
if z == 1:
|
||||
z_basis = -z_basis
|
||||
$Pivot.basis = Basis.looking_at(z_basis.normalized())
|
||||
$CollisionShape3D.basis = $Pivot.basis
|
||||
# apply camera direction to movement direction
|
||||
if z != 0:
|
||||
# adding the value to the existing direction
|
||||
# variable lets the user press multiple keys
|
||||
# to move diagonally
|
||||
direction += camera_basis.z * z
|
||||
if x != 0:
|
||||
direction += camera_basis.x * x
|
||||
|
||||
func _ready():
|
||||
spawn = Vector3(position)
|
||||
initial_gear = $Pivot/Container/Gear.duplicate()
|
||||
get_viewport().size_changed.connect(resize_ui)
|
||||
resize_ui()
|
||||
make_backpack_ui()
|
||||
|
||||
func _physics_process(delta):
|
||||
if suspended:
|
||||
return
|
||||
|
||||
if health < 1 or position.y <= -1000:
|
||||
die()
|
||||
|
||||
# UI and backpack keys
|
||||
if Input.is_action_pressed("ui_backpack"):
|
||||
var mesg = "Equipped: " + $Pivot/Container/Gear.gear_name() + "\nBackpack: "
|
||||
for node in $Backpack.get_children():
|
||||
if not node is Gear:
|
||||
continue
|
||||
mesg += node.name + "." + node.gear_name() + " "
|
||||
message(mesg)
|
||||
if Input.is_action_just_pressed("backpack_1"):
|
||||
use_backpack_slot("1")
|
||||
if Input.is_action_just_pressed("backpack_2"):
|
||||
use_backpack_slot("2")
|
||||
if Input.is_action_just_pressed("backpack_3"):
|
||||
use_backpack_slot("3")
|
||||
|
||||
# Movement keys
|
||||
var mx = 0
|
||||
var mz = 0
|
||||
|
||||
if Input.is_action_pressed("move_forward"):
|
||||
mz -= 1
|
||||
if Input.is_action_pressed("move_back"):
|
||||
mz += 1
|
||||
if Input.is_action_pressed("move_left"):
|
||||
mx -= 1
|
||||
if Input.is_action_pressed("move_right"):
|
||||
mx += 1
|
||||
if Input.is_action_pressed("jump") and is_on_floor():
|
||||
target_velocity.y = jump_power
|
||||
|
||||
if !(mx == 0 and mz == 0):
|
||||
move_player(mx, mz)
|
||||
|
||||
target_velocity.x = direction.x * walk_speed
|
||||
target_velocity.z = direction.z * walk_speed
|
||||
direction = Vector3.ZERO
|
||||
|
||||
if not is_on_floor():
|
||||
target_velocity.y = target_velocity.y - (fall_speed * delta)
|
||||
velocity = target_velocity
|
||||
|
||||
move_and_slide()
|
||||
|
||||
# Gear uses
|
||||
var gear = $Pivot/Container/Gear
|
||||
assert(gear is Gear)
|
||||
if gear.continuous():
|
||||
if Input.is_action_pressed("gear_use"):
|
||||
gear.use(self)
|
||||
else:
|
||||
if Input.is_action_just_pressed("gear_use"):
|
||||
gear.use(self)
|
||||
|
||||
# Signals
|
||||
|
||||
func _on_vanish_timer_timeout():
|
||||
$Message.visible = false
|
||||
|
||||
# Ensure that gears are invisible in the backpack.
|
||||
# As children of a Node they will be detached from
|
||||
# 3D space so if visible is true they may be visibly
|
||||
# littered on the ground where the player changed
|
||||
# gears.
|
||||
func _on_backpack_child_entered_tree(node):
|
||||
assert(node is Gear)
|
||||
node.visible = false
|
||||
func _on_backpack_child_exiting_tree(node):
|
||||
assert(node is Gear)
|
||||
node.visible = true
|
||||
Loading…
Add table
Add a link
Reference in a new issue