princesse lactose: premier commit

La princesse, saute, se déplace et s'amuse comme une folle.
Les collisions ne marchent pas totalement bien.
Ça s'améliorera au fil du temps.
Grâce à git, les choses vont s'améliorer.
This commit is contained in:
Thomas Lavocat
2023-04-03 09:33:50 +02:00
commit e0deb730ec
19 changed files with 1125 additions and 0 deletions

1
maps/map.json Normal file
View File

@@ -0,0 +1 @@
{"width":12,"height":16,"block_width":16,"block_height":16,"sprites":[0],"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}

1
maps/map2.json Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"width":24,"height":16,"block_width":16,"block_height":16,"sprites":[0,"plateformes:1,3","plateformes:2,3","grimpables:1,3","plateformes:7,4","plateformes:9,3","plateformes:10,3","plateformes:15,3","plateformes:1,1","plateformes:3,1","plateformes:4,2","grimpables:1,2","plateformes:15,5","grimpables:1,1","plateformes:4,4","plateformes:0,7","plateformes:6,4","plateformes:12,4","grimpables:1,0","plateformes:3,3","plateformes:4,3","plateformes:5,3","plateformes:9,1","grimpables:0,3","grimpables:0,2","plateformes:2,2","plateformes:5,1","plateformes:4,1","plateformes:14,3","plateformes:0,4","plateformes:11,3","plateformes:12,3","flag","plateformes:13,3","grimpables:0,1","plateformes:9,4","plateformes:10,4","plateformes:11,4","plateformes:13,4","plateformes:15,4","grimpables:0,0"],"data":[0,0,0,0,1,2,3,3,3,3,3,4,5,6,7,0,0,0,0,0,0,0,5,6,8,9,9,4,9,10,11,11,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,3,0,10,13,11,11,11,11,14,0,0,0,0,0,0,0,15,16,0,0,0,17,0,7,11,0,10,18,18,18,18,19,20,21,0,0,0,0,0,0,22,23,0,0,0,17,0,17,3,0,10,2,1,2,19,10,20,20,0,0,0,0,0,0,0,24,0,0,0,17,0,17,3,0,25,25,25,10,10,10,20,20,21,0,0,0,0,0,0,24,0,0,0,17,0,17,11,0,4,9,15,26,26,16,27,27,26,0,0,0,0,0,0,24,0,0,0,17,0,17,3,0,3,0,0,0,0,0,0,0,5,7,0,0,0,0,0,24,0,0,0,17,0,17,3,0,11,0,0,0,0,0,0,0,0,0,5,7,0,0,0,24,0,0,0,17,0,17,3,0,13,0,0,0,0,0,0,0,0,0,0,0,5,28,7,24,0,0,0,17,0,17,3,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,17,0,17,11,0,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,17,0,17,13,0,0,0,0,0,0,0,0,0,0,0,0,29,5,6,7,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,30,31,7,32,0,0,0,24,0,0,0,0,0,0,0,0,0,5,6,30,31,33,7,0,0,0,0,0,0,0,0,34,0,0,0,0,0,0,5,6,7,35,36,37,17,38,39,0,0,0,0,0,0,0,0,40,5,5,6]}

101
ms/main.ms Normal file
View File

@@ -0,0 +1,101 @@
init = function()
played_map = "map2"
mapw =
maph =
princess = new Princess(0, 10, played_map)
prev_time = system.time()
prevx = 0
prevy = 0
end
update = function()
if not maps[played_map].ready then
return
end
now = system.time()
timedelta = now - prev_time
princess.update_me()
//----------------------------------------------------------------------------
//
// Gestion des inputs
wants_jump = keyboard.SPACE or gamepad.A
stop_jump = keyboard.release.SPACE or gamepad.release.A
wants_left = keyboard.LEFT or gamepad.LEFT_STICK_LEFT
wants_climb = keyboard.UP or gamepad.LEFT_STICK_UP
wants_right = keyboard.RIGHT or gamepad.LEFT_STICK_RIGHT
wants_crouch = keyboard.DOWN or gamepad.LEFT_STICK_DOWN
wants_run = keyboard.SHIFT_LEFT or gamepad.X
wants_dash = keyboard.ALT_LEFT or gamepad.RT
// Sauter n'est possible que si l'on est pas déjà en train de sauter et que
// la princesse a les pieds au sol
/*
if (wants_jump and not princess_states.contains(JUMPING) and
(on_ground or on_climbable)) then
princess_states.push(JUMPING)
end
*/
if wants_right then
princess.go_right()
else
princess.stop_going_right()
end
if wants_left then
princess.go_left()
else
princess.stop_going_left()
end
if wants_jump then
princess.do_jump()
end
if stop_jump then
princess.stop_jump()
end
/*
if wants_run and not princess_states.contains(RUNNING) then
princess_states.push(RUNNING)
end
if not wants_run then
princess_states.removeElement(RUNNING)
end
can_climbe = (on_climbable or heads_on_climbable)
if wants_climb and not princess_states.contains(CLIMBING) and can_climbe then
princess_states.push(CLIMBING)
end
if not wants_climb or not can_climbe then
princess_states.removeElement(CLIMBING)
end
if wants_crouch and not princess_states.contains(CLIMBING_DOWN) and can_climbe then
princess_states.push(CLIMBING_DOWN)
end
if not wants_crouch or not can_climbe then
princess_states.removeElement(CLIMBING_DOWN)
end
*/
prev_time = now
end
draw = function()
screen.fillRect(0,0,screen.width,screen.height,"rgb(171,255,255)")
screen.drawMap(played_map,
princess.xoffset,
princess.yoffset,
princess.map.width*princess.map.block_width,
princess.map.height*princess.map.block_height)
princess.draw_me()
end

View File

@@ -0,0 +1,462 @@
PrincessOld = class
// globals
LEFT = 0
RIGHT= 1
// taille de la princess
X_SIZE = 7.68
Y_SIZE = 16
// états
IDLING = 0
WALKING_R = 1
WALKING_L = 2
JUMPING = 3
CROUCHING = 4
FARTING = 5
DASHING = 6
FALLING = 7
RUNNING = 8
CLIMBING_UP = 9
CLIMBING_DOWN = 10
PRESSING_WALL = 11
// Définitions statiques
ONE_METER = 16 //nombre de pixels par mètre
// accélérations
WALK_ACCEL = 6 // exrimé en m/s/s
FLIGHT_WALK_ACCEL = 3
RUN_ACCEL = 9 // exprimé en m/s/s
FLIGHT_RUN_ACCEL = 6
AIR_CONTROL_DIVIDER = 2.4 // diviseur pour limiter le contrôle de trajectoire en l'air
GRAVITY = 1.5 // exprimé en m/s/s
JUMP_ACCEL = 5
//frictions
GROUND_FRICTION = 0.3 // coefficient de friction du sol
GROUND_X_DIV = 10
AIR_FRICTION = 0.3 //coefficient de friction dans l'air
WALL_FRICTION = 0.3
// Quand la princesse est en friction sur le mur
// de combien est-elle propulsée du côté opposé
// lorsqu'elle saute à ce moment là
WALL_KICK = 4
JUMP_KICK = 8
// Nombre d'inréments composant un saut
JUMPING_COUNTER = 7
// Nombre d'incrément à rajouter lorsque la touche de saut est maintenue
JUMPING_COUNTER_REFILL = 2
// Tous les combien d'incréments rajouter un refill sur le compteur
JUMPING_KEY_COUNTER_THRESHOLD = 3
constructor = function(x, y, map_name)
this.x = x
this.y = y -10 // décaler le srpite car sinon 0,0 est en son centre
this.map = maps[map_name]
this.states = []
this.x_speed = 0
this.y_speed = 0
this.x_accel = 0
this.y_accel = 0
this.last_direction = RIGHT
this.xoffset=0
this.yoffset=0
// jumping states
this.jumping_counter = 0 // compte le nombre d'étape à faire pour sauter
// compte le nombre de frames dans le saut, utilisé pour savoir
// si le bouton a été enfoncé longtemps ou non
this.jump_key_counter = 0
// mis à 1 si le saut à démarré avec un kick pour pouvoir
// rajouter un peu de kick en cours de saut si la touche de saut
// est maintenue.
this.jump_started_wall_kick = 0
end
x_in_map = function(x)
/*
transforme une coordonée x avec une référence au centre de la carte
en une coordonnée où le point de référence est en bas à gauche de la carte
*/
map_half_width = (this.map.width/2)*this.map.block_width
return x+map_half_width-this.xoffset
end
x_to_block = function(x_in_map)
// Transforme une coordonée x en numéro de block correspondant
return floor(x_in_map / this.map.block_width)
end
mapx_to_x = function(mapx)
return mapx-((this.map.width/2)* this.map.block_width)+this.xoffset
end
y_in_map = function(y)
/*
transforme une coordonée y avec une référence au centre de la carte
en une coordonnée où le point de référence est en bas à gauche de la carte
*/
map_half_height = (this.map.height/2)* this.map.block_height
return y+map_half_height-this.yoffset
end
mapy_to_y = function(mapy)
return mapy-((this.map.height/2)* this.map.block_height)+this.yoffset
end
y_to_block = function(y_in_map)
// Transforme une coordonée y en numéro de block correspondant
return floor(y_in_map / this.map.block_height)
end
get_touching = function(name, x, y)
/*
Renvoie les coordonées en unité block du block pointé aux coordonnées du personnage.
*/
block_x = x_to_block(x_in_map(x))
block_y = y_to_block(y_in_map(y))
block = map.get(block_x,block_y)
if block != 0 then
if block.startsWith(name) then
return [block_x, block_y]
else
return [-1, -1]
end
end
return [-1, -1]
end
feet_on_ground = function()
// renvoie vrai si le block sous les pieds de la princesse est une plateforme
return get_touching("plateformes", this.x, this.y-Y_SIZE/2-1)[0] > -1
end
touch_wall = function()
// renvoie vrai si le block sous les pieds de la princesse est une plateforme
return get_touching("plateformes", this.x-X_SIZE/2-1, this.y)[0] > -1 or
get_touching("plateformes", this.x+X_SIZE/2+1, this.y)[0] > -1
end
head_on_ceiling = function()
// renvoie vrai si le block au dessus de la tête de la princesse est une plateforme
return get_touching("plateformes", this.x, this.y+Y_SIZE/2)[0] > -1
end
walk = function(timedelta)
/*
Met le personnage en mouvemment à gauche ou à droite
timedelta, nombre de milisecondes depuis le dernier appel
*/
accel = 0
if this.states.contains(WALKING_L) or this.states.contains(WALKING_R) then
accel = WALK_ACCEL
if this.states.contains(RUNNING) then
accel = RUN_ACCEL
end
// si le personnage n'est pas au sol, diviser l'accélération latérale
if not feet_on_ground() then
accel = FLIGHT_WALK_ACCEL
if this.states.contains(RUNNING) then
accel = FLIGHT_RUN_ACCEL
end
end
end
// Inverser le vecteur de déplacement si l'on va à gauche
if this.states.contains(WALKING_L) then
accel = accel * -1
end
td_in_s = timedelta /1000
this.x_accel = this.x_accel + accel*td_in_s
end
gravity = function(timedelta)
/*
Applique la gravité au personnage
timedelta, nombre de milisecondes depuis le dernier appel
*/
if not this.feet_on_ground() then
td_in_s = timedelta /1000
this.y_accel = this.y_accel - GRAVITY*td_in_s
end
end
jump = function(timedelta)
if this.states.contains(JUMPING) then
// initialiser les variables du saut
if this.jumping_counter == 0 then
this.jump_started_wall_kick = 0
this.jumping_counter = JUMPING_COUNTER
end
// si l'utilisateur appuie longtemps sur la touche espace, alors sauter un peu plus loni
if this.jump_key_counter > 0 and this.jump_key_counter % JUMPING_KEY_COUNTER_THRESHOLD == 0 then
this.jumping_counter += JUMPING_COUNTER_REFILL
// besoin d'étendre le kick de départ si le saut a été initié contre un mur
// la valeur à rajouter est plus petite que le kick de départ
if this.jump_started_wall_kick then
if this.states.contains(WALKING_L) then
this.x_speed = WALL_KICK/2
end
if this.states.contains(WALKING_R) then
this.x_speed = -WALL_KICK/2
end
end
end
// Donner un petit kick pour le wall jump
if this.states.contains(PRESSING_WALL) then
this.jump_started_wall_kick = 1
if this.states.contains(WALKING_L) then
this.x_speed = WALL_KICK
end
if this.states.contains(WALKING_R) then
this.x_speed = -WALL_KICK
end
end
// calculer l'accélération
//td_in_s = timedelta /1000
//this.y_accel = this.y_accel + JUMP_ACCEL * td_in_s
this.y_speed = JUMP_KICK * (this.jumping_counter/JUMPING_COUNTER)
// traiter la fin du saut
this.jumping_counter -=1
if this.jumping_counter == 0 then
this.states.removeElement(JUMPING)
return
end
end
end
move = function()
/*
Cette fonction applique les accélérations calculées à ce tour sur la princesse et les applique
*/
// calculer la friction qui s'oppose au déplacement
// c'est grâce à la friction que le personnage atteindra sa vélocité maximum
// et freinera losqu'il n'aura plus d'accélération
// La quantité de friction s'applique au sol et en l'air et elle augmente avec le carré de la vitesse
// il en resulte un vecteur opposé au déplacement qui vient contrer celui ci.
x_friction = AIR_FRICTION
if this.feet_on_ground() then
x_friction += GROUND_FRICTION
end
x_friction = pow(this.x_speed * x_friction, 2)
if this.x_speed < 0 then
x_friction = x_friction * -1
end
this.x_speed = this.x_speed + (this.x_accel * ONE_METER) - x_friction
y_friction = AIR_FRICTION
if(
this.y_speed < 0 and
touch_wall() and
(this.states.contains(WALKING_L) or this.states.contains(WALKING_R))
)then
if not this.states.contains(PRESSING_WALL) then
this.states.push(PRESSING_WALL)
end
y_friction += WALL_FRICTION
else
this.states.removeElement(PRESSING_WALL)
end
y_friction = pow(this.y_speed * y_friction, 2)
if this.y_speed < 0 then
y_friction = y_friction * -1
end
befiore_speed = this.y_speed
this.y_speed = this.y_speed + (this.y_accel * ONE_METER) - y_friction
signx = 1
signy = 1
// gérer la collision sur x
if this.x_speed > 0 then
x_add = X_SIZE/2
else
x_add = -X_SIZE/2
signx = -1
end
if this.y_speed > 0 then
y_add = Y_SIZE/2
else
y_add = -Y_SIZE/2
signy = -1
end
// éviter de glisser trop longtemps quand la force de friction est trop faible pour arrêter le personnage
if abs(this.x_speed) < WALK_ACCEL/GROUND_X_DIV then
this.x_speed = 0
end
// déplace la princesse uniquement de la distance totale si elle à la place de le faire
futur_x = this.x + this.x_speed
touching = get_touching("plateformes", futur_x + x_add, this.y + -Y_SIZE/2)
if touching[0] > -1 then
// Si la princesse va toucher son collisioneur, alors la placer au bord de l'élément
if this.x_speed > 0 then
colisioner_x = touching[0]+1
colisioner_left_border = mapx_to_x(colisioner_x * this.map.block_width - this.map.block_width)
futur_x = floor(colisioner_left_border - X_SIZE/2)
elsif this.x_speed < 0 then
colisioner_x = touching[0]
colisioner_left_border = mapx_to_x(colisioner_x * this.map.block_width + this.map.block_width)
futur_x = ceil(colisioner_left_border + X_SIZE/2)
end
this.x_speed = 0 //arrêt brutal
end
dispx = abs(futur_x - this.x)
this.xoffset -= dispx*signx
futur_y = this.y + this.y_speed
touching = get_touching("plateformes", this.x + x_add, futur_y + y_add)
if touching[1] > -1 then
// Si la princesse va toucher son collisioneur, alors la placer au bord de l'élément
if this.y_speed > 0 then
colisioner_y = touching[1]
colisioner_bottom_border = mapy_to_y(colisioner_y * this.map.block_height)
futur_y = floor(colisioner_bottom_border - Y_SIZE/2)
elsif this.y_speed < 0 then
colisioner_y = touching[1]
colisioner_top_border = mapy_to_y(colisioner_y * this.map.block_height + this.map.block_height)
futur_y = ceil(colisioner_top_border + Y_SIZE/2)
end
this.y_speed = 0 //arrêt brutal
end
dispy = abs(futur_y - this.y)
this.yoffset -= dispy*signy
// remise à zéro de l'accélération
this.x_accel = 0
this.y_accel = 0
end
update_me = function(timedelta)
walk(timedelta)
jump(timedelta)
gravity(timedelta)
move()
end
draw_me = function()
/*
Dessine la Princesse à l'écran
*/
if this.last_direction == LEFT then
screen.setDrawScale(-1,1)
end
if this.states.contains(JUMPING) or this.states.contains(FALLING) then
screen.drawSprite(
"princess.1",
this.x,
this.y,
X_SIZE,
Y_SIZE)
elsif states.contains(WALKING_L) then
screen.drawSprite(
"princess",
this.x,
this.y,
X_SIZE,
Y_SIZE)
elsif states.contains(WALKING_R) then
screen.drawSprite(
"princess",
this.x,
this.y,
X_SIZE,
Y_SIZE)
else
screen.drawSprite(
"princess.0",
this.x,
this.y,
X_SIZE,
Y_SIZE)
end
if this.last_direction == LEFT then
screen.setDrawScale(1,1)
end
end
go_right = function()
this.last_direction = RIGHT
if not this.states.contains(WALKING_R) then
this.states.push(WALKING_R)
end
end
stop_going_right = function()
this.states.removeElement(WALKING_R)
end
go_left = function()
this.last_direction = LEFT
if not this.states.contains(WALKING_L) then
this.states.push(WALKING_L)
end
end
stop_going_left = function()
this.states.removeElement(WALKING_L)
end
do_jump = function()
// Un nouveau saut est déclenché uniquement si le cycle d'un saut
// précédent n'est pas fini.
// Pour terminer, la princesse doit avoir touché le sol ou être accrochée au mur
// mais l'utilisateur doit également avoir relâché la touche saut
if not this.states.contains(JUMPING) and this.jump_key_counter == 0 then
if (feet_on_ground() or this.states.contains(PRESSING_WALL)) then
this.states.push(JUMPING)
end
// lorsqu'un saut est démarré, mettre à zéro le compteur de frames
this.jump_key_counter = 0
else
// dans tous les cas incrémenter le compteur de frames
this.jump_key_counter += 1
end
end
stop_jump = function()
this.jump_key_counter = 0
end
end

559
ms/princess_accel_static.ms Normal file
View File

@@ -0,0 +1,559 @@
// TODO régler les collisions!!!!
Princess = class
// globals
LEFT = 0
RIGHT= 1
// taille de la princess
X_SIZE = 12
Y_SIZE = 23
// états
IDLING = 0
WALKING_R = 1
WALKING_L = 2
JUMPING = 3
CROUCHING = 4
FARTING = 5
DASHING = 6
FALLING = 7
RUNNING = 8
CLIMBING_UP = 9
CLIMBING_DOWN = 10
PRESSING_WALL = 11
JUMP_KICKING = 12
X_SPEED_TABLE = [0, 0.2, 0.4, 0.6, 1, 1.6, 2.4, 3]
X_SPEED_DECEL = [0, 0.2, 0.6, 1.6, 3]
X_SPEED_AIR_DECEL =[0, 0.2, 0.6, 0.8, 0.9, 0.9, 1,
1.1, 1.1, 1.1, 1.2, 1.2, 1.2,
1.2, 1.2, 1.3, 1.4, 1.5, 1.6,
1.8, 1.9, 3]
FALL_SPEED_TABLE = [0, 0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3, 4, ]
JUMP_SPEED_TABLE = [0, 0.4, 0.8, 1.2, 1.6, 2, 2.4, 2.8, 3, 3, 4, 5]
KICK_SPEED_TABLE = [0, 0.2, 0.4, 0.6, 1, 1.6, 2.4, 3]
// Nombre d'inréments composant un saut
JUMPING_COUNTER = 20
// Nombre d'incrément à rajouter lorsque la touche de saut est maintenue
JUMPING_COUNTER_REFILL = 2
// Tous les combien d'incréments rajouter un refill sur le compteur
JUMPING_KEY_COUNTER_THRESHOLD = 3
COYOTE_LENGTH = 20
constructor = function(x, y, map_name)
this.x = x
this.y = y -10 // décaler le srpite car sinon 0,0 est en son centre
this.map = maps[map_name]
this.states = []
this.x_speed = 0
this.y_speed = 0
this.x_accel = 0
this.y_accel = 0
this.last_direction = RIGHT
this.xoffset=0
this.yoffset=0
// jumping states
this.jumping_counter = 0 // compte le nombre d'étape à faire pour sauter
// compte le nombre de frames dans le saut, utilisé pour savoir
// si le bouton a été enfoncé longtemps ou non
this.jump_key_counter = 0
// mis à 1 si le saut à démarré avec un kick pour pouvoir
// rajouter un peu de kick en cours de saut si la touche de saut
// est maintenue.
this.jump_started_wall_kick = 0
this.jump
this.coyote = []
this.coyote_pressing = []
end
x_in_map = function(x)
/*
transforme une coordonée x avec une référence au centre de la carte
en une coordonnée où le point de référence est en bas à gauche de la carte
*/
map_half_width = (this.map.width/2)*this.map.block_width
return x+map_half_width-this.xoffset
end
x_to_block = function(x_in_map)
// Transforme une coordonée x en numéro de block correspondant
return floor(x_in_map / this.map.block_width)
end
mapx_to_x = function(mapx)
return mapx-((this.map.width/2)* this.map.block_width)+this.xoffset
end
y_in_map = function(y)
/*
transforme une coordonée y avec une référence au centre de la carte
en une coordonnée où le point de référence est en bas à gauche de la carte
*/
map_half_height = (this.map.height/2)* this.map.block_height
return y+map_half_height-this.yoffset
end
mapy_to_y = function(mapy)
return mapy-((this.map.height/2)* this.map.block_height)+this.yoffset
end
y_to_block = function(y_in_map)
// Transforme une coordonée y en numéro de block correspondant
return floor(y_in_map / this.map.block_height)
end
get_touching = function(name, x, y)
/*
Renvoie les coordonées en unité block du block pointé aux coordonnées du personnage.
*/
block_x = x_to_block(x_in_map(x))
block_y = y_to_block(y_in_map(y))
block = map.get(block_x,block_y)
if block != 0 then
if block.startsWith(name) then
return [block_x, block_y]
else
return [-1, -1]
end
end
return [-1, -1]
end
feet_on_ground = function()
// renvoie vrai si le block sous les pieds de la princesse est une plateforme
return get_touching("plateformes", this.x, this.y-Y_SIZE/2-1)[0] > -1
end
futur_feet_on_ground = function(x)
// renvoie vrai si le block sous les pieds de la princesse est une plateforme
return get_touching("plateformes", x, this.y-Y_SIZE/2-1)[0] > -1
end
coyote_touch = function()
return coyote[0]
end
coyote_pressing_touch = function()
return coyote_pressing[0]
end
touch_wall = function()
// renvoie vrai si le block sous les pieds de la princesse est une plateforme
return get_touching("plateformes", this.x-X_SIZE/2-1, this.y)[0] > -1 or
get_touching("plateformes", this.x+X_SIZE/2+1, this.y)[0] > -1
end
head_on_ceiling = function()
// renvoie vrai si le block au dessus de la tête de la princesse est une plateforme
return get_touching("plateformes", this.x, this.y+Y_SIZE/2)[0] > -1
end
get_speed_table = function(table, index)
speed_table_len = table.length
if index < speed_table_len then
return table[index]
else
return table[speed_table_len-1]
end
end
walk = function(timedelta)
if this.states.contains(JUMP_KICKING) then
return
print("can't walk")
end
if this.states.contains(WALKING_L) or this.states.contains(WALKING_R) then
table = X_SPEED_TABLE
this.walking_step = min(table.length, this.walking_step+1)
else
if feet_on_ground() then
table = X_SPEED_DECEL
this.start_air_decel = 0
if this.walking_step >= X_SPEED_DECEL.length -1 then
this.walking_step = X_SPEED_DECEL.length -1
end
else
table = X_SPEED_AIR_DECEL
if this.start_air_decel == 0 then
if this.walking_step >= X_SPEED_DECEL.length -1 then
this.walking_step = X_SPEED_AIR_DECEL.length -1
end
this.start_air_decel = 1
end
end
if this.walking_step >= 0 then
if this.walking_step > table.length-1 then
this.walking_step = table.length-1
end
this.walking_step-=1
end
end
if this.walking_step >= 0 then
this.x_speed = get_speed_table(table, this.walking_step)
if this.last_direction == LEFT then
this.x_speed *= -1
end
end
if abs(x_speed) > 0 then
print(x_speed)
end
end
gravity = function(timedelta)
if(
not feet_on_ground() and
touch_wall() and
not this.states.contains(JUMPING) and
(this.states.contains(WALKING_L) or this.states.contains(WALKING_R))
)then
if not this.states.contains(PRESSING_WALL) then
this.states.push(PRESSING_WALL)
print("pressing wall")
end
else
if this.states.contains(PRESSING_WALL) then
this.states.removeElement(PRESSING_WALL)
print("stop pressing wall")
end
end
max_speed = FALL_SPEED_TABLE.length
if this.states.contains(PRESSING_WALL) then
max_speed = 4
end
if this.feet_on_ground() or this.states.contains(JUMPING) then
this.falling_step = -1
this.states.removeElement(FALLING)
else
if not this.states.contains(JUMPING) then
this.falling_step = min(max_speed, this.falling_step+=1)
if not this.states.contains(FALLING) then
this.states.push(FALLING)
end
end
end
if this.falling_step >= 0 then
this.y_speed = - get_speed_table(FALL_SPEED_TABLE, this.falling_step)
end
end
jump = function(timedelta)
if this.states.contains(JUMPING) then
// initialiser les variables du saut
if this.jumping_counter == 0 then
this.jump_started_wall_kick = 0
this.jumping_counter = JUMP_SPEED_TABLE.length
this.kick_counter = KICK_SPEED_TABLE.length -1
// Donner un petit kick pour le wall jump
if this.states.contains(PRESSING_WALL) then
if not this.states.contains(JUMP_KICKING) then
print("jump kicking")
this.states.push(JUMP_KICKING)
end
end
end
// si l'utilisateur appuie longtemps sur la touche espace, alors sauter un peu plus loni
if this.jump_key_counter > 0 and this.jump_key_counter % JUMPING_KEY_COUNTER_THRESHOLD == 0 then
this.jumping_counter += JUMPING_COUNTER_REFILL
if this.states.contains(JUMP_KICKING) then
this.kick_counter += JUMPING_COUNTER_REFILL
end
end
if this.states.contains(JUMP_KICKING) then
this.x_speed = get_speed_table(KICK_SPEED_TABLE, this.kick_counter)
if this.last_direction == RIGHT then
this.x_speed *= -1
end
this.kick_counter -=1
print("kick "+this.x_speed)
if this.kick_counter <= 0 then
this.states.removeElement(JUMP_KICKING)
this.walking_step=0
end
end
this.y_speed = get_speed_table(JUMP_SPEED_TABLE, this.jumping_counter)
this.jumping_counter -= 1
if this.jumping_counter == 0 then
this.states.removeElement(JUMPING)
print("jump cycle done")
end
end
end
next_collision_x = function(futur_x, y, right, left)
ret_futur_x = futur_x
for i=(y - Y_SIZE/2) to (y + Y_SIZE/2) by 8
point = get_touching("plateformes", futur_x, i)
hypothesis = -1
if point[0] > 0 then
if right then
colisioner_x = point[0]+1
colisioner_left_border = mapx_to_x(colisioner_x * this.map.block_width - this.map.block_width)
hypothesis = floor(colisioner_left_border - X_SIZE/2)
elsif left then
colisioner_x = point[0]
colisioner_left_border = mapx_to_x(colisioner_x * this.map.block_width + this.map.block_width)
hypothesis = ceil(colisioner_left_border + X_SIZE/2)
end
end
if hypothesis != -1 and abs(hypothesis) < abs(ret_futur_x) then
ret_futur_x = hypothesis
end
end
return ret_futur_x
end
next_collision_y = function(x, futur_y, top, bottom)
ret_futur_y = futur_y
for i=(x - X_SIZE/2) to (x + X_SIZE/2) by 4
point = get_touching("plateformes", i, futur_y)
hypothesis = -1
if point[0] > 0 then
if top then
colisioner_y = point[1]
colisioner_bottom_border = mapy_to_y(colisioner_y * this.map.block_height)
futur_y = floor(colisioner_bottom_border - Y_SIZE/2)
elsif bottom then
colisioner_y = point[1]
colisioner_top_border = mapy_to_y(colisioner_y * this.map.block_height + this.map.block_height)
hypothesis = ceil(colisioner_top_border + Y_SIZE/2)
end
end
if hypothesis != -1 and abs(hypothesis) < abs(ret_futur_y) then
ret_futur_y = hypothesis
end
end
return ret_futur_y
end
move = function()
signx = 1
signy = 1
// gérer la collision sur x
if this.x_speed > 0 then
x_add = X_SIZE/2
else
x_add = -X_SIZE/2
signx = -1
end
if this.y_speed > 0 then
y_add = Y_SIZE/2
else
y_add = -Y_SIZE/2
signy = -1
end
// déplace la princesse uniquement de la distance totale si elle à la place de le faire
futur_x = this.x + this.x_speed
if abs(this.x_speed) !=0 then
futur_x_with_collision = next_collision_x(futur_x+x_add, this.y, this.x_speed > 0, this.x_speed < 0)
if futur_x_with_collision != futur_x+x_add then
futur_x = futur_x_with_collision
this.x_speed = 0
end
end
dispx = abs(futur_x - this.x)
this.xoffset -= dispx*signx
futur_y = this.y + this.y_speed
touching = get_touching("plateformes", this.x + x_add, futur_y + y_add)
if touching[1] > -1 then
// Si la princesse va toucher son collisioneur, alors la placer au bord de l'élément
if this.y_speed > 0 then
colisioner_y = touching[1]
colisioner_bottom_border = mapy_to_y(colisioner_y * this.map.block_height)
futur_y = floor(colisioner_bottom_border - Y_SIZE/2)
elsif this.y_speed < 0 then
colisioner_y = touching[1]
colisioner_top_border = mapy_to_y(colisioner_y * this.map.block_height + this.map.block_height)
futur_y = ceil(colisioner_top_border + Y_SIZE/2)
end
cancel_jump()
this.y_speed = 0 //arrêt brutal
end
dispy = abs(futur_y - this.y)
this.yoffset -= dispy*signy
// remise à zéro de l'accélération
this.x_accel = 0
this.y_accel = 0
end
update_me = function(timedelta)
coyote.push(feet_on_ground())
coyote_pressing.push(this.states.contains(PRESSING_WALL))
walk(timedelta)
jump(timedelta)
gravity(timedelta)
move()
if coyote.length > COYOTE_LENGTH then
coyote.removeAt(0)
end
if coyote_pressing.length > COYOTE_LENGTH then
coyote_pressing.removeAt(0)
end
end
draw_me = function()
reverse = (not this.states.contains(PRESSING_WALL) and this.last_direction == LEFT) or (this.states.contains(PRESSING_WALL) and this.last_direction == RIGHT)
if reverse then
screen.setDrawScale(-1,1)
end
if this.states.contains(JUMPING) and not this.states.contains(PRESSING_WALL) then
if this.jumping_counter <= JUMP_SPEED_TABLE.length-1 and this.jumping_counter >= JUMP_SPEED_TABLE.length-3 then
screen.drawSprite(
"princess_jumping_impulsion",
this.x,
this.y,
X_SIZE,
Y_SIZE)
else
screen.drawSprite(
"princess_jumping",
this.x,
this.y,
X_SIZE,
Y_SIZE)
end
elsif this.states.contains(FALLING) and not this.states.contains(PRESSING_WALL) then
if states.contains(WALKING_L) or states.contains(WALKING_R) then
screen.drawSprite(
"princess_falling_direction",
this.x,
this.y,
X_SIZE,
Y_SIZE)
else
screen.drawSprite(
"princess_falling",
this.x,
this.y,
X_SIZE,
Y_SIZE)
end
elsif this.states.contains(PRESSING_WALL) then
screen.drawSprite(
"princess_wall_stick",
this.x,
this.y,
X_SIZE,
Y_SIZE)
elsif states.contains(WALKING_L) and not this.states.contains(FALLING) then
screen.drawSprite(
"princess",
this.x,
this.y,
X_SIZE,
Y_SIZE)
elsif states.contains(WALKING_R) and not this.states.contains(FALLING)then
screen.drawSprite(
"princess",
this.x,
this.y,
X_SIZE,
Y_SIZE)
else
screen.drawSprite(
"princess.0",
this.x,
this.y,
X_SIZE,
Y_SIZE)
end
if reverse then
screen.setDrawScale(1,1)
end
end
go_right = function()
this.last_direction = RIGHT
if not this.states.contains(WALKING_R) then
print("right")
this.states.push(WALKING_R)
this.walking_step = this.kick_counter
//this.kick_counter = -1
end
end
stop_going_right = function()
this.states.removeElement(WALKING_R)
end
go_left = function()
this.last_direction = LEFT
if not this.states.contains(WALKING_L) then
print("left")
this.states.push(WALKING_L)
this.walking_step = this.kick_counter
//this.kick_counter = -1
end
end
stop_going_left = function()
this.states.removeElement(WALKING_L)
end
do_jump = function()
// Un nouveau saut est déclenché uniquement si le cycle d'un saut
// précédent n'est pas fini.
// Pour terminer, la princesse doit avoir touché le sol ou être accrochée au mur
// mais l'utilisateur doit également avoir relâché la touche saut
if not this.states.contains(JUMPING) and this.jump_key_counter == 0 then
if (feet_on_ground() or this.states.contains(PRESSING_WALL) or coyote_touch() or coyote_pressing_touch()) then
this.states.push(JUMPING)
print("jump")
end
else
this.jump_key_counter += 1
end
end
stop_jump = function()
print("stop jump")
this.jump_key_counter = 0
end
cancel_jump = function()
print("cancel jump")
this.jumping_counter = 0
this.states.removeElement(JUMPING)
this.kick_counter = 0
this.states.removeElement(JUMP_KICKING)
end
end

BIN
sprites/flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

BIN
sprites/grimpables.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
sprites/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

BIN
sprites/items.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
sprites/mastersystem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
sprites/plateformes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
sprites/princess.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
sprites/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB