Initial scaffold: Godot 4.3 scenes, systems, and placeholders.
Wire all twelve levels with billboard prefabs, autoload systems (inventory, achievements, mock shop, DE/EN/BY), and satire audio locks so the Title→End flow is playable with placeholder assets.
This commit is contained in:
commit
938cc4bc82
114 changed files with 4819 additions and 0 deletions
58
scripts/player/player_controller.gd
Normal file
58
scripts/player/player_controller.gd
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
extends CharacterBody3D
|
||||
class_name PlayerController
|
||||
## Simple top-down-ish 3D movement for billboard levels.
|
||||
|
||||
@export var move_speed: float = 6.0
|
||||
@export var attack_range: float = 1.8
|
||||
@export var attack_damage: int = 1
|
||||
|
||||
signal interacted
|
||||
signal attacked
|
||||
|
||||
@onready var _billboard: BillboardSprite = $BillboardSprite
|
||||
|
||||
var _locked: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
add_to_group("player")
|
||||
if _billboard and _billboard.texture == null:
|
||||
var tex: Texture2D = load("res://assets/sprites/placeholders/player.png")
|
||||
if tex:
|
||||
_billboard.set_texture(tex)
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if _locked or get_tree().paused:
|
||||
velocity = Vector3.ZERO
|
||||
return
|
||||
var input := Vector2(
|
||||
Input.get_axis("move_left", "move_right"),
|
||||
Input.get_axis("move_up", "move_down")
|
||||
)
|
||||
var dir := Vector3(input.x, 0.0, input.y)
|
||||
if dir.length() > 1.0:
|
||||
dir = dir.normalized()
|
||||
velocity = dir * move_speed
|
||||
move_and_slide()
|
||||
if Input.is_action_just_pressed("interact"):
|
||||
_try_interact()
|
||||
if Input.is_action_just_pressed("attack"):
|
||||
_try_attack()
|
||||
|
||||
func lock_input(locked: bool) -> void:
|
||||
_locked = locked
|
||||
|
||||
func _try_interact() -> void:
|
||||
interacted.emit()
|
||||
for body in get_tree().get_nodes_in_group("interactable"):
|
||||
if body is Node3D and global_position.distance_to(body.global_position) <= 2.2:
|
||||
if body.has_method("on_interact"):
|
||||
body.on_interact(self)
|
||||
return
|
||||
|
||||
func _try_attack() -> void:
|
||||
attacked.emit()
|
||||
AudioDirector.play_hit()
|
||||
for body in get_tree().get_nodes_in_group("enemy"):
|
||||
if body is Node3D and global_position.distance_to(body.global_position) <= attack_range:
|
||||
if body.has_method("take_hit"):
|
||||
body.take_hit(attack_damage)
|
||||
Loading…
Add table
Add a link
Reference in a new issue