“Celeste” - Jeu original développé par Maddy Makes Games Réutilisation des idées, textures et logo avec l’autorisation de Maddy Makes Games.
Allez voir le jeu original, il est vraiment trop bien: https://www.celestegame.com/
Il y a besoin de celeste_levels.py
from kandinsky import * from time import * from ion import * import micropython as mp mp.kbd_intr(KEY_HOME) def load_level(n): f=open("celeste_levels.py","r") for i in range(n+1): while f.readline()!="\n": pass levels = ["("] a="" while a!="\n": a=f.readline() levels.append(a.replace("\x00","").replace("\n","")) f.close() levels.pop(-1) levels.append(")") return "".join(levels) def draw_image(rle,x0,y0,w,pal,zoomx,zoomy,itransp=-1): i,x = 0,0 x0,y0=int(x0),int(y0) nvals = len(pal) -1 nbits = 0 while nvals: nvals>>=1 nbits+=1 maskval = (1<<nbits)-1 maskcnt = (0xFF>>nbits>>1)<<nbits while i<len(rle): v=rle[i] mv=v&maskval c=(v&maskcnt) >> nbits if v&0b10000000 or nbits==8: i+=1 c|=rle[i]<<(7-nbits+(nbits==8)) c+=1 while c: cw=min(c,w-x) if mv!=itransp: fill_rect(x0+x*zoomx,y0,cw*zoomx,zoomy,pal[mv]) c-=cw x=(x+cw)%w y0 += x==0 and zoomy i+=1 palette = ("#f8f0e0","#20b0f8",(0,0,100),"#00e850","#f80048","#645450","#c0c0c0","#f8a000","#a85030") images = (None, None, b"\2\xa0\x021 A\20Q\20\21\20\21\20\21\20\21\20Q", b"\xf0\1\1P1\20\xa1\4", b"`\2\xf0\x0010A Q\20!\0\21\20Q\20Q\20", b"\20Q\20Q\20\21\0!\20Q A01\xf0\0\2`", b"\xa1\4\x101P\1\xf0\1", b"Q\20Q\20\1\20!\20\1\20!\20A 1\xa0\2\2", b"\20Q A A0101 A A\20Q", b"\xf1\a", b"Q\20A A 1010A A Q\20", b"\2\xa0\2!0A A0!\x80\1\2`", b"\x80\3\x01010\1\x80\3", b"`\2\x80\1!0A A0!\xa0\2\2", b"\2P\2\xa0\2\21@1010\1\0\x1101\20", b" !@\21P\21@!@101@\21 \2P\2", b"\x101@!@!0!@!P\21P\21@1\20", b"\2P\2\xa0\1\1P101@\21\xa0\1\2P\2", b'\x82\1\b7\b"\5\22\5B\25B\5\22\5B\25B\5\22\5B\25', b"\x95\x022525252\x95\2", b'\22\0"\0"\0"\0"\0"\0\22\6\20\2\6\20\2\6\0\6\2\6\0\6\5\6\0\6\5\6\0\6\5\6\0\6\5\6\0\6\5&\5&', b'%B6\0"\6`F"%B6\0"\6`F"', b'&\5&\5\6\0\6\5\6\0\6\5\6\0\6\5\6\0\6\5\6\0\6\2\6\0\6\2\6\20\2\6\20\22\0"\0"\0"\0"\0"\0\22', b'"F`\6"\x006B%"F`\6"\x006B%', b'\22\3\2\23B\23B4"\4\a4\x124\a\4\22\24\a$"4B\24"') palette2 = ( "k","#b8c0c0","#787898","#10acf8", ) logo = ( b"l\1\xd0\1\1\0\1\xc8\1\2\b\1\xc0\1\2\20\3\xb8\1\2\24\3\xb4\1\3\30\3\b\1\xa0\1\2 \3\0\2\0\2\x98\1\3(\2\b\2\x94\1\3\x84\1\21\4\25\4\5\4\3\b\25\b\21\4\25\4\25\0\31\0\31\0\5\0\3\f\31\0\31\0\31\0!\b\5\0\5\24\5\24\5\24\5\34\5\f\5\20\6\24\16\f\6\24\16\f\32\b\6\f\16\b\6\b\6\0\6\24\6\f\2\0\6,\2\b\6\f\6\20\32\0\26\4\32\0\26\4\32\b\6\f\26\4\22\4\32\0\32\0\32\4\22\f\6\f\32\x8c\2\3t\3T\3\xfc\0\3H\a\x84\1\3@\3\x8c\1\3<\3\x90\1\38\3\x94\1\3\4\a$\3\x98\1\3\0\3\0\3 \3\xa0\1\3\b\3\34\3\xb0\1\3\34\3\xb4\1\3\24\3\xbc\1\3\f\3\xc4\1\3" ) def drw_logo(): draw_image(logo, 105, 20, 55, palette2, zoomx=2, zoomy=2, itransp=0) def drw_texture(i,x,y): if i<2: fill_rect(x,y,16,16,(0,0,100)) else: draw_image(images[i],x,y,8,palette,2,2) keys = {} def keyinput(key,value=None): if value!=None: keyPressed = value else: keyPressed = keydown(key) if not key in keys: keys[key] = False if keyPressed and not keys[key]: keys[key] = True return True if keys[key]: if not keyPressed: keys[key] = False return False return False tile_colors = ((0,0,100),(220,150,50),(0,200,250),(255,0,0),(150,150,0)) class World: def __init__(self): self.chapter = 0 self.x = 0 self.y = 14 self.dataX = 0 self.dataY = 0 self.dataHeight = 13 self.dataWidth = 20 self.nb_on_screen = (20,13) self.colors = tile_colors self.scale = 16 self.deadTiles = {20,21,22,23} self.colliderTiles = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19} self.spawnTile = 1 self.trampoline = 18 self.currentLevel = 8 self.data = tuple() self.t = monotonic() def drw(self): fill_rect(0,14,320,208,tile_colors[0]) for i in range(self.nb_on_screen[1]): for j in range(self.nb_on_screen[0]): drw_texture(ord(self.data[self.currentLevel][0][(self.dataY+i)*self.dataWidth+j+self.dataX])-95,self.x+j*self.scale,self.y+i*self.scale) def move(self,x,y): if 0>self.dataX+x or self.dataWidth-self.nb_on_screen[0]<self.dataX+x: x=0 if 0>self.dataY+y or self.dataHeight-self.nb_on_screen[1]<self.dataY+y: y=0 if x==0 and y==0: return for ghost in ghosts: fill_rect(ghost.x,ghost.y,ghost.sx,ghost.sy,tile_colors[0]) ghost.x -= x*self.scale ghost.y -= y*self.scale on_screen_before = [self.data[self.currentLevel][0][(self.dataY+i)*self.dataWidth+self.dataX:(self.dataY+i)*self.dataWidth+self.dataX+self.nb_on_screen[0]] for i in range(self.nb_on_screen[1])] self.dataX += x self.dataY += y on_screen_now = [self.data[self.currentLevel][0][(self.dataY+i)*self.dataWidth+self.dataX:(self.dataY+i)*self.dataWidth+self.dataX+self.nb_on_screen[0]] for i in range(self.nb_on_screen[1])] for i in range(self.nb_on_screen[1]): for j in range(self.nb_on_screen[0]): if on_screen_before[i][j] != on_screen_now[i][j]: drw_texture(ord(on_screen_now[i][j])-95,self.x+j*self.scale,self.y+i*self.scale) player.y -= y*self.scale player.x -= x*self.scale def getMapTileAtPoint(self,x,y): return (int((x+self.dataX*self.scale-self.x)/self.scale), int((y+self.dataY*self.scale-self.y)/self.scale)) def getMapTilePosition(self,x,y): return ((x-self.dataX)*self.scale+self.x, (y-self.dataY)*self.scale+self.y) def getTile(self,x,y): if x<0 or x>=self.dataWidth or y<0 or y>=self.dataHeight: return 0 return ord(self.data[self.currentLevel][0][y*self.dataWidth+x])-95 ghosts = [] class Ghost: def __init__(self): ghosts.append(self) self.x = round(player.x) self.y = round(player.y) self.sx = player.sx self.sy = player.sy self.c = player.ori_col self.max_step = 50 self.step = 0 def drw(self): fill_rect(self.x,self.y,self.sx,self.sy,self.c) if self.step == self.max_step: ghosts.remove(self) del self return self.step += 1 self.c = ((self.c[0]*(self.max_step-self.step)+tile_colors[0][0]*self.step)//self.max_step, (self.c[1]*(self.max_step-self.step)+tile_colors[0][1]*self.step)//self.max_step, (self.c[2]*(self.max_step-self.step)+tile_colors[0][2]*self.step)//self.max_step,) class Player: def __init__(self): self.sx = 8 self.sy = 14 self.vx = 0 self.vy = 0 self.ori_col = (0,200,0) self.col = (0,200,0) self.nb_dash = 1 self.max_nb_dash = 1 self.dashing = False self.dash_time = 0 self.max_dash_time = 16 self.dash_speed = 4 self.diagonal_dash = False self.on_ground = False self.on_right_wall = False self.on_left_wall = False self.jumping_trampoline = False self.climbing = False self.climbing_time = 0 self.max_climbing_time = 1000 self.climbing_speed = 0.04 self.max_climbing_speed = 0.8 self.climbing_delay = -1 self.tuto_can_dash = False self.tuto_can_climb = False self.tuto_can_walljump = False self.last_level_jump = True self.deathCounter = 0 self.collision_preciseness = 1 def init(self): if world.currentLevel == 0: self.tuto_can_climb = False self.tuto_can_dash = False 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)) self.x,self.y = world.getMapTilePosition(x2,y2) self.old_x,self.old_y = self.x,self.y self.vx,self.vy = 0,0 self.dashing = False self.dash_time = 0 world.drw() def drw(self,x,y,c): fill_rect(round(x),round(y),self.sx,self.sy,c) def check_level_one(self): if world.chapter!=0: return if self.x+world.dataX*world.scale<50 and world.currentLevel==0: self.climbing=False if not self.tuto_can_climb: draw_string("Climb with [back]",75,20,"w",tile_colors[0]) self.tuto_can_climb = True if 170>world.dataX*world.scale+self.x>154: draw_string("Climb with [back]",75,20,tile_colors[0],tile_colors[0]) if world.currentLevel==1: if not self.tuto_can_walljump: draw_string("Walljump by pressing\n[OK] against a wall",3,17,"w",tile_colors[0],1) self.tuto_can_walljump = True if world.dataX*world.scale+self.x<448 or world.currentLevel!=3: self.nb_dash = 0 else: if not self.tuto_can_dash: for i in range(10): self.old_x,self.old_y = self.x,self.y world.move(1,0) self.drw(self.old_x,self.old_y,tile_colors[0]) self.drw(self.x,self.y,"g") sleep(0.05) for i in range(18): draw_string("Dash with [on/off]"[i],70+i*10,20,"w",tile_colors[0]) sleep(0.08) while not keydown(KEY_ONOFF): pass draw_string("Dash with [on/off]",70,20,tile_colors[0],tile_colors[0]) self.jumping_trampoline = False self.dashing = True dashed = True self.vx = self.dash_speed self.vy = -self.dash_speed self.diagonal_dash=True self.tuto_can_dash = True else: self.vx=0.4 if self.on_ground: sleep(0.5) for i in range(21): fill_rect(0,14+i*10,320,10,(100,0,75)) sleep(0.05) sleep(0.2) for i in range(15): draw_string("You can do this"[i],85+i*10,100,"w",(100,0,75)) sleep(0.15) sleep(1.5) for i in range(9): draw_string("Good luck"[i],115+i*10,130,"w",(100,0,75)) sleep(0.1) sleep(1) for i in range(10): draw_string("Press [OK]"[i],110+i*10,190,"w",(100,0,75)) sleep(0.1) while not keydown(4): pass 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 = True else: self.vy = min(0,self.vy) self.y = world.getMapTilePosition(*bottomRight)[1]-self.sy return True elif bottomLeftTile in world.deadTiles or bottomRightTile in world.deadTiles: self.playDead() return False def onCeiling(self): topLeft = world.getMapTileAtPoint(self.x+self.collision_preciseness,self.y) topLeftTile = world.getTile(*topLeft) topRight = world.getMapTileAtPoint(self.x+self.sx-self.collision_preciseness,self.y) topRightTile = world.getTile(*topRight) if topLeftTile in world.colliderTiles or topRightTile in world.colliderTiles: self.vy = max(0,self.vy) self.y = world.getMapTilePosition(*topLeft)[1]+world.scale return True elif topLeftTile in world.deadTiles or topRightTile in world.deadTiles: self.playDead() return False def onRightWall(self): topRight = world.getMapTileAtPoint(self.x+self.sx,self.y+self.collision_preciseness) topRightTile = world.getTile(*topRight) bottomRight = world.getMapTileAtPoint(self.x+self.sx,self.y+self.sy-self.collision_preciseness) bottomRightTile = world.getTile(*bottomRight) if topRightTile in world.colliderTiles or bottomRightTile in world.colliderTiles: self.vx = min(0,self.vx) self.x = world.getMapTilePosition(*topRight)[0]-self.sx return True if topRightTile in world.deadTiles or topRightTile in world.deadTiles: self.playDead() return False def onLeftWall(self): topLeft = world.getMapTileAtPoint(self.x,self.y+self.collision_preciseness) topLeftTile = world.getTile(*topLeft) bottomLeft = world.getMapTileAtPoint(self.x,self.y+self.sy-self.collision_preciseness) bottomLeftTile = world.getTile(*bottomLeft) if topLeftTile in world.colliderTiles or bottomLeftTile in world.colliderTiles: self.vx = max(0,self.vx) self.x = world.getMapTilePosition(*topLeft)[0]+world.scale return True if topLeftTile in world.deadTiles or bottomLeftTile in world.deadTiles: self.playDead() return False def fixCollisions(self): self.on_ground = self.onGround() self.on_right_wall = self.onRightWall() self.on_left_wall = self.onLeftWall() self.onCeiling() def playDead(self): self.init() self.deathCounter += 1 def updt(self): gravity = 0.02 self.old_x,self.old_y = self.x,self.y pressedKeys = get_keys() arrowLeft = "left" in pressedKeys arrowRight = "right" in pressedKeys arrowUp = "up" in pressedKeys arrowDown = "down" in pressedKeys okPressed = "OK" in pressedKeys homePressed = "back" in pressedKeys onOffPressed = "onOff" in pressedKeys if world.chapter!=0 and world.currentLevel==len(world.data)-1: if self.last_level_jump: sleep(0.2) self.vy=-1.3 self.last_level_jump = False self.vx=0.7 okPressed = True if self.on_ground: for i in range(10): draw_string("You did it"[i],110+i*10,100,"w",tile_colors[0]) sleep(0.14) sleep(0.5) for i in range(80): draw_string("You did it",110,100-i,"w",tile_colors[0]) sleep(0.02) a="You died "+str(self.deathCounter)+" time"+"s"*(self.deathCounter>1) for i in range(len(a)): draw_string(a[i],160-(len(a)*10)//2+i*10,100,"w",tile_colors[0]) sleep(0.05) sleep(0.5) for i in range(50): draw_string(a,160-(len(a)*10)//2,100-i,"w",tile_colors[0]) sleep(0.02) sleep(0.3) t=monotonic()-world.t a="It took you "+str(int(t//60))+" min and "+str(round(t)%60)+" sec" for i in range(len(a)): draw_string(a[i],160-(len(a)*10)//2+i*10,100,"w",tile_colors[0]) sleep(0.05) sleep(0.3) for i in range(20): draw_string(a,160-(len(a)*10)//2,100-i,"w",tile_colors[0]) sleep(0.02) sleep(0.3) for i in range(8): draw_string("Congrats"[i],120+i*10,110,"w",tile_colors[0]) sleep(0.05) sleep(0.3) for i in range(10): draw_string("Press [OK]"[i],110+i*10,140,"w",tile_colors[0]) sleep(0.02) while not keydown(4): pass home_menu() if not self.dashing: arrowHori = arrowRight-arrowLeft if arrowHori != 0: if self.on_ground: self.vx += 0.04*arrowHori else: self.vx += 0.015*arrowHori else: if self.on_ground: self.vx /= 1.5 else: self.vx /= 1.1 self.vx = max(-0.8,min(0.8,self.vx)) if okPressed: if self.on_ground: self.vy = -1.3 elif self.on_left_wall or self.on_right_wall: self.vy = -0.8 self.vx = 0.8*(self.on_left_wall-self.on_right_wall) elif self.vy < 0 and not self.jumping_trampoline: self.vy = max(-0.5,self.vy) if self.jumping_trampoline and self.vy > 0: self.jumping_trampoline = False if not self.climbing: self.vy += gravity self.vy = min(8,self.vy,0.8+50*((not self.on_left_wall and not self.on_right_wall) or self.climbing_time>self.max_climbing_time)) if homePressed and (self.on_left_wall or self.on_right_wall): if self.climbing_time<self.max_climbing_time: if not self.climbing: self.vy = 0 self.climbing = True else: self.climbing = False self.check_level_one() if self.climbing: arrowVerti = arrowDown-arrowUp if arrowVerti == 0: self.vy /= 2 else: self.vy += self.climbing_speed*arrowVerti self.vy = max(-self.max_climbing_speed,min(self.max_climbing_speed,self.vy)) self.climbing_time += 1+abs(arrowVerti)*3 if self.climbing_time > self.max_climbing_time: self.climbing = False if self.climbing_delay==-1: self.climbing_delay = 0 dashed = False if keyinput(KEY_ONOFF,onOffPressed) and self.nb_dash>0: self.jumping_trampoline = False self.nb_dash -= 1 self.dashing = True dashed = True self.vx = self.dash_speed*(arrowHori+(not arrowDown and not arrowUp and not arrowLeft and not arrowRight)) self.vy = self.dash_speed*(arrowDown-arrowUp) if self.vx != 0 and self.vy != 0: self.diagonal_dash = True if self.on_ground: if not dashed: self.nb_dash = self.max_nb_dash self.climbing_time = 0 self.col = self.ori_col self.climbing_delay = -1 if self.climbing_delay%20==0: if self.climbing_delay!=-1: self.climbing_speed += 1 if self.col == self.ori_col: self.col = "r" else: self.col = self.ori_col else: self.dash_time += 1+0.5*self.diagonal_dash if self.dash_time%(4-self.diagonal_dash)==0: Ghost() if self.dash_time > self.max_dash_time: self.dashing = False self.diagonal_dash = False self.dash_time = 0 self.y += self.vy self.x += self.vx if (self.x<0 and world.data[world.currentLevel][-1]==0) or (self.y<0 and world.data[world.currentLevel][-1]==1) or (self.x>320 and world.data[world.currentLevel][-1]==2) or (self.y>222 and world.data[world.currentLevel][-1]==3): world.currentLevel += 1 self.init() elif self.y<0 or self.y>222 or self.x<0 or self.x>320: self.deathCounter += 1 self.init() self.fixCollisions() self.drw(self.old_x,self.old_y,tile_colors[0]) will_move = [int((self.x>270)-(self.x<40)),int((self.y>180)-(self.y<40))] if will_move != [0,0]: world.move(*will_move) self.drw(self.x,self.y,self.col) world = World() player = Player() def home_menu(): fill_rect(0,0,320,222,tile_colors[0]) drw_logo() draw_string("[0] Prologue",20,115,"w",tile_colors[0]) draw_string("[1] Chapter 1 - A side",20,135,"w",tile_colors[0]) draw_string("[2] Chapter 1 - B side",20,155,"w",tile_colors[0]) draw_string("[3] Chapter 1 - C side",20,175,"w",tile_colors[0]) if len(eval(load_level(4)))!=1: draw_string("[4] Chapter 1 - Custom",20,195,"w",tile_colors[0]) a=[KEY_ZERO,KEY_ONE,KEY_TWO,KEY_THREE,KEY_FOUR] while 1: for i in range(5): if keydown(a[i]): world.chapter = i world.currentLevel = 0 world.data = eval(load_level(i)) world.t = monotonic() player.deathCounter = 0 player.init() return home_menu() while 1: fill_rect(0,0,320,14,(248,180,48)) player.updt() for i in ghosts: i.drw()