Un remake de Chrome Dino sur Numworks !
from math import * from random import * from kandinsky import * from ion import * from time import sleep, monotonic # Window W,H = 320,222 SIZE, WIN = (W,H), (0,0,W,H) FONTW, FONTH = 10,18 # Utils def clamp(m,x,M): return max(m,min(x,M)) def proba(n): return randint(1,n)==1 def ints(list): return tuple(int(x) for x in list) def center_pos(rect): return rect[0]+rect[2]//2, rect[1]+rect[3]//2 def collide_x(r1,r2): return r1[0] < r2[0]+r2[2] and r2[0] < r1[0]+r1[2] def collide_y(r1,r2): return r1[1] < r2[1]+r2[3] and r2[1] < r1[1]+r1[3] def collide (r1,r2): return collide_x(r1,r2) and collide_y(r1,r2) # - colors BLACK = (0, 0, 0) DARK_GRAY = (95, 87, 79) LIGHT_GRAY = (194, 195, 199) WHITE = (255, 241, 232) # 4-7 DARK_BLUE = (29, 43, 83) BLUE = (41, 173, 255) DARK_GREEN = (0, 135, 81) GREEN = (0, 228, 54) # 8-B YELLOW = (255, 236, 39) ORANGE = (255, 163, 0) RED = (255, 0, 77) BROWN = (171, 82, 54) # C-F PEACH = (255, 204, 170) PINK = (255, 119, 168) PURPLE = (126, 37, 83) LAVENDER = (131, 118, 156) COLORS = [BLACK, DARK_GRAY, LIGHT_GRAY, WHITE, DARK_BLUE, BLUE, DARK_GREEN, GREEN, YELLOW, ORANGE, RED, BROWN, PEACH, PINK, PURPLE, LAVENDER] # Image module def draw_rect(rect, color): fill_rect(int(rect[0]),int(rect[1]),int(rect[2]),int(rect[3]),color) def fill(color=WHITE): draw_rect(WIN, color) def draw_image(img,color=BLACK, X=0,Y=0): "( (x,y,w,h[,color]), ... )" for r in img: draw_rect((X+r[0],Y+r[1], r[2], r[3]), (r[4] if len(r) > 4 else color)) def draw_text(text, x, y, side="topleft", color=BLACK, background=WHITE): if "right" in side: x -= len(text)*FONTW elif not "left" in side: x -= len(text)*FONTW/2 if "bottom" in side: y -= FONTH elif not "top" in side: y -= FONTH/2 draw_string(text, int(round(x)),int(round(y)), color, background) # Time (time: temps de la FRAME ! ne pas utiliser en dehors d'engine) time,timers = 0,{} def every(dt): if dt not in timers: timers[dt] = time return (time - timers[dt]) >= dt def timer(t, dura): return (monotonic() - t) >= dura # update pressed = {} just_pressed = {} def update(keys=[KEY_OK]): """ keys: touches inscrites dans just_pressed. BIG ATTENTION: ne JAMAIS utiliser just_pressed dans un "every" """ global time for dt in timers: if time-timers[dt] >= dt: timers[dt] = time time = monotonic() for key in keys: kd = keydown(key) just_pressed[key] = kd and not pressed.get(key) pressed[key] = kd return True ## DINO low_detail = False started = jumped = False scale = 4 def add(r1,r2): res = [] for i in range(max(len(r1),len(r2))): x = r1[i] if i < len(r1) else 0 y = r2[i] if i < len(r2) else 0 res.append(x+y) return res def scaled(*list): return [x*scale for x in list] def bottom(rect): return rect[1]+rect[3] def right(rect): return rect[0]+rect[2] # Game def game(): global low_detail, started, jumped floor = (0, 136, W, H-136) crouch = False vy = 0 JUMP_HEIGHT = 14 left_foot, right_foot = scaled(1,8,2,1), scaled(4,8,2,1) head = (scaled(5,0,4,4), scaled(6,2,4,4)) dino = [head[crouch],scaled(0,3,7,4),scaled(1,7,2,1),scaled(4,7,2,1)] dino_rects = [[100, floor[1]-15*scale, w*scale, 9*scale] for w in (9,10)] dino_rect = dino_hitbox = dino_rects[crouch] cactus = [] next = 1 speed = 35 score = 0 time = monotonic() bg, fg = LIGHT_GRAY, DARK_GRAY text_colors = BLACK, WHITE cactus_colors = DARK_GREEN, GREEN dino_colors = DARK_GRAY, LIGHT_GRAY def draw_dino(started): dino[0] = head[crouch] if low_detail: draw_rect(dino_hitbox, dino_colors[0]) else: # corps du dino (tete, corps, jambe) draw_image(dino, dino_colors[0], *dino_rect[:2]) # pieds du dino if bottom(dino_rect) == floor[1] and started: foot = int(monotonic() // .2 +1) %2 draw_rect(add(left_foot, dino_rect[:2]), (bg,dino_colors[0])[foot]) draw_rect(add(right_foot,dino_rect[:2]), (dino_colors[0],bg)[foot]) # jeu a pas commencé ... elif bottom(dino_rect) == floor[1] and not started: draw_rect(add(left_foot, dino_rect[:2]), dino_colors[0]) draw_rect(add(right_foot,dino_rect[:2]), dino_colors[0]) def draw_low_detail_text(jumped): textcol, bgcol = ((BLACK,bg),(text_colors[1],fg))[jumped] draw_text((" shift | low detail ","[ shift | low detail ]")[low_detail], W/2,H*.92,"center",textcol, bgcol) fill(bg) if not started: draw_rect((dino_rect[0]-20, floor[1], dino_rect[2]+40, 40),fg) else: draw_rect(floor,fg) draw_low_detail_text(jumped) draw_text("0000", W-20,20,"topright",text_colors[0],bg) draw_dino(started) while update(keys=(KEY_OK,KEY_DOWN,KEY_SHIFT)): if just_pressed[KEY_DOWN]:vy = JUMP_HEIGHT if just_pressed[KEY_SHIFT]: low_detail = not low_detail draw_low_detail_text(jumped) # Dino if every(.02): # Input old_hitbox = dino_hitbox[:] crouch = keydown(KEY_DOWN) r = dino_rects[crouch] r[1] = bottom(dino_rect) - r[3] dino_rect = r if crouch: dino_hitbox = add(dino_rect, scaled(0,2,0,-2)) else: dino_hitbox = dino_rect if keydown(KEY_UP) and bottom(dino_rect) == floor[1]: vy = -JUMP_HEIGHT # (début) jumped = True if not started: fill_rect(0, 20, int(W*.7), 20, bg) draw_rect(floor,fg) draw_low_detail_text(jumped) # Y movement if vy < 0 or bottom(dino_rect) < floor[1]: vy += 1 dino_rect[1] += vy dino_rect[1] = min(dino_rect[1], floor[1]-dino_rect[3]) else: vy = 0 dino_rect[1] = floor[1] - dino_rect[3] # (début) if jumped: started = True elif not started: draw_text("jump to start", W/2, 20, "midtop", background=bg) # Draw if vy or started: draw_rect(old_hitbox, bg) draw_dino(started) # Cactus if started and every(.15): bin = [] # update all for type, r in cactus: # predraw draw_rect(r, bg) # move r[0] -= speed # delete if right(r) < 0: bin.append((type,r)); continue for c in bin: cactus.remove(c) # gameover gameover, cactus_dx = False, 0 for type, r in cactus: if collide(r, dino_hitbox): cactus_dx = right(dino_rect) - r[0] gameover = True break if gameover: break # draw all for type, r in cactus: draw_rect(r, cactus_colors[type]) # new if timer(time, next): time = monotonic() next = .5 + random()*1.5 air = proba(3) size = [randint(6,10)*scale]*2 if not air else [6*scale,4*scale] cactus.append((air, [W, floor[1]-size[1] - 28*air*randint(1,2), size[0], size[1]])) # Score if started and every(.2): score += 1 if score%100 == 0: bg, fg = fg, bg speed = min(70, speed+score%100 * 10) cactus_colors = (cactus_colors[1],cactus_colors[0]) text_colors = (text_colors[1],text_colors[0]) dino_colors = (dino_colors[1],dino_colors[0]) fill(bg) draw_rect(floor,fg) draw_text("0000", W-20,20,"topright",text_colors[0],bg) draw_low_detail_text(jumped) draw_text(str(score), W-20,20,"topright",text_colors[0],bg) for type, r in cactus: r[0] += cactus_dx draw_rect(r, cactus_colors[type]) draw_text("ok to retry", W/2,H*.7,"center",text_colors[1],fg) draw_text("esc to quit", W/2,H*.8,"center",text_colors[1],fg) while not (update() and just_pressed.get(KEY_OK)): pass game() # Start game()