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()