经典方块游戏-贪吃蛇
1、贪吃蛇类定义
1 # -*- coding: utf-8 -*- 2 3 from base import Base 4 from point import Point 5 from utils import * 6 import random 7 8 class Snake(Base): 9 __FIRST_LEN = 3 10 __FIRST_DIR = Direct.Right 11 __SCORE_PER_FOOD = 100 12 __FIRST_SPEED = 700 13 __MAX_SPEED = 300 14 15 def __init__(self): 16 Base.__init__(self) 17 startX = int(( Base.width() - self.__FIRST_LEN ) / 2) 18 startY = int(Base.height() / 2) 19 # body [ tail ... head ] 20 self._body = [ Point(startX + i, startY) for i in range(self.__FIRST_LEN) ] 21 self._dir = self.__FIRST_DIR 22 self._food = self._add_food() 23 # 速度以前进一步所需时间代替,速度越大,时间越小 24 self._speed = self.__FIRST_SPEED 25 self._timer_forward = 0 26 27 def _add_food(self): 28 self._clear_area() 29 self._set_body() 30 31 randIdx = random.randint(1, Base.width() * Base.height() - len(self._body)) 32 33 for x in range(Base.width()): 34 for y in range(Base.height()): 35 if self._area[x][y] != Block.Empty: 36 continue 37 randIdx -= 1 38 if randIdx == 0: 39 return Point(x, y) 40 return None 41 42 def _set_body(self): 43 for p in self._body: 44 self._area[p.x][p.y] = Block.Fill 45 46 def _check_point_in_body(self, point): 47 return point in self._body 48 49 def _update_speed(self): 50 self._speed = int(self.__FIRST_SPEED - len(self._body) * (self.__FIRST_SPEED - self.__MAX_SPEED) / (Base.width()*Base.height()/2)) 51 if self._speed < self.__MAX_SPEED: 52 self._speed = self.__MAX_SPEED 53 54 def _update_score(self): 55 self._score += self.__SCORE_PER_FOOD 56 self._update_speed() 57 print('score %d'%(self._score)) 58 59 def _turn_direction(self, dir): 60 if dir == self._dir: 61 return 62 p1 = self._body[-1] 63 p2 = self._body[-2] 64 if dir == Direct.Left: 65 if p1.x == p2.x + 1 and p1.y == p2.y: 66 return 67 elif dir == Direct.Down: 68 if p1.x == p2.x and p1.y == p2.y + 1: 69 return 70 elif dir == Direct.Right: 71 if p1.x == p2.x - 1 and p1.y == p2.y: 72 return 73 elif dir == Direct.Up: 74 if p1.x == p2.x and p1.y == p2.y - 1: 75 return 76 self._dir = dir 77 78 def refresh_area(self): 79 self._clear_area() 80 self._set_body() 81 if self._food: 82 self._area[self._food.x][self._food.y] = Block.Fill 83 84 def _forward(self): 85 if self._status != Status.Running: 86 return 87 88 nextPoint = Base.forward_from(self._body[-1], self._dir) 89 #print('Snake forward, body {0} {1} {2}, dir {3}, nextPoint {4}'.format(self._body[0], self._body[1], self._body[2], self._dir, nextPoint)) 90 if Base.check_point_in_area(nextPoint) and not self._check_point_in_body(nextPoint): 91 if nextPoint == self._food: 92 self._update_score() 93 self._body.append(nextPoint) 94 self._food = self._add_food() 95 96 if not self._food: 97 self._status = Status.Passed 98 else: 99 self._body.append(nextPoint) 100 self._body.pop(0) 101 else: 102 print('Snake over') 103 self._status = Status.Over 104 105 def press_button(self, btn): 106 if btn == Button.Left: 107 self._turn_direction(Direct.Left) 108 elif btn == Button.Down: 109 self._turn_direction(Direct.Down) 110 elif btn == Button.Right: 111 self._turn_direction(Direct.Right) 112 elif btn == Button.Up: 113 self._turn_direction(Direct.Up) 114 elif btn == Button.Trans: 115 self._forward() 116 elif btn == Button.Reset: 117 self.__init__() 118 elif btn == Button.Pause_start: 119 if self._status == Status.Running: 120 self._status = Status.Pause 121 elif self._status == Status.Pause: 122 self._status = Status.Running 123 124 def pass_time(self, millisecond): 125 self._timer_forward += millisecond 126 if self._timer_forward > self._speed: 127 step = int(self._timer_forward / self._speed) 128 for i in range(step): 129 self._forward() 130 self._timer_forward %= self._speed 131 132 if __name__ == '__main__': 133 print('Snake(): {0}'.format(Snake())) 134 snake = Snake() 135 snake.refreshArea() 136 snake._forward() 137 snake.press_button(Button.Down) 138 snake.press_button(Button.Trans) 139 snake.press_button(Button.Reset) 140 print('done')
2、pygame游戏驱动
1 # -*- coding: utf-8 -*- 2 3 import pygame 4 from pygame.locals import * 5 from screen_params import * 6 from snake import Snake 7 from base import Base 8 from utils import * 9 10 pygame.init() 11 screen = pygame.display.set_mode(screen_size) 12 clock = pygame.time.Clock() 13 14 color_black = (0, 0, 0) 15 color_white = (255, 255, 255) 16 color_gray = (240, 240, 240) 17 18 snake = Snake() 19 20 while 1: 21 for event in pygame.event.get(): 22 if event.type==pygame.QUIT: 23 pygame.quit() 24 exit(0) 25 elif event.type == pygame.KEYDOWN: 26 if event.key == K_LEFT: 27 snake.press_button(Button.Left) 28 elif event.key == K_DOWN: 29 snake.press_button(Button.Up) 30 elif event.key == K_RIGHT: 31 snake.press_button(Button.Right) 32 elif event.key == K_UP: 33 snake.press_button(Button.Down) 34 elif event.key == K_SPACE: 35 snake.press_button(Button.Pause_start) 36 elif event.key == K_r: 37 snake.press_button(Button.Reset) 38 39 screen.fill(color_white) 40 41 time_passed = clock.tick(30) 42 snake.pass_time(time_passed) 43 44 # 绘制游戏区域边框 45 pygame.draw.rect(screen, color_black, Rect(area_point, area_size), 1) 46 # 绘制小方块 47 snake.refresh_area() 48 for x in range(Base.width()): 49 for y in range(Base.height()): 50 if snake.area(x, y) != Block.Empty: 51 pygame.draw.rect(screen, color_black, Rect(block_points[x][y], (block_side, block_side))) 52 else: 53 pygame.draw.rect(screen, color_gray, Rect(block_points[x][y], (block_side, block_side))) 54 55 pygame.display.flip() 56 57 fps = clock.get_fps() 58