Game jam submission
This commit is contained in:
+61
-7
@@ -2,23 +2,66 @@ class_name Player
|
||||
extends CharacterBody3D
|
||||
|
||||
@export var player_id := 1
|
||||
@export var gravity_vector := Vector3(0, -20, 0)
|
||||
@export var gravity_vector := Vector3(0, -15, 0)
|
||||
@export var move_speed := 8.0
|
||||
@export var accel := 50.0
|
||||
@export var friction := 16.0
|
||||
@export var jump_speed := 12.0
|
||||
@export var jump_speed := 8.0
|
||||
@export var air_control := 0.65
|
||||
@export var coyote := 0.1
|
||||
@export var buffer := 0.1
|
||||
@export var col1 := Color(0.3, 0.6, 1)
|
||||
@export var col2 := Color(1, 0.47, 0.35)
|
||||
|
||||
var ct := 0.0
|
||||
var bt := 0.0
|
||||
|
||||
## Player-vs-player stacking. A rider standing on us would otherwise block our
|
||||
## own move_and_slide (its collider reads as a slanted wall), so while carried we
|
||||
## drop the players layer from our mask — the rider keeps colliding with us, the
|
||||
## test is one-way. Carrying the rider along is CharacterBody3D's own
|
||||
## moving-platform handling; adding it again here just launches them off.
|
||||
const PLAYERS_LAYER := 2
|
||||
const CARRIED_LINGER := 0.1
|
||||
var carried_t := 0.0
|
||||
|
||||
## Cleared when the run ends. Physics keeps running — the player still falls,
|
||||
## slides to a stop and gets dragged by whatever is left of the rope — only
|
||||
## input is ignored.
|
||||
var controls_enabled := true : set = set_controls_enabled
|
||||
|
||||
const BLUE_TEXTURE_DIR := "res://assets/Chara_blue/"
|
||||
|
||||
# Drops the buffered jump on the way out, so a press from the frame before the
|
||||
# controls were cut does not still fire afterwards.
|
||||
func set_controls_enabled(value : bool) -> void:
|
||||
controls_enabled = value
|
||||
if not value:
|
||||
bt = 0.0
|
||||
|
||||
func _ready():
|
||||
add_to_group("players")
|
||||
# $Body.color = col1 if player_id == 1 else col2
|
||||
if player_id == 1:
|
||||
_apply_blue_skin(self)
|
||||
|
||||
# The character mesh ships with the red base-color maps baked into its
|
||||
# materials. Player 1 reuses the same mesh with the blue maps swapped in:
|
||||
# every other map (normal/roughness/metallic/height) is shared between the
|
||||
# two colour variants, so only albedo needs overriding.
|
||||
func _apply_blue_skin(node: Node) -> void:
|
||||
for child in node.get_children():
|
||||
_apply_blue_skin(child)
|
||||
var mi := node as MeshInstance3D
|
||||
if mi == null or mi.mesh == null:
|
||||
return
|
||||
for i in mi.mesh.get_surface_count():
|
||||
var mat := mi.get_active_material(i) as BaseMaterial3D
|
||||
if mat == null or mat.albedo_texture == null:
|
||||
continue
|
||||
var blue_path := BLUE_TEXTURE_DIR + mat.albedo_texture.resource_path.get_file()
|
||||
if not ResourceLoader.exists(blue_path):
|
||||
continue
|
||||
var blue_mat := mat.duplicate() as BaseMaterial3D
|
||||
blue_mat.albedo_texture = load(blue_path)
|
||||
mi.set_surface_override_material(i, blue_mat)
|
||||
|
||||
func _physics_process(d):
|
||||
var up = Vector3.UP if gravity_vector.length_squared() < 0.0001 else -gravity_vector.normalized()
|
||||
@@ -26,9 +69,9 @@ func _physics_process(d):
|
||||
velocity += gravity_vector * d
|
||||
ct = coyote if is_on_floor() else max(ct - d, 0.0)
|
||||
bt = max(bt - d, 0.0)
|
||||
if Input.is_action_just_pressed("p%d_jump" % player_id):
|
||||
if controls_enabled and Input.is_action_just_pressed("p%d_jump" % player_id):
|
||||
bt = buffer
|
||||
var ix = Input.get_axis("p%d_left" % player_id, "p%d_right" % player_id)
|
||||
var ix = Input.get_axis("p%d_left" % player_id, "p%d_right" % player_id) if controls_enabled else 0.0
|
||||
var a = accel if is_on_floor() else accel * air_control
|
||||
if abs(ix) > 0.01:
|
||||
velocity.x = move_toward(velocity.x, ix * move_speed, a * d)
|
||||
@@ -38,8 +81,19 @@ func _physics_process(d):
|
||||
velocity = velocity.slide(up) + up * jump_speed
|
||||
bt = 0.0
|
||||
ct = 0.0
|
||||
carried_t = max(carried_t - d, 0.0)
|
||||
set_collision_mask_value(PLAYERS_LAYER, carried_t <= 0.0)
|
||||
# plane lock: 2D platformer physics in a 3D scene. Sliding along an angled
|
||||
# collision normal can otherwise walk the player off the Z=0 plane.
|
||||
velocity.z = 0.0
|
||||
move_and_slide()
|
||||
# Riding is handled by CharacterBody3D's own moving-platform support, so the
|
||||
# only thing to do here is tell whoever we landed on that it is carrying us.
|
||||
for i in get_slide_collision_count():
|
||||
var col := get_slide_collision(i)
|
||||
if col.get_normal().dot(up) < 0.7:
|
||||
continue
|
||||
var below := col.get_collider() as Player
|
||||
if below != null:
|
||||
below.carried_t = CARRIED_LINGER
|
||||
global_position.z = 0.0
|
||||
|
||||
Reference in New Issue
Block a user