godot-platformer-template/Player.gd

117 lines
3.3 KiB
GDScript3
Raw Normal View History

2020-11-23 01:06:21 +08:00
extends KinematicBody2D
# list of things we should to implement:
# https://twitter.com/MaddyThorson/status/1238338584479813637
# Done:
# 1. Coyote time.
# 2. Jump buffering.
# 3. Halved gravity jump peak.
# TODO:
# 4. Jump corner correction.
# 8. You can actually wall jump 2 pixels from a wall.
const COYOTE_TIME = 0.1
const BUFFER_JUMP_TIME = 0.1
const VAR_JUMP_TIME = 0.2 # hold jump to jump higher
const JUMP_SPEED = -160
const MAX_FALL = 160
const GRAVITY = 1000
const HALF_GRAV_THRESHOLD = 40
const MAX_RUN = 100
const RUN_ACCEL = 800
const RUN_ACCEL_AIR_MULT = 0.8
var speed = Vector2.ZERO
var buffer_jump_grace = 0
var coyote_jump_grace = 0
var var_jump = 0
onready var sprite = $Sprite
onready var camera = $Camera2D
onready var area_camera = $AreaCamera2D
2020-11-23 01:06:21 +08:00
func _physics_process(delta):
if buffer_jump_grace > 0:
buffer_jump_grace -= delta
if coyote_jump_grace > 0:
coyote_jump_grace -= delta
if var_jump > 0:
var_jump -= delta
var on_ground = is_on_floor()
if on_ground:
coyote_jump_grace = COYOTE_TIME
else:
if Input.is_action_just_pressed("player_jump"):
buffer_jump_grace = BUFFER_JUMP_TIME
# Vertical Control
if (coyote_jump_grace > 0 && (Input.is_action_just_pressed("player_jump") || buffer_jump_grace > 0)):
# Jumping
buffer_jump_grace = 0
coyote_jump_grace = 0
var_jump = VAR_JUMP_TIME
speed.y = JUMP_SPEED
else:
# Gravity
var mult = 1
if Input.is_action_pressed("player_jump") && abs(speed.y) <= HALF_GRAV_THRESHOLD:
mult = 0.5
# speed.y += min(MAX_FALL, GRAVITY * mult * delta)
speed.y = move_toward(speed.y, MAX_FALL, GRAVITY * mult * delta)
# Variable Jumping
if Input.is_action_just_released("player_jump"):
var_jump = 0
if var_jump > 0 && Input.is_action_pressed("player_jump"):
speed.y = JUMP_SPEED
# Horizontal Control
var x_input = Input.get_action_strength("player_right") - Input.get_action_strength("player_left")
if x_input != 0:
sprite.flip_h = x_input < 0
var accel = RUN_ACCEL
if !on_ground:
accel *= RUN_ACCEL_AIR_MULT
speed.x = move_toward(speed.x, x_input * MAX_RUN, accel * delta)
# Apply movement
speed = move_and_slide(speed, Vector2.UP)
func _on_CameraLimitArea_body_shape_entered(body_id, body, body_shape, area_shape):
if body is TileMap:
return
var body_shape_owner_id = body.shape_find_owner(body_shape)
var body_shape_owner = body.shape_owner_get_owner(body_shape_owner_id)
var body_shape_2d = body.shape_owner_get_shape(body_shape_owner_id, 0)
var body_global_transform = body_shape_owner.global_transform
var area_shape_owner_id = shape_find_owner(area_shape)
var area_shape_owner = shape_owner_get_owner(area_shape_owner_id)
var area_shape_2d = shape_owner_get_shape(area_shape_owner_id, 0)
var area_global_transform = area_shape_owner.global_transform
var collision_points = area_shape_2d.collide_and_get_contacts(area_global_transform,
body_shape_2d,
body_global_transform)
print(body_shape_2d.extents, area_shape_2d.extents)
area_camera.limit_left = 0
area_camera.limit_top = 0
area_camera.limit_right = 320
area_camera.limit_bottom = 176
area_camera.make_current()
print(area_global_transform.x.x, area_global_transform.y.y, area_global_transform.y.x, area_global_transform.x.y)
func _on_CameraLimitArea_body_shape_exited(body_id, body, body_shape, area_shape):
camera.make_current()