GrappleTest/Player/BasicCharacter/CharacterController.gd

348 lines
8.6 KiB
GDScript3
Raw Permalink Normal View History

2024-02-22 00:10:13 -06:00
extends CharacterBody2D
2024-03-13 16:15:55 -05:00
const SPEED = 500.0
2024-02-22 00:10:13 -06:00
const ACCEL = 7.0
2024-02-26 08:28:11 -06:00
var direction = 0
var addedveloc = 0
2024-03-17 21:56:16 -05:00
var forcedVeloc = 0
2024-02-22 00:10:13 -06:00
2024-02-24 12:12:57 -06:00
const JUMP_VELOCITY = -450.0
2024-03-13 16:15:55 -05:00
const MAX_JUMPS = 1
2024-02-24 12:12:57 -06:00
var jumps = MAX_JUMPS
2024-02-27 11:27:54 -06:00
2024-02-26 08:28:11 -06:00
var wallKayote = 0
2024-02-24 12:12:57 -06:00
2024-02-27 11:27:54 -06:00
const FALL_SPEED = -JUMP_VELOCITY
2024-02-22 00:10:13 -06:00
var falling = false
2024-02-26 08:28:11 -06:00
var floorTime = 0
2024-03-13 16:15:55 -05:00
var kayote = 0
2024-02-24 12:12:57 -06:00
2024-02-26 08:28:11 -06:00
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
2024-02-24 12:12:57 -06:00
2024-03-13 16:15:55 -05:00
var checkpointPos = Vector2.ZERO
@export var ghostMode = false
var ghostFrame = 0
var startPos = Vector2.ZERO
var can_move = true
2024-03-17 21:56:16 -05:00
var camera : Camera2D
2024-03-13 16:15:55 -05:00
@export var savedInputsPath : String
2024-03-17 21:56:16 -05:00
@onready var sceneReload = load(get_tree().current_scene.scene_file_path)
2024-03-13 16:15:55 -05:00
var savedInputs = []
var wallPower = 0
var squishers = -1
func actionPressed(inp):
if ghostMode:
if inp in savedInputs[ghostFrame]:
return true
return false
else:
return Input.is_action_pressed(inp)
func actionJustPressed(inp):
if ghostMode:
if inp in savedInputs[ghostFrame] and not inp in savedInputs[ghostFrame - 1]:
return true
return false
else:
return Input.is_action_just_pressed(inp)
func getAxis(inp1, inp2):
if ghostMode:
var dir = 0
if actionPressed("left"):
dir -= 1
if actionPressed("right"):
dir += 1
return clamp(dir, -1, 1)
else:
return Input.get_axis(inp1, inp2)
2024-02-26 08:28:11 -06:00
func isWallSliding():
2024-03-17 21:56:16 -05:00
for collisionNumb in get_slide_collision_count():
var collision = get_slide_collision(collisionNumb)
var object = collision.get_collider()
if object is TileMap:
var tileMap : TileMap = object
var tilePos = tileMap.get_coords_for_body_rid(collision.get_collider_rid())
var tileData = tileMap.get_cell_tile_data(0, tilePos)
if tileData and not tileData.get_custom_data("Slidable") == true:
return false
2024-02-26 08:28:11 -06:00
return is_on_wall_only() and direction
2024-02-24 12:12:57 -06:00
2024-02-27 11:27:54 -06:00
func getGravMulti():
2024-03-17 21:56:16 -05:00
var axis = (gen.boolToNumb(actionPressed("up") or forceLowGrav, 1))
2024-02-27 11:27:54 -06:00
if velocity.y < 0:
return axis
return 1
2024-02-24 12:12:57 -06:00
func launch(veloc):
addedveloc = veloc
velocity.x = veloc
2024-02-22 00:10:13 -06:00
2024-03-17 21:56:16 -05:00
func forceLaunch(veloc):
forcedVeloc = veloc
velocity.x = veloc
2024-02-26 08:28:11 -06:00
signal Jumped
2024-03-13 16:15:55 -05:00
signal Died
2024-02-26 08:28:11 -06:00
2024-03-13 16:15:55 -05:00
var deathParticles = preload("res://Particles/Player/deathParticles.tscn")
2024-03-17 21:56:16 -05:00
var doubleWallJumped = false
var forceLowGrav = true
var landed = false
2024-03-13 16:15:55 -05:00
func die():
Died.emit()
var parti = deathParticles.instantiate()
parti.modulate = $Sprite.self_modulate
add_child(parti)
can_move = false
$Sprite.visible = false
2024-03-17 21:56:16 -05:00
gen.savedPos = checkpointPos
await Camera.deathAnim().finished
get_tree().change_scene_to_packed(sceneReload)
2024-03-13 16:15:55 -05:00
func _ready():
2024-03-17 21:56:16 -05:00
RenderingServer.set_default_clear_color(Color8(0, 0, 0))
if find_child("Camera"):
camera = $Camera
2024-03-13 16:15:55 -05:00
if ghostMode:
2024-03-17 21:56:16 -05:00
startPos = global_position
2024-03-13 16:15:55 -05:00
var rc = load(savedInputsPath)
2024-02-27 11:27:54 -06:00
2024-03-13 16:15:55 -05:00
if rc:
var inputKeyRaw = rc["actions"]
var frameDataRaw = rc["data"]
var inputKey = []
var frameData = {}
for action in inputKeyRaw:
inputKey.append(action)
for frame in frameDataRaw:
frameData[frame] = {}
for x in frameDataRaw[frame]:
frameData[frame][x] = frameDataRaw[frame][x]
var frameCount = gen.getRecordingFrameCount(frameData)
var held = []
for frame in range(frameCount):
savedInputs.append([])
if frameData.has(frame):
for actID in frameData[frame]:
var pressed = frameData[frame][actID]
var inputName = inputKey[actID]
if pressed == 1:
held.append(inputName)
elif inputName in held:
held.remove_at(held.find(inputName))
savedInputs[frame] += held
2024-03-17 21:56:16 -05:00
else:
Camera.player = self
var parti = deathParticles.instantiate()
parti.modulate = $Sprite.self_modulate
add_child(parti)
$Sprite.visible = true
$"../Smoother".reset_node(self)
#camera.position_smoothing_enabled = true
if gen.savedPos != Vector2.ZERO:
global_position = gen.savedPos
gen.savedPos = Vector2.ZERO
velocity = Vector2(0, 0)
#camera.reset_smoothing()
2024-03-13 16:15:55 -05:00
@onready var trail = $"Sprite/Trail"
var ghosting = true
var ghostParti = preload("res://Particles/Ghosts/spawnParticles.tscn")
2024-03-17 21:56:16 -05:00
var lastFloor = null
2024-03-13 16:15:55 -05:00
func spawnParti():
var parti = ghostParti.instantiate()
add_child(parti)
parti.top_level = true
parti.global_position = global_position
func _physics_process(delta):
if ghostFrame + 1 >= savedInputs.size() and ghostMode:
ghostFrame = 0
trail.points = []
$Sprite.visible = false
ghosting = false
spawnParti()
global_position = startPos
velocity = Vector2.ZERO
await get_tree().create_timer(3).timeout
spawnParti()
ghosting = true
$Sprite.visible = true
2024-02-24 12:12:57 -06:00
2024-03-13 16:15:55 -05:00
if (ghosting or !ghostMode) and can_move:
var space_state = get_world_2d().direct_space_state
2024-02-26 08:28:11 -06:00
2024-03-13 16:15:55 -05:00
if ghostFrame == 0:
spawnParti()
ghostFrame += 1
direction = round(getAxis("left", "right"))
2024-02-24 12:12:57 -06:00
2024-03-13 16:15:55 -05:00
wallKayote -= delta
2024-03-17 21:56:16 -05:00
if is_on_floor() and !landed:
velocity.y = 0
2024-03-13 16:15:55 -05:00
if not is_on_floor():
if velocity.y < 2000:
velocity.y += gravity * delta / getGravMulti()
floorTime = 0
kayote -= delta
2024-03-17 21:56:16 -05:00
if lastFloor:
if "velocity" in lastFloor:
velocity += lastFloor.velocity
lastFloor = null
2024-03-13 16:15:55 -05:00
else:
2024-03-17 21:56:16 -05:00
#velocity.y = 0
doubleWallJumped = false
2024-03-13 16:15:55 -05:00
kayote = 0.3
floorTime += delta
jumps = MAX_JUMPS
2024-02-24 12:12:57 -06:00
falling = false
2024-03-17 21:56:16 -05:00
for collisionNumb in get_slide_collision_count():
var collision = get_slide_collision(collisionNumb)
var object = collision.get_collider()
if abs(collision.get_angle()) <= floor_max_angle:
lastFloor = object
if velocity.y <= 0:
forceLowGrav = false
2024-02-26 08:28:11 -06:00
2024-03-13 16:15:55 -05:00
if isWallSliding():
wallKayote = 0.3
falling = false
if actionJustPressed("respawn") or position.y > 5000:
die()
2024-02-26 08:28:11 -06:00
2024-03-13 16:15:55 -05:00
if actionJustPressed("jump"):
if wallKayote > 0 and not is_on_floor():
2024-03-17 21:56:16 -05:00
if doubleWallJumped:
wallKayote = 0
else:
doubleWallJumped = true
wallKayote += 0.1
2024-03-13 16:15:55 -05:00
if actionPressed("down"):
launch(get_wall_normal().x * SPEED * 1.75)
velocity.y = clamp((velocity.y / 2) + JUMP_VELOCITY / 1.8, -INF, JUMP_VELOCITY / 1.8)
else:
2024-03-17 21:56:16 -05:00
launch(get_wall_normal().x * SPEED * 1.4)
2024-03-13 16:15:55 -05:00
velocity.y = clamp(velocity.y + JUMP_VELOCITY, -INF, JUMP_VELOCITY)
2024-03-17 21:56:16 -05:00
Jumped.emit()
2024-03-13 16:15:55 -05:00
2024-03-17 21:56:16 -05:00
#if result and "velocity" in result.collider:
#velocity.x += result.collider.velocity.x
2024-03-13 16:15:55 -05:00
elif jumps > 0:
velocity.y = clamp(velocity.y + JUMP_VELOCITY, -INF, JUMP_VELOCITY)
2024-03-17 21:56:16 -05:00
doubleWallJumped = false
2024-03-13 16:15:55 -05:00
if kayote < 0:
jumps -= 1
else:
var query = PhysicsRayQueryParameters2D.create(global_position + (Vector2.UP * 32), global_position + (Vector2.DOWN * 64))
query.exclude = [self]
var result = space_state.intersect_ray(query)
if result and "velocity" in result.collider:
velocity += result.collider.velocity
falling = false
2024-03-17 21:56:16 -05:00
if actionPressed("down") and kayote > 0 and abs(velocity.x) < SPEED * 1.5:
launch(direction * SPEED * 1.5)
2024-03-13 16:15:55 -05:00
kayote = 0
2024-03-17 21:56:16 -05:00
Jumped.emit()
2024-03-13 16:15:55 -05:00
if actionJustPressed("down") and not falling and not isWallSliding():
falling = true
velocity.y = clamp(velocity.y + FALL_SPEED, FALL_SPEED, INF)
if isWallSliding():
var upDown = clamp(getAxis("up", "down"), -0.5, 1)
var holdMulti = (upDown * 2) + 1
var query = PhysicsRayQueryParameters2D.create(global_position + (get_wall_normal() * 32), global_position + (get_wall_normal() * -64))
query.exclude = [self]
var result = space_state.intersect_ray(query)
2024-03-17 21:56:16 -05:00
2024-03-13 16:15:55 -05:00
if result and "velocity" in result.collider and abs(result.collider.velocity.x) > 50:
velocity.y = lerpf(velocity.y, 0, delta * 30)
else:
velocity.y = lerpf(velocity.y, clamp(velocity.y, JUMP_VELOCITY, 100 * holdMulti), delta * 10)
var finalSpeed = clamp(abs(velocity.x), SPEED, INF)
if floorTime > 0.05:
finalSpeed = clamp(lerp(finalSpeed, SPEED, delta * 20), SPEED, INF)
velocity.x = lerp(velocity.x, direction * finalSpeed, delta * ACCEL)
if abs(velocity.x) < abs(addedveloc):
addedveloc = lerp(addedveloc, velocity.x, ACCEL * 2 * delta)
velocity.x += addedveloc * delta * 15
2024-03-17 21:56:16 -05:00
if abs(velocity.x) < abs(forcedVeloc):
forcedVeloc = lerp(forcedVeloc, velocity.x, ACCEL * 2 * delta)
velocity.x += forcedVeloc * delta * 35
2024-03-13 16:15:55 -05:00
2024-03-17 21:56:16 -05:00
addedveloc = lerpf(addedveloc, 0, delta * 6)
if not is_on_floor():
forcedVeloc = lerpf(forcedVeloc, 0, delta)
else:
forcedVeloc = lerpf(forcedVeloc, 0, delta * 5)
2024-03-13 16:15:55 -05:00
2024-03-17 21:56:16 -05:00
landed = is_on_floor()
2024-03-13 16:15:55 -05:00
move_and_slide()
2024-03-17 21:56:16 -05:00
func _process(_delta):
2024-03-13 16:15:55 -05:00
if ghostMode:
if velocity.length() > 5:
trail.add_point(global_position)
elif trail.get_point_count() > 0:
trail.remove_point(0)
if trail.get_point_count() > 100:
trail.remove_point(0)
2024-03-17 21:56:16 -05:00
func _on_squish_detection_body_shape_entered(_body_rid, _body, _body_shape_index, _local_shape_index):
2024-03-13 16:15:55 -05:00
squishers += 1
if squishers >= 2:
die()
2024-02-22 00:10:13 -06:00
2024-03-17 21:56:16 -05:00
func _on_squish_detection_body_shape_exited(_body_rid, _body, _body_shape_index, _local_shape_index):
2024-03-13 16:15:55 -05:00
squishers -= 1