Pour le moment et par manque de gameplay, je préfère choisir de ne pas limiter le prout de quelque manière que ce soit. J'ai donc délibérément supprimé du HUD la geauge de prout et aussi le fait que le prout se recharge. Maintenant les fromages sont juste des fromages. Une sorte de truc à ramasser mais qui sert à rien. Le gameplay après le juyce.
667 lines
24 KiB
GDScript
667 lines
24 KiB
GDScript
class_name Princess extends CharacterBody2D
|
|
|
|
## The player listens for input actions appended with this suffix.[br]
|
|
## Used to separate controls for multiple players in splitscreen.
|
|
@export var action_suffix := ""
|
|
|
|
var gravity: int = ProjectSettings.get("physics/2d/default_gravity")
|
|
@onready var wall_detect_left := $wall_detect_left as RayCast2D
|
|
@onready var wall_detect_right := $wall_detect_right as RayCast2D
|
|
@onready var wall_detect_left2 := $wall_detect_left2 as RayCast2D
|
|
@onready var wall_detect_right2 := $wall_detect_right2 as RayCast2D
|
|
@onready var wall_detect_left3 := $wall_detect_left3 as RayCast2D
|
|
@onready var wall_detect_right3 := $wall_detect_right3 as RayCast2D
|
|
@onready var wall_far_detect_left := $wall_far_detect_left as RayCast2D
|
|
@onready var wall_far_detect_left2 := $wall_far_detect_left2 as RayCast2D
|
|
@onready var wall_far_detect_left3 := $wall_far_detect_left3 as RayCast2D
|
|
@onready var wall_far_detect_right := $wall_far_detect_right as RayCast2D
|
|
@onready var wall_far_detect_right2 := $wall_far_detect_right2 as RayCast2D
|
|
@onready var wall_far_detect_right3 := $wall_far_detect_right3 as RayCast2D
|
|
|
|
@onready var ground_far_detect := $ground_far_detect as RayCast2D
|
|
@onready var ground_far_detect2 := $ground_far_detect2 as RayCast2D
|
|
@onready var animation := $AnimatedSprite2D as AnimatedSprite2D
|
|
@onready var camera := $Camera2D as Camera2D
|
|
@onready var death_animation := $"Death player" as AnimationPlayer
|
|
|
|
@onready var nuage_prout := $"GPUParticles2D" as GPUParticles2D
|
|
@onready var nuage_jump := $"GPUParticles2DJump" as GPUParticles2D
|
|
|
|
################################################################################
|
|
#
|
|
# Constantes de déplacement à pimper dans l'inspecteur
|
|
#
|
|
################################################################################
|
|
@export var WALKING_SPEED = 155
|
|
@export var FALLING_SPEED = 230
|
|
@export var JUMPING_SPEED = 220
|
|
var DASH_SPEED = WALKING_SPEED * 2
|
|
@export var X_SPEED_TABLE = [0, 0.1, 0.15, 0.3, 0.4, 0.7, 1]
|
|
@export var X_SPEED_DECEL = [0, 0.1, 0.6, 1]
|
|
@export var FALL_SPEED_TABLE = [0, 0.1, 0.15, 0.2, 0.3, 0.6, 0.9, 1]
|
|
@export var JUMP_SPEED_TABLE = [0.2, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
|
|
@export var KICK_SPEED_TABLE = [0.5, 0.6, 0.7, 0.8, 0.9, 1.1]
|
|
@export var DASH_SPEED_TABLE = [0.5, 0.6, 0.7, 0.8, 0.9, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3]
|
|
|
|
# Nombre d'incrément à rajouter lorsque la touche de saut est maintenue
|
|
@export var JUMPING_COUNTER_REFILL = 2
|
|
# Tous les combien d'incréments rajouter un refill sur le compteur
|
|
@export var JUMPING_KEY_COUNTER_THRESHOLD = 3
|
|
@export var KICK_JUMP_LIMITER = 0.75
|
|
@export var KICK_REFILL_MAX_AMOUNT = 10
|
|
|
|
# Nombre de frames coyote durant lesquelle le joueur peut encore sauter
|
|
# sans encore être au sol
|
|
@export var COYOTE_LENGTH := 5
|
|
@export var COYOTE_GRAB_LENGTH := 15
|
|
|
|
# Différence de vitesse de ralentissement entre le sol et l'air
|
|
@export var WALK_INCR_GROUND : int = 1
|
|
@export var WALK_INCR_AIR : int = 3
|
|
|
|
@export var MAX_FARTS : int = 3
|
|
|
|
signal cheese_collected(speed:float) # utilisé pour remplir le HUD qui apelera
|
|
# ensuite la fonction reload_fart quand il aura fini
|
|
signal lactase_collected() # utilisé pour vider le HUD qui apelera
|
|
# ensuite la fonction kill_farts quand il aura fini
|
|
signal dash_fart() # utilisé pour vider le HUD
|
|
signal princesse_is_dead() # signal au jeu de recharger la scene
|
|
|
|
var locked = true
|
|
var locked_controls = true
|
|
|
|
################################################################################
|
|
#
|
|
# Etat de la princesse
|
|
#
|
|
################################################################################
|
|
var dead = false
|
|
# Direction dans laquelle est positioné le personnage.
|
|
var direction : int = 1
|
|
|
|
var walking : bool = false # si le joueur veut marche ou non
|
|
var walking_step: int = -1 # où la princesse en est dans son tableau d'accel
|
|
var walk_incr_reserve : int = 0 # utilisé pour la différence ralentissement air/sol
|
|
var init_decel: bool = true # utilisé pour initialiser la décélération
|
|
var init_direction_change = true # utilisé pour initialiser le changement de direction
|
|
var near_cliff = false
|
|
|
|
# variables d'état relatives au saut
|
|
var jumping : bool = false # Princesse est-elle en train de sauter ?
|
|
var need_jump : bool = false # Le joueur veut-il sauter et peut il ?
|
|
var jumping_step : int = -1 # Où en est la princesse dans son tableau d'accel
|
|
var jump_key_counter : int = 0 # Où en est-on du refil ?
|
|
var collide_ground_far_detect = false # est-ce que les collisioneurs du sol sont en contact avec ?
|
|
|
|
# variables d'état relatives au kick mural
|
|
var collide_wall_far_detect = false # est-ce que les collisioneurs du sol sont en contact avec ?
|
|
var need_kicking : bool = false # Le joueur veut-il sauter et peut il ?
|
|
var kicking : bool = false
|
|
var kick_step : int = -1
|
|
var kick_direction : int = 1
|
|
var last_kick_key_counter : int = 0
|
|
|
|
# Coyote time
|
|
var coyote_ground = []
|
|
var coyote_grab = []
|
|
|
|
# variable d'état relative à la gravité
|
|
var falling_step : int = -1 # Où en est la princess dans son acceleration de chute ?
|
|
|
|
# Variables d'état relative à l'accroche au mur
|
|
var pressing_wall_left = false # Princesse est elle en contact avec un mur à gauche?
|
|
var pressing_wall_right = false # Princesse est elle en contact avec un mur droite ?
|
|
var pressing_wall = false # Princesse est elle en contact avec un mur ?
|
|
var grab_wall = false # Je joueur veut-il et peut-il s'accrocher au mur ?
|
|
|
|
# Variables d'état relative au dash
|
|
var dashing : bool = false
|
|
var dash_step : int = -1
|
|
var dash_direction_x : int = 1
|
|
var dash_direction_y : int = 1
|
|
|
|
# Variables d'état relative au crouch
|
|
var crouch : bool = false
|
|
|
|
func copy_from(other : Princess):
|
|
direction = other.direction
|
|
walking = false
|
|
walking_step = other.walking_step
|
|
walk_incr_reserve = other.walk_incr_reserve
|
|
init_decel = other.init_decel
|
|
init_direction_change = other.init_direction_change
|
|
jumping = other.jumping
|
|
need_jump = other.need_jump
|
|
need_kicking = other.need_kicking
|
|
jumping_step = other.jumping_step
|
|
jump_key_counter = other.jump_key_counter
|
|
kicking = other.kicking
|
|
kick_step = other.kick_step
|
|
kick_direction = other.kick_direction
|
|
coyote_ground = other.coyote_ground
|
|
coyote_grab = other.coyote_grab
|
|
falling_step = other.falling_step
|
|
pressing_wall_left = other.pressing_wall_left
|
|
pressing_wall_right = other.pressing_wall_right
|
|
pressing_wall = other.pressing_wall
|
|
grab_wall = other.grab_wall
|
|
dashing = other.dashing
|
|
dash_step = other.dash_step
|
|
dash_direction_x = other.dash_direction_x
|
|
dash_direction_y = other.dash_direction_y
|
|
near_cliff = other.near_cliff
|
|
|
|
################################################################################
|
|
#
|
|
# Gestion d'avec quoi Princesse collisionne
|
|
#
|
|
################################################################################
|
|
const PLATFORM_LAYER = 1 << (5 - 1) # collision layer 5 -> plateformes
|
|
const PICS_BLOCK_LAYER = 1 << (6 - 1) # collision layer 6 -> pics
|
|
const CHEESE_LAYER = 1 << (6 - 1) # collision layer 7 -> fromages
|
|
var layer_of_collision = null
|
|
|
|
func init_walk_state():
|
|
walk_incr_reserve = 0
|
|
walking_step = -1
|
|
init_decel = false
|
|
|
|
func walk(direction:int) -> float:
|
|
# Fait marcher le personnage
|
|
|
|
# Le personnage ne se déplace pas dans les cas suivants:
|
|
if kicking or kicking or dashing or get_coyote(coyote_grab):
|
|
init_walk_state()
|
|
return velocity.x
|
|
|
|
if not get_coyote(coyote_grab) and pressing_wall:
|
|
return WALKING_SPEED * direction *1.2
|
|
|
|
# Si le personnage est dans l'air, il aura une friction plus faible lors de
|
|
# la décélération.
|
|
var threshold = WALK_INCR_AIR
|
|
if is_on_floor():
|
|
threshold = WALK_INCR_GROUND
|
|
|
|
# Un changement de direction implique de perdre la vélocité dans la direction
|
|
# précédente avant de repartir dans la direction que l'on veut.
|
|
# ça ne change rien pour le nombre de frames nécéssaires pour accélérer dans
|
|
# tous les cas. Mais le feeling est meilleur.
|
|
var direction_change: bool = (direction > 0 and velocity.x < 0) or (direction < 0 and velocity.x > 0)
|
|
if direction_change:
|
|
if init_direction_change:
|
|
init_direction_change = false
|
|
walk_incr_reserve += 1
|
|
# appliquer le nombre de frames nécéssaire pour décrémenter, dépend
|
|
# de où est le personnage (air vs sol)
|
|
if walk_incr_reserve >= threshold:
|
|
walk_incr_reserve = 0
|
|
walking_step-=1
|
|
else:
|
|
init_direction_change = true
|
|
|
|
# Si le joueur décide de marcher alors, le compteur de pas doit s'incrémenter
|
|
# Si le joueur ne veut plus marcher, alors, le compteur de pas décrémente
|
|
# La vitese choisie est le numéro d'étape dans le tableau correspondant
|
|
# X_SPEED_TABLE pour l'accélération
|
|
# X_SPEED_DECEL pour la décélération
|
|
var table = X_SPEED_TABLE
|
|
if not walking:
|
|
table = X_SPEED_DECEL
|
|
|
|
# dans le cas où le personnage est propulsé par une force extérieure et
|
|
# qu'il n'y a pas d'input du joueur. Lorsque le joueur va vouloir reprendre
|
|
# la main, il faut démarrer à la bonne vélocité
|
|
var abs_v_x = abs(velocity.x)
|
|
if abs_v_x != 0:
|
|
if walking_step == -1:
|
|
# trouver l'indice le plus proche de la vitesse courante
|
|
for index in range(0, table.size()-1):
|
|
var speed_i = table[walking_step] * WALKING_SPEED
|
|
var speed_i1 = table[walking_step+1] * WALKING_SPEED
|
|
# lorsque l'on a trouvé l'indice le bon endroit dans le tableau, alors
|
|
# on renvoie l'indice trouvé
|
|
if abs_v_x == speed_i:
|
|
walking_step = index
|
|
if abs_v_x == speed_i1:
|
|
walking_step = index+1
|
|
if abs_v_x > speed_i and abs_v_x < speed_i1:
|
|
walking_step = index+1
|
|
# si rien n'est trouvé, alors on initialise l'indice au maximum possible
|
|
if walking_step == -1:
|
|
walking_step = table.size() - 1
|
|
|
|
if walking:
|
|
walk_incr_reserve += 1
|
|
# appliquer le nombre de frames nécéssaire pour décrémenter, dépend
|
|
# de où est le personnage (air vs sol)
|
|
if walking_step > 2:
|
|
if walk_incr_reserve >= threshold:
|
|
walk_incr_reserve = 0
|
|
walking_step = min(walking_step+1, X_SPEED_TABLE.size() -1)
|
|
else:
|
|
walking_step+=1
|
|
init_decel = true
|
|
else:
|
|
# Lors de la première frame de la décélération, initialiser la valeur
|
|
# du compteur d'incrément en haut du tableau de décélération
|
|
if init_decel:
|
|
walking_step = min(walking_step, X_SPEED_DECEL.size() - 1)
|
|
init_decel = false
|
|
if near_cliff:
|
|
walking_step = 0
|
|
|
|
|
|
|
|
# Si le compteur d'incrément est supérieur ou égal à zéro, c'est qu'il
|
|
# faut bouger, donc il est nécéssaire en premier temps de récupérer la vitesse
|
|
# à l'indice courant. Puis si le joueur ne veut plus accélérer, alors, appliquer
|
|
# la décélération
|
|
if walking_step >= 0:
|
|
var speed = table[walking_step] * WALKING_SPEED
|
|
if not walking:
|
|
walk_incr_reserve += 1
|
|
# appliquer le nombre de frames nécéssaire pour décrémenter, dépend
|
|
# de où est le personnage (air vs sol)
|
|
if walk_incr_reserve >= threshold:
|
|
walk_incr_reserve = 0
|
|
walking_step-=1
|
|
if direction_change and walking:
|
|
# dans le cas du changement de direction,
|
|
return speed * direction + velocity.x
|
|
else:
|
|
return speed * direction
|
|
return velocity.x
|
|
|
|
func fall() -> float:
|
|
# fait tomber princesse
|
|
if jumping or kicking or dashing:
|
|
stop_fall()
|
|
return velocity.y
|
|
var intertia = 0
|
|
if velocity.y < 0:
|
|
intertia = max(velocity.y, -FALLING_SPEED)
|
|
if is_on_floor_only():
|
|
if get_floor_normal()[0] < 0: # pente à gauche
|
|
if direction >= 0:# on va à droite, désactive la gravité
|
|
falling_step = -1
|
|
return velocity.y
|
|
else: # on va à gauche, gravité à fond
|
|
falling_step = FALL_SPEED_TABLE.size()-1
|
|
else: # pente à droite
|
|
if direction > 0:# on va à droite, active la gravité à fond
|
|
falling_step = FALL_SPEED_TABLE.size()-1
|
|
else: # on va à gauche, désactive la gravité
|
|
falling_step = -1
|
|
return velocity.y
|
|
else:
|
|
if get_coyote(coyote_grab) and not crouch:
|
|
falling_step = max(falling_step-1, 1)
|
|
else:
|
|
if intertia < 0 and intertia + FALL_SPEED_TABLE[falling_step] * FALLING_SPEED >0:
|
|
falling_step = 0
|
|
falling_step = min(falling_step+1, FALL_SPEED_TABLE.size()-1)
|
|
return intertia + FALL_SPEED_TABLE[falling_step] * FALLING_SPEED
|
|
|
|
func stop_fall() -> void:
|
|
falling_step = -1
|
|
|
|
func jump() -> float:
|
|
# fait sauter princesse
|
|
if not jumping or kicking or dashing:
|
|
return velocity.y
|
|
|
|
if not is_on_ceiling() and jump_key_counter > 0 and jump_key_counter % JUMPING_KEY_COUNTER_THRESHOLD == 0:
|
|
jumping_step = min(
|
|
jumping_step + JUMPING_COUNTER_REFILL,
|
|
JUMP_SPEED_TABLE.size() -1
|
|
)
|
|
|
|
if jumping_step > 0:
|
|
jumping_step -= 1
|
|
return JUMP_SPEED_TABLE[jumping_step] * JUMPING_SPEED * -1
|
|
else:
|
|
end_jump()
|
|
return velocity.y
|
|
|
|
func end_jump():
|
|
# termine le saut de Princesse
|
|
jumping = false
|
|
jumping_step = -1
|
|
|
|
func kick() -> void:
|
|
# fait kicker la princesse
|
|
if not kicking or dashing:
|
|
return
|
|
|
|
if not is_on_ceiling() and jump_key_counter > last_kick_key_counter and jump_key_counter < KICK_REFILL_MAX_AMOUNT :
|
|
last_kick_key_counter = jump_key_counter
|
|
kick_step = KICK_SPEED_TABLE.size() -1
|
|
else:
|
|
last_kick_key_counter = 1000
|
|
|
|
if kick_step > 0:
|
|
kick_step -= 1
|
|
velocity.y = KICK_SPEED_TABLE[kick_step] * JUMPING_SPEED * -1 * KICK_JUMP_LIMITER
|
|
velocity.x = KICK_SPEED_TABLE[kick_step] * WALKING_SPEED * kick_direction
|
|
else:
|
|
cancel_kick()
|
|
|
|
func cancel_kick() -> void:
|
|
kick_step = -1
|
|
kicking=false
|
|
|
|
func dash() -> void:
|
|
# fait dasher la princesse
|
|
if not dashing:
|
|
return
|
|
|
|
if dash_step > 0:
|
|
dash_step -= 1
|
|
velocity.y = DASH_SPEED_TABLE[dash_step] * DASH_SPEED * dash_direction_y
|
|
velocity.x = DASH_SPEED_TABLE[dash_step] * DASH_SPEED * dash_direction_x
|
|
else:
|
|
cancel_dash()
|
|
|
|
func cancel_dash() -> void:
|
|
dash_step = -1
|
|
dashing=false
|
|
nuage_prout.emitting = false
|
|
|
|
func choose_animation_orientation() -> void:
|
|
# Oriente l'animation correctement en fonction de laquelle on joue et de
|
|
# la direction du personnage
|
|
if not is_zero_approx(velocity.x):
|
|
if velocity.x > 0.0:
|
|
animation.scale.x = 1.0
|
|
else:
|
|
animation.scale.x = -1.0
|
|
|
|
if get_coyote(coyote_grab):
|
|
if pressing_wall_left:
|
|
animation.scale.x = 1
|
|
elif pressing_wall_right:
|
|
animation.scale.x = -1
|
|
|
|
func play_animation() -> void:
|
|
# Joue l'animation de Princesse et dans le bon sens
|
|
choose_animation_orientation()
|
|
var anim := get_new_animation()
|
|
if anim != animation.animation:
|
|
animation.animation = anim
|
|
animation.play()
|
|
|
|
func move_and_handle_collisions() -> void:
|
|
if kicking or dashing:
|
|
end_jump()
|
|
if dashing:
|
|
cancel_kick()
|
|
|
|
# Bouge Princesse et réagis aux éléments avec lesquels elle rentre en collision
|
|
move_and_slide()
|
|
for i in get_slide_collision_count():
|
|
var collider : KinematicCollision2D= get_slide_collision(i)
|
|
var tile_rid = collider.get_collider_rid()
|
|
layer_of_collision = PhysicsServer2D.body_get_collision_layer(tile_rid)
|
|
if layer_of_collision == PICS_BLOCK_LAYER:
|
|
death()
|
|
|
|
func get_coyote(table: Array):
|
|
var result = false
|
|
for i in table:
|
|
result = result or i
|
|
return result
|
|
|
|
func read_input() -> void:
|
|
# Lis les commandes du joueur pour piloter Princesse
|
|
if locked or locked_controls:
|
|
return
|
|
|
|
# le joueur veut-il accélérer sa chute si il s'accroche au mur?
|
|
crouch = Input.is_action_pressed("move_down" + action_suffix)
|
|
|
|
# Le joueur veut-il sauter ou kicker ?
|
|
if Input.is_action_just_pressed("jump" + action_suffix):
|
|
# Peut-il sauter ?
|
|
if not kicking and collide_ground_far_detect or (is_on_floor() or get_coyote(coyote_ground)):
|
|
need_jump=true
|
|
need_kicking=false
|
|
else:
|
|
need_jump=false
|
|
# Peut-il kicker ?
|
|
if not kicking and (collide_wall_far_detect or get_coyote(coyote_grab)):
|
|
need_kicking=true
|
|
need_jump=false
|
|
else:
|
|
need_kicking=false
|
|
|
|
# Dès qu'il peut et veut kicker, déclencher le kick
|
|
if need_kicking and get_coyote(coyote_grab):
|
|
if not kicking:
|
|
need_kicking=false
|
|
nuage_jump.restart()
|
|
nuage_jump.emitting = true
|
|
kicking=true
|
|
coyote_grab = [false]
|
|
last_kick_key_counter = 0
|
|
kick_step = KICK_SPEED_TABLE.size()-1
|
|
if pressing_wall_left:
|
|
kick_direction = 1
|
|
else:
|
|
kick_direction = -1
|
|
|
|
# Dès qu'il peut et veut sauter, déclencher le saut
|
|
if need_jump and (is_on_floor() or get_coyote(coyote_ground)):
|
|
need_jump = false
|
|
if not jumping:
|
|
nuage_jump.restart()
|
|
nuage_jump.emitting = true
|
|
jumping = true
|
|
jumping_step = JUMP_SPEED_TABLE.size()-1
|
|
|
|
# Si il continue d'appuyer, lui rallonger son saut
|
|
if Input.is_action_pressed("jump" + action_suffix):
|
|
jump_key_counter += 1
|
|
else:
|
|
jump_key_counter = 0
|
|
|
|
# Le joueur veut-il marcher ?
|
|
walking = (
|
|
Input.is_action_pressed("move_left" + action_suffix) or
|
|
Input.is_action_pressed("move_right" + action_suffix)
|
|
)
|
|
# Calculer dans quelle direction il veut marcher
|
|
if walking:
|
|
var axis = Input.get_axis(
|
|
"move_left" + action_suffix,
|
|
"move_right" + action_suffix
|
|
)
|
|
if not is_zero_approx(axis):
|
|
if axis < 0:
|
|
if direction == 1 and is_on_floor():
|
|
nuage_jump.restart()
|
|
nuage_jump.emitting = true
|
|
direction = -1
|
|
else:
|
|
if direction == -1 and is_on_floor():
|
|
nuage_jump.restart()
|
|
nuage_jump.emitting = true
|
|
direction = 1
|
|
else:
|
|
if kicking:
|
|
direction = kick_direction
|
|
|
|
# Le joueur veut-il et peut-il s'accrocher au mur ?
|
|
if pressing_wall:
|
|
if not grab_wall :
|
|
grab_wall = (
|
|
(pressing_wall_left and direction == -1)
|
|
or
|
|
(pressing_wall_right and direction == 1)
|
|
)
|
|
else:
|
|
# Désactivation du grab wall
|
|
if walking:
|
|
if pressing_wall_left and direction == 1:
|
|
grab_wall = false
|
|
if pressing_wall_right and direction == -1:
|
|
grab_wall = false
|
|
if kicking or dashing:
|
|
grab_wall = false
|
|
else:
|
|
grab_wall = false
|
|
coyote_grab = [false]
|
|
|
|
|
|
if Input.is_action_just_pressed("dash" + action_suffix):
|
|
if not dashing:
|
|
var axis_x = Input.get_axis(
|
|
"move_left" + action_suffix,
|
|
"move_right" + action_suffix
|
|
)
|
|
var axis_y = Input.get_axis(
|
|
"move_up" + action_suffix,
|
|
"move_down" + action_suffix
|
|
)
|
|
if not is_zero_approx(axis_x):
|
|
if axis_x < 0:
|
|
dash_direction_x = -1
|
|
else:
|
|
dash_direction_x = 1
|
|
else:
|
|
dash_direction_x = 0
|
|
if not is_zero_approx(axis_y):
|
|
if axis_y < 0:
|
|
dash_direction_y = -1
|
|
else:
|
|
dash_direction_y = 1
|
|
else:
|
|
dash_direction_y = 0
|
|
|
|
# Ne dasher que si une direction est donnée avec le joystick
|
|
if dash_direction_x or dash_direction_y:
|
|
Input.start_joy_vibration(0, 1, 0.5, 0.2)
|
|
dashing = true
|
|
nuage_prout.restart()
|
|
nuage_prout.emitting = true
|
|
dash_fart.emit()
|
|
# Limiter le dash en diagonnale car sinon il est trop grand
|
|
# par rapport à un dash dans une seule direction
|
|
if dash_direction_x and dash_direction_y:
|
|
dash_step = DASH_SPEED_TABLE.size()-2
|
|
else:
|
|
dash_step = DASH_SPEED_TABLE.size()-1
|
|
|
|
func compute_state() -> void:
|
|
collide_ground_far_detect = ground_far_detect.is_colliding() or ground_far_detect2.is_colliding()
|
|
near_cliff = collide_ground_far_detect and not(ground_far_detect.is_colliding() and ground_far_detect2.is_colliding())
|
|
collide_wall_far_detect = (
|
|
wall_far_detect_left.is_colliding() or
|
|
wall_detect_left2.is_colliding() or
|
|
wall_detect_left3.is_colliding() or
|
|
wall_far_detect_right.is_colliding() or
|
|
wall_far_detect_right2.is_colliding() or
|
|
wall_far_detect_right3.is_colliding()
|
|
)
|
|
# Met à jour une partie de l'état de la princesse
|
|
# gestion du coyote time sur le contact au sol
|
|
coyote_ground.append(is_on_floor())
|
|
if coyote_ground.size() > COYOTE_LENGTH:
|
|
coyote_ground.remove_at(0)
|
|
|
|
# Met à jour une partie de l'état de la princesse
|
|
# gestion du coyote time sur le contact au sol
|
|
coyote_grab.append(grab_wall)
|
|
if coyote_grab.size() > COYOTE_GRAB_LENGTH:
|
|
coyote_grab.remove_at(0)
|
|
|
|
# gestion de l'état de la pression au mur
|
|
pressing_wall_left = (
|
|
not is_on_floor() and not collide_ground_far_detect and not is_on_ceiling_only()
|
|
) and (
|
|
(wall_detect_left.is_colliding() and wall_detect_left2.is_colliding()) or
|
|
(wall_detect_left3.is_colliding())
|
|
)
|
|
pressing_wall_right = (
|
|
not is_on_floor() and not collide_ground_far_detect and not is_on_ceiling_only()
|
|
) and (
|
|
(wall_detect_right.is_colliding() and wall_detect_right2.is_colliding()) or
|
|
(wall_detect_right3.is_colliding())
|
|
)
|
|
pressing_wall = pressing_wall_left or pressing_wall_right
|
|
|
|
func get_new_animation() -> String:
|
|
# Renvoie la bonne annimation en fonction de l'état de la princesse
|
|
var animation_new: String
|
|
|
|
if is_on_floor():
|
|
if walking_step > 0:
|
|
animation_new = "walk"
|
|
else:
|
|
if near_cliff:
|
|
animation_new = "near_cliff"
|
|
else:
|
|
animation_new = "idle"
|
|
else:
|
|
if velocity.y > 0.0:
|
|
if get_coyote(coyote_grab):
|
|
animation_new = "wall_stick"
|
|
else:
|
|
if walking_step > 0:
|
|
animation_new = "falling_diagonals"
|
|
else:
|
|
animation_new = "falling_straight"
|
|
else:
|
|
animation_new = "jumping"
|
|
return animation_new
|
|
|
|
func _physics_process(_delta: float) -> void:
|
|
if dead or locked:
|
|
return
|
|
compute_state()
|
|
read_input()
|
|
velocity.y = jump()
|
|
velocity.y = fall()
|
|
velocity.x = walk(direction)
|
|
kick()
|
|
dash()
|
|
move_and_handle_collisions()
|
|
play_animation()
|
|
|
|
func you_got_cheese(speed:float=1) -> void:
|
|
cheese_collected.emit(speed)
|
|
reload_fart()
|
|
|
|
func reload_fart() -> void:
|
|
Input.start_joy_vibration(0, 0, 1, 0.2)
|
|
|
|
func you_got_lactase() -> void:
|
|
lactase_collected.emit()
|
|
kill_farts()
|
|
|
|
func kill_farts() -> void:
|
|
cancel_dash()
|
|
Input.start_joy_vibration(0, 0.5, 0, 0.1)
|
|
|
|
func death() -> void:
|
|
if not dead:
|
|
print("death")
|
|
locked = true
|
|
locked_controls = true
|
|
dead = true
|
|
Input.start_joy_vibration(0, 1,0.7, 1)
|
|
self.rotation = 90
|
|
death_animation.play(&"death")
|
|
kill_farts()
|
|
|
|
func _ready() -> void:
|
|
locked = false
|
|
dead = false
|
|
|
|
func go_out_and_play():
|
|
locked_controls = false
|
|
|
|
func _on_death_player_animation_finished(_anim_name: StringName) -> void:
|
|
princesse_is_dead.emit()
|