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:
559
ms/princess_accel_static.ms
Normal file
559
ms/princess_accel_static.ms
Normal 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
|
||||
Reference in New Issue
Block a user