celeste.py

Created by mathieu-croslacoste

Created on January 03, 2025

11.4 KB

Adaptation du script “celeste” par loic-azavant (https://my.numworks.com/python/loic-azavant/celeste) pour Epsilon (le firmware officiel par défaut)

Nécéssite “celeste_levels.py” (https://my.numworks.com/python/mathieu-croslacoste/celeste_levels) pour fonctionner.


from celeste_levels import*
class World:
 def __init__(it):it.chapter=0;it.x=0;it.y=14;it.dataX=0;it.dataY=0;it.dataHeight=13;it.dataWidth=20;it.nb_on_screen=(20,13);it.colors=tile_colors;it.scale=16;it.deadTiles=[20,21,22,23];it.colliderTiles=[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];it.spawnTile=1;it.trampoline=18;it.currentLevel=8;it.data=tuple();it.t=M()
 def drw(it):
  F(0,14,320,208,tile_colors[0])
  for i in range(it.nb_on_screen[1]):
   for j in range(it.nb_on_screen[0]):drw_texture(ord(it.data[it.currentLevel][0][(it.dataY+i)*it.dataWidth+j+it.dataX])-95,it.x+j*it.scale,it.y+i*it.scale)
 def move(it,x,y):
  if 0>it.dataX+x or it.dataWidth-it.nb_on_screen[0]<it.dataX+x:x=0
  if 0>it.dataY+y or it.dataHeight-it.nb_on_screen[1]<it.dataY+y:y=0
  if x==0 and y==0:return
  for ghost in ghosts:F(ghost.x,ghost.y,ghost.sx,ghost.sy,tile_colors[0]);ghost.x-=x*it.scale;ghost.y-=y*it.scale
  on_screen_before=[it.data[it.currentLevel][0][(it.dataY+i)*it.dataWidth+it.dataX:(it.dataY+i)*it.dataWidth+it.dataX+it.nb_on_screen[0]]for i in range(it.nb_on_screen[1])];it.dataX+=x;it.dataY+=y;on_screen_now=[it.data[it.currentLevel][0][(it.dataY+i)*it.dataWidth+it.dataX:(it.dataY+i)*it.dataWidth+it.dataX+it.nb_on_screen[0]]for i in range(it.nb_on_screen[1])]
  for i in range(it.nb_on_screen[1]):
   for j in range(it.nb_on_screen[0]):
    if on_screen_before[i][j]!=on_screen_now[i][j]:drw_texture(ord(on_screen_now[i][j])-95,it.x+j*it.scale,it.y+i*it.scale)
  player.y-=y*it.scale;player.x-=x*it.scale
 def getMapTileAtPoint(it,x,y):return(int((x+it.dataX*it.scale-it.x)/it.scale),int((y+it.dataY*it.scale-it.y)/it.scale))
 def getMapTilePosition(it,x,y):return((x-it.dataX)*it.scale+it.x,(y-it.dataY)*it.scale+it.y)
 def getTile(it,x,y):
  if x<0 or x>=it.dataWidth or y<0 or y>=it.dataHeight:return 0
  return ord(it.data[it.currentLevel][0][y*it.dataWidth+x])-95
ghosts=[]
class Ghost:
 def __init__(it):ghosts.append(it);it.x=int(player.x);it.y=int(player.y);it.sx=player.sx;it.sy=player.sy;it.c=player.ori_col;it.max_step=50;it.step=0
 def drw(it):
  F(it.x,it.y,it.sx,it.sy,it.c)
  if it.step==it.max_step:ghosts.remove(it);del it;return
  it.step+=1;it.c=((it.c[0]*(it.max_step-it.step)+tile_colors[0][0]*it.step)//it.max_step,(it.c[1]*(it.max_step-it.step)+tile_colors[0][1]*it.step)//it.max_step,(it.c[2]*(it.max_step-it.step)+tile_colors[0][2]*it.step)//it.max_step)
class Player:
 def __init__(it):it.sx=8;it.sy=14;it.vx=0;it.vy=0;it.ori_col=(0,200,0);it.col=(0,200,0);it.nb_dash=1;it.max_nb_dash=1;it.dashing=0;it.dash_time=0;it.max_dash_time=16;it.dash_speed=4;it.diagonal_dash=0;it.on_ground=0;it.on_right_wall=0;it.on_left_wall=0;it.jumping_trampoline=0;it.climbing=0;it.climbing_time=0;it.max_climbing_time=1000;it.climbing_speed=.04;it.max_climbing_speed=.8;it.climbing_delay=-1;it.tuto_can_dash=0;it.tuto_can_climb=0;it.tuto_can_walljump=0;it.last_level_jump=1;it.deathCounter=0;it.collision_preciseness=1
 def init(it):
  if world.currentLevel==0:it.tuto_can_climb=0;it.tuto_can_dash=0
  ghosts.clear();world.dataHeight,world.dataWidth=world.data[world.currentLevel][1];a=world.data[world.currentLevel][0].find("`");x2,y2=a%world.dataWidth,a//world.dataWidth;world.dataX=max(0,min(world.dataWidth-world.nb_on_screen[0],x2-world.nb_on_screen[0]//2));world.dataY=max(0,min(world.dataHeight-world.nb_on_screen[1],y2-world.nb_on_screen[1]//2));it.x,it.y=world.getMapTilePosition(x2,y2);it.old_x,it.old_y=it.x,it.y;it.vx,it.vy=0,0;it.dashing=0;it.dash_time=0;world.drw()
 def drw(it,x,y,c):F(int(x),int(y),it.sx,it.sy,c)
 def check_level_one(it):
  if world.chapter!=0:return
  if it.x+world.dataX*world.scale<50 and world.currentLevel==0:
   it.climbing=0
   if not it.tuto_can_climb:D("Climb with [back]",75,20,"w",tile_colors[0]);it.tuto_can_climb=1
   if 170>world.dataX*world.scale+it.x>154:D(" "*17,75,20,tile_colors[0],tile_colors[0])
  if world.currentLevel==1:
   if not it.tuto_can_walljump:D("Walljump by pressing\n[OK] against a wall",3,17,"w",tile_colors[0]);it.tuto_can_walljump=1
  if world.dataX*world.scale+it.x<448 or world.currentLevel!=3:it.nb_dash=0
  else:
   if not it.tuto_can_dash:
    for i in range(10):it.old_x,it.old_y=it.x,it.y;world.move(1,0);it.drw(it.old_x,it.old_y,tile_colors[0]);it.drw(it.x,it.y,"g");S(.05)
    for i in range(21):D("Dash with [backspace]"[i],70+i*10,20,"w",tile_colors[0]);S(.08)
    while K(17)^1:0
    D(" "*21,70,20,tile_colors[0],tile_colors[0]);it.jumping_trampoline=0;it.dashing=1;dashed=1;it.vx=it.dash_speed;it.vy=-it.dash_speed;it.diagonal_dash=1;it.tuto_can_dash=1
   else:it.vx=0.4
   if it.on_ground:
    S(.5)
    for i in range(21):F(0,14+i*10,320,10,(100,0,75));S(.05)
    S(.2)
    for i in range(15):D("You can do this"[i],85+i*10,100,"w",(100,0,75));S(.15)
    S(1.5)
    for i in range(9):D("Good luck"[i],115+i*10,130,"w",(100,0,75));S(.1)
    S(1)
    for i in range(10):D("Press [OK]"[i],110+i*10,190,"w",(100,0,75));S(.1)
    while K(4)^1:0
    home_menu()
 def onGround(self):
  bottomLeft=world.getMapTileAtPoint(self.x+self.collision_preciseness,self.y+self.sy);bottomLeftTile=world.getTile(*bottomLeft);bottomRight=world.getMapTileAtPoint(self.x+self.sx-self.collision_preciseness,self.y+self.sy);bottomRightTile=world.getTile(*bottomRight)
  if bottomLeftTile in world.colliderTiles or bottomRightTile in world.colliderTiles:
   if bottomLeftTile==world.trampoline or bottomRightTile == world.trampoline:self.vy=-1.7;self.jumping_trampoline=1
   else:self.vy=min(0,self.vy)
   self.y=world.getMapTilePosition(*bottomRight)[1]-self.sy;return 1
  elif bottomLeftTile in world.deadTiles or bottomRightTile in world.deadTiles:self.playDead()
  return 0
 def onCeiling(it):
  topLeft=world.getMapTileAtPoint(it.x+it.collision_preciseness,it.y);topLeftTile=world.getTile(*topLeft);topRight=world.getMapTileAtPoint(it.x+it.sx-it.collision_preciseness,it.y);topRightTile=world.getTile(*topRight)
  if topLeftTile in world.colliderTiles or topRightTile in world.colliderTiles:it.vy=max(0,it.vy);it.y=world.getMapTilePosition(*topLeft)[1]+world.scale;return 1
  elif topLeftTile in world.deadTiles or topRightTile in world.deadTiles:it.playDead()
  return 0
 def onRightWall(it):
  topRight=world.getMapTileAtPoint(it.x+it.sx,it.y+it.collision_preciseness);topRightTile=world.getTile(*topRight);bottomRight=world.getMapTileAtPoint(it.x+it.sx,it.y+it.sy-it.collision_preciseness);bottomRightTile=world.getTile(*bottomRight)
  if topRightTile in world.colliderTiles or bottomRightTile in world.colliderTiles:it.vx=min(0,it.vx);it.x=world.getMapTilePosition(*topRight)[0]-it.sx;return 1
  if topRightTile in world.deadTiles or topRightTile in world.deadTiles:it.playDead()
  return 0
 def onLeftWall(it):
  topLeft=world.getMapTileAtPoint(it.x,it.y+it.collision_preciseness);topLeftTile=world.getTile(*topLeft);bottomLeft=world.getMapTileAtPoint(it.x,it.y+it.sy-it.collision_preciseness);bottomLeftTile=world.getTile(*bottomLeft)
  if topLeftTile in world.colliderTiles or bottomLeftTile in world.colliderTiles:it.vx=max(0,it.vx);it.x=world.getMapTilePosition(*topLeft)[0]+world.scale;return 1
  if topLeftTile in world.deadTiles or bottomLeftTile in world.deadTiles:it.playDead()
  return 0
 def fixCollisions(it):it.on_ground=it.onGround();it.on_right_wall=it.onRightWall();it.on_left_wall=it.onLeftWall();it.onCeiling()
 def playDead(it):it.init();it.deathCounter+=1
 def updt(it):
  gravity=.02;it.old_x,it.old_y=it.x,it.y;arrowLeft=K(0);arrowRight=K(3);arrowUp=K(1);arrowDown=K(2);okPressed=K(4);homePressed=K(5);onOffPressed=K(17)
  if world.chapter!=0 and world.currentLevel==len(world.data)-1:
   if it.last_level_jump:S(.2);it.vy=-1.3;it.last_level_jump=0
   it.vx=.7;okPressed=1
   if it.on_ground:
    for i in range(10):D("You did it"[i],110+i*10,100,"w",tile_colors[0]);S(.14)
    S(.5)
    for i in range(80):D("You did it",110,100-i,"w",tile_colors[0]);S(.02)
    a="You died "+str(it.deathCounter)+" time"+"s"*(it.deathCounter>1)
    for i in range(len(a)):D(a[i],160-(len(a)*10)//2+i*10,100,"w",tile_colors[0]);S(.05)
    S(.5)
    for i in range(50):D(a,160-(len(a)*10)//2,100-i,"w",tile_colors[0]);S(.02)
    S(.3);t=M()-world.t;a="It took you "+str(int(t//60))+" min and "+str(round(t)%60)+" sec"
    for i in range(len(a)):D(a[i],160-(len(a)*10)//2+i*10,100,"w",tile_colors[0]);S(.05)
    S(.3)
    for i in range(20):D(a,160-(len(a)*10)//2,100-i,"w",tile_colors[0]);S(.02)
    S(.3)
    for i in range(8):D("Congrats"[i],120+i*10,110,"w",tile_colors[0]);S(.05)
    S(.3)
    for i in range(10):D("Press [OK]"[i],110+i*10,140,"w",tile_colors[0]);S(.02)
    while K(4)^1:0
    home_menu()
  if not it.dashing:
   arrSum=arrowRight-arrowLeft
   if arrSum:
    if it.on_ground:it.vx+=.04*arrSum
    else:it.vx+=.015*arrSum
   else:
    if it.on_ground:it.vx/=1.5
    else:it.vx/=1.1
   it.vx=max(-0.8,min(0.8,it.vx))
   if okPressed:
    if it.on_ground:it.vy=-1.3
    elif it.on_left_wall or it.on_right_wall:it.vy=-.8;it.vx=.8*(it.on_left_wall-it.on_right_wall)
   elif it.vy<0 and not it.jumping_trampoline:it.vy=max(-0.5,it.vy)
   if it.jumping_trampoline and it.vy>0:it.jumping_trampoline=0
   if not it.climbing:it.vy+=gravity;it.vy=min(8,it.vy,0.8+50*((not it.on_left_wall and not it.on_right_wall) or it.climbing_time>it.max_climbing_time))
   if homePressed and(it.on_left_wall or it.on_right_wall):
    if it.climbing_time<it.max_climbing_time:
     if not it.climbing:it.vy=0
     it.climbing=1
   else:it.climbing=0
   it.check_level_one()
   if it.climbing:
    arrVsum=arrowDown-arrowUp
    if arrVsum==0:it.vy/=2
    else:it.vy+=it.climbing_speed*arrVsum;it.vy=max(-it.max_climbing_speed,min(it.max_climbing_speed,it.vy))
    it.climbing_time+=1+abs(arrVsum)*3
    if it.climbing_time>it.max_climbing_time:
     it.climbing=0
     if it.climbing_delay==-1:it.climbing_delay=0
   dashed=0
   if keyinput(17,onOffPressed)and it.nb_dash>0:
    it.jumping_trampoline=0;it.nb_dash-=1;it.dashing=1;dashed=1;it.vx=it.dash_speed*(arrSum+(not arrowDown and not arrowUp and not arrowLeft and not arrowRight));it.vy=it.dash_speed*(arrowDown-arrowUp)
    if it.vx!=0 and it.vy!=0:it.diagonal_dash=1
   if it.on_ground:
    if not dashed:it.nb_dash=it.max_nb_dash
    it.climbing_time=0;it.col=it.ori_col;it.climbing_delay=-1
   if it.climbing_delay%20==0:
    if it.climbing_delay!=-1:it.climbing_speed+=1
    if it.col==it.ori_col:it.col="r"
    else:it.col=it.ori_col
  else:
   it.dash_time+=1+.5*it.diagonal_dash
   if it.dash_time%(4-it.diagonal_dash)==0:Ghost()
   if it.dash_time>it.max_dash_time:it.dashing=0;it.diagonal_dash=0;it.dash_time=0
  it.y+=it.vy;it.x+=it.vx
  if(it.x<0 and world.data[world.currentLevel][-1]==0)or(it.y<0 and world.data[world.currentLevel][-1]==1)or(it.x>320 and world.data[world.currentLevel][-1]==2)or(it.y>222 and world.data[world.currentLevel][-1]==3):world.currentLevel+=1;it.init()
  elif it.y<0 or it.y>222 or it.x<0 or it.x>320:it.deathCounter+=1;it.init()
  it.fixCollisions();it.drw(it.old_x,it.old_y,tile_colors[0]);will_move=[(it.x>270)-(it.x<40),(it.y>180)-(it.y<40)]
  if will_move!=[0,0]:world.move(*will_move)
  it.drw(it.x,it.y,it.col)
world=World();player=Player()
def home_menu():
 z=load_level(4);F(0,0,320,222,tile_colors[0]);drw_logo();s=["[0] Prologue","[1] Chapter 1 - A side","[2] Chapter 1 - B side","[3] Chapter 1 - C side","[4] Chapter 1 - Custom"]
 for i in range(4+(z!=0)):D(s[i],20,115+20*i,"w",tile_colors[0])
 while 1:
  for i in range(5):
   if K([48,42,43,44,36][i])and(i!=4 or z):world.chapter=i;world.currentLevel=0;world.data=load_level(i);world.t=M();player.deathCounter=0;player.init();return
home_menu()
while 1:
 F(0,0,320,14,(248,180,48));player.updt()
 for i in ghosts:i.drw()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.