# coding: utf-8 """ A simple snake game. (c) Julian Habrock , 8/2009 bytemuehle.de """ import random import pygame import pygame.locals as loc DIRS = {loc.K_UP:(0, -1), loc.K_RIGHT:(1, 0), loc.K_DOWN:(0, 1), loc.K_LEFT:(-1, 0)} COLORS = {"black":(0, 0, 0), "orange":(255, 140, 135), "red":(255, 0, 0), "green":(0, 255, 0), "mangenta":(205, 35, 120)} COLS, ROWS = 64, 40 FPS = 26 def main(): """main game function""" # Options (change ingame) bite_yourself = True use_circles = True hard_border = True show_fps = True # Initialize everything pygame.init() icon = pygame.Surface((32, 32)) icon.set_colorkey((0, 0, 0)) pygame.draw.circle(icon, COLORS["green"], (16, 16), 10) pygame.display.set_icon(icon) screen = pygame.display.set_mode((COLS*10, ROWS*10+30)) pygame.display.set_caption('5n4k3 - by jug') pygame.mouse.set_visible(0) clock = pygame.time.Clock() font = pygame.font.Font(None, 26) # Internal variables and flags alive = False paused = False counter = 0 bricks, apple = [], None dir_ = (1, 0) drects = [] # small hepler function func = use_circles and pygame.draw.ellipse or pygame.draw.rect drawbrick = lambda b, c:drects.append(func(screen, COLORS[c], (b[0]*10, b[1]*10, 10, 10))) def draw_menu(template=False): """ draw the menu, depending on game status. Note: Will blit variable values only until ``template`` is True """ if alive: if template: data = ( ( (("apples:", 21), ("fps:", 121) if show_fps else None, ("lay" if paused else "ause", 510), ("enu", 595)), (0, 0, 0)), ( (("p", 500), ("m", 580)), (0, 0, 200))) else: data = ( ( (("%2.i " % counter if counter else " 0", 87), ("%2.i " % int(clock.get_fps()), 158)if show_fps else None), (0, 200, 0)), ) else: if template: data = ( ( (("r", 20), ("b", 165), ("s", 345), ("n", 480), ("esc", 575)), (0, 0, 200)), ( (("ound forms:", 27), ("locking borders:", 175), ("how fps:", 354), ("ew game", 490), ("ape", 602)), (0, 0, 0))) else: data = (( ((use_circles, 131), (hard_border, 315), (show_fps, 429)), None), ) if template: drects.append(screen.fill((255, 255, 255), (0, ROWS*10, COLS*10, 30))) for dataset, color in data: for data in dataset: if not data: continue text, xpos = data if not color: color2 = text and (0, 200, 0) or (200, 0, 0) text = text and "on " or "off" text_surf = font.render(text, 1, color or color2, (255, 255, 255)) drects.append(text_surf.get_rect(topleft=(xpos, ROWS*10+5))) screen.blit(text_surf, (xpos, ROWS*10+5)) draw_menu(1) while 1: clock.tick(FPS) for event in pygame.event.get(): if event.type == loc.QUIT: return elif event.type == loc.KEYDOWN: if alive: if event.key in (loc.K_m, loc.K_ESCAPE): alive = False draw_menu(1) pygame.display.set_caption( '5n4k3 - quit with %i apple%s' % (counter, "s" if counter != 1 else "")) elif event.key in DIRS and not paused: dir_ = DIRS[event.key] elif event.key == loc.K_p: paused = not paused draw_menu(1) pygame.display.set_caption('5n4k3 - %s' % ("paused" if paused else "by jug")) elif event.key == loc.K_c: mods = pygame.key.get_mods() if mods & loc.KMOD_ALT: bite_yourself = not bite_yourself else: if event.key == loc.K_r: use_circles = not use_circles elif event.key == loc.K_s: show_fps = not show_fps elif event.key == loc.K_b: hard_border = not hard_border elif event.key == loc.K_ESCAPE: return elif event.key in (loc.K_n, loc.K_RETURN): # clear old bricks for brick in bricks: drawbrick(brick, "black") if apple: drawbrick(apple, "black") bricks = [(ROWS/2, COLS/2)] dir_ = (1, 0) apple = None alive = True counter = 0 func = (use_circles and pygame.draw.ellipse or pygame.draw.rect) drawbrick = lambda b, c:drects.append(func(screen, COLORS[c], (b[0]*10, b[1]*10, 10, 10))) draw_menu(1) pygame.display.set_caption('5n4k3 - by jug') draw_menu() if alive and not paused: brickx, bricky = bricks[0] stepx, stepy = dir_ newx, newy = brickx + stepx, bricky + stepy newbrick = (newx+COLS) % COLS, (newy + ROWS) % ROWS if hard_border and not (0 <= newx < COLS and 0 <= newy < ROWS): newbrick = bricks[0] alive = False if (newbrick in bricks and bite_yourself) or not alive: alive = False drawbrick(newbrick, "red") draw_menu(1) pygame.display.update(drects) pygame.display.set_caption('5n4k3 - died with %i apple%s' % (counter, "s" if counter != 1 else "")) continue drawbrick(newbrick, "mangenta") bricks.insert(0, newbrick) if len(bricks)>1: drawbrick(bricks[1], "orange") if newbrick != apple: drawbrick(bricks.pop(), "black") else: counter += 1 if newbrick == apple or not apple: apple = random.randint(1, COLS-1), random.randint(1, ROWS-1) while apple in bricks: apple = random.randint(1, COLS-1), random.randint(1, ROWS-1) drawbrick(apple, "green") pygame.display.update(drects) drects = [] if __name__ == '__main__': main()