经典方块游戏-贪吃蛇

 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')
snake.py

 

 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     
game_snake.py

 

posted on 2018-01-05 17:58  Jinglelove  阅读(236)  评论(0编辑  收藏  举报