class_name BoxBoy extends CharacterBody2D @onready var _sprite = $AnimatedSprite2D const MOVE_FORCE: int = 300 const JUMP_FORCE: int = 500 #about 4 tiles const GRAVITY_RISING: int = 15 const GRAVITY_FALLING: int = 30 #bouncy platform const BOUNCE_FORCE: int = -820 #about 10 tiles var just_bounced: bool = false #allow max bounce height (i.e. ignore jump input) #floaty field const FLOATY_RISING: int = -10 const FLOATY_FALLING: int = -30 const FLOATY_HEIGHT_CLEAR: float = 1_000_000_000 var floaty_height: float = FLOATY_HEIGHT_CLEAR #limits const MAX_MOVE_SPEED: int = 300 const MAX_FALL_SPEED: int = 500 const MAX_FLOATY_SPEED: int = -300 #boilerplate func _ready(): clear_floaty_height() _sprite.play("idle", 1) #movement func _physics_process(_delta) -> void: #print(position.y, " ", floaty_height) #jump input if is_on_floor() and Input.is_action_just_pressed("input_jump"): velocity.y -= JUMP_FORCE #vertical movement elif is_floaty() and position.y >= floaty_height: #below the floaty surface if is_rising(): velocity.y += FLOATY_RISING else: velocity.y += FLOATY_FALLING elif is_floaty() and position.y < floaty_height: ##above the floaty surface, but still floaty if is_rising(): velocity.y += GRAVITY_FALLING #rise slower? else: var diff = floaty_height - position.y position.y += log(diff) velocity.y = 0 #normally, fall faster than you rise elif is_rising() and (Input.is_action_pressed("input_jump") or just_bounced): velocity.y += GRAVITY_RISING else: velocity.y += GRAVITY_FALLING just_bounced = false #sideways movement var move_dir = Input.get_axis("input_left", "input_right") if move_dir: _sprite.flip_h = move_dir < 0 #fancy HD 4K graphics velocity.x += MOVE_FORCE * move_dir #no input, slow down elif velocity.x != 0: velocity.x = log(abs(velocity.x)) * sign(velocity.x) #terminal velocity (in all directions) if position.y > floaty_height and velocity.y < MAX_FLOATY_SPEED: velocity.y = MAX_FLOATY_SPEED if is_falling() and velocity.y > MAX_FALL_SPEED: velocity.y = MAX_FALL_SPEED if abs(velocity.x) > MAX_MOVE_SPEED: velocity.x = MAX_MOVE_SPEED * sign(velocity.x) #do the thing move_and_slide() #animation stuff func _on_animation_finished() -> void: if randf() < 0.2: _sprite.play("idle_glance", 2) else: _sprite.play("idle", 2) #utils #func is_airborne() -> bool: return !is_on_floor() func is_rising() -> bool: return velocity.y < 0 func is_falling() -> bool: return velocity.y >= 0 #external actions func apply_bounce() -> void: velocity.y = BOUNCE_FORCE just_bounced = true func set_floaty_height(height: float) -> void: floaty_height = height func clear_floaty_height() -> void: floaty_height = FLOATY_HEIGHT_CLEAR func is_floaty() -> bool: return floaty_height != FLOATY_HEIGHT_CLEAR