小组任务,贪吃蛇游戏代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sys import exit#调用exit函数,用于终止python程序
from random import choice#调用choice函数,返回一个列表,元组或字符串的随机项
import pygame#调用pygame库
from pygame.locals import QUIT, KEYDOWN#调用quit(用于退出python),keydown函数(触发按下某键时的功能)
   
TITLE = '贪吃蛇--Transfer by 逗比小青年'
 
WIDTH = 660#宽度
HEIGHT = 500#长度
SNAKE_SIZE = 20#每一块蛇的大小
BOARD_COLOR = (0, 0, 100)#底板颜色
  
  
class Vector():
     def __init__(self, x, y):
         self._x = x
         self._y = y
 
     @property
     def x(self):
         return self._x
 
     @property
     def y(self):
         return self._y
 
     @x.setter
     def x(self, value):
         self._x = value
 
     @y.setter
     def y(self, value):
         self._y = value
 
     def __len__(self):#返回集合长度
         return 2
 
     def __getitem__(self, index):#getitem用于输出序列属性中的某个元素
         if index == 0:
             return self.x
         if index == 1:
             return self.y
         raise IndexError#raise 关键字用于引发一个异常,即程序出现错误后,程序内部会显示"IndexError"
 
     def copy(self):#复制对象子列
         type_self = type(self)
         return type_self(self.x, self.y)
 
     def move(self, other):#运动函数
         if isinstance(other, Vector):#isinstance() 函数用来判断一个对象是否是一个已知的类型
             self.x += other.x
             self.y += other.y
         else:
             self.x += other
             self.y += other
         return self
 
     def __eq__(self, other):
         if isinstance(other, Vector):
             return self.x == other.x and self.y == other.y
         return NotImplemented
 
     def __ne__(self, other):
         if isinstance(other, Vector):
             return self.x != other.x or self.y != other.y
         return NotImplemented
 
     def __repr__(self):#repr() 函数将对象转化为供解释器读取的形式
         type_self = type(self)
         name = type_self.__name__
         return '{}({!r}, {!r})'.format(name, self.x, self.y)
 
 
class Snake:#
    def __init__(self):
         self.map = {(x, y): 0
                     for x in range(1,
                                    int(WIDTH / SNAKE_SIZE) - 2)
                     for y in range(1,
                                    int(HEIGHT / SNAKE_SIZE) - 2)}
         self.body = [
             Vector(5 * SNAKE_SIZE, 5 * SNAKE_SIZE),
             Vector(6 * SNAKE_SIZE, 5 * SNAKE_SIZE)
         ]
         self.head = self.body[-1].copy()
         self.color = (0, 0, 0)
         self.direction = {
             'right': Vector(SNAKE_SIZE, 0),
             'left': Vector(-SNAKE_SIZE, 0),
             'up': Vector(0, -SNAKE_SIZE),
             'down': Vector(0, SNAKE_SIZE)
         }
         self.move_direction = 'right'
         self.speed = 4
         self.score = 0
         self.food = Vector(0, 0)
         self.food_color = (255, 0, 0)
         self.generate_food()
         self.game_started = False
 
    def generate_food(self):#食物生成
         empty_pos = [
             pos for pos in self.map.keys()
             if Vector(pos[0] * SNAKE_SIZE, pos[1] *
                       SNAKE_SIZE) not in self.body
         ]
         result = choice(empty_pos)
         self.food.x = result[0] * 20
         self.food.y = result[1] * 20
 
    def move(self):#移动中的进食过程与死亡判断
         self.head = self.body[-1].copy()
         self.head.move(self.direction[self.move_direction])
         if not self._islive(self.head):
             return False
 
         self.body.append(self.head)
 
         if self.head == self.food:
             self.score += 1
             if self.score % 5 == 0:
                 self.speed += 2
             self.generate_food()
         else:
             self.body.pop(0)
         return True
 
    def _islive(self, head):#死亡定义
         return 0 < head.x < WIDTH - SNAKE_SIZE and 0 < head.y < HEIGHT - SNAKE_SIZE and head not in self.body
 
 
KEY_DIRECTION_DICT = {#操控键位设置
     119: 'up',  # W
     115: 'down',  # S
     97: 'left',  # A
     100: 'right',  # D
     273: 'up',  # UP
     274: 'down',  # DOWN
     276: 'left',  # LEFT
     275: 'right',  # RIGHT
 }
 
 
def press(events, snake):#按压反馈
     for event in events:
         if event.type == QUIT:
             exit()
         if event.type == KEYDOWN:
             if event.key == 13:
                 snake.game_started = True
             if snake.game_started and event.key in KEY_DIRECTION_DICT:
                 return direction_check(snake.move_direction,
                                        KEY_DIRECTION_DICT[event.key])
 
 
def draw_score(screen, score, position):#实时分数显示
     tips_font = pygame.font.SysFont('arial', 20)
     screen.blit(
         tips_font.render('Score: {}'.format(score), True, (0, 0, 205),
                          (255, 255, 255)), position)
 
 
def game_continue(screen, snake):
     init_board(screen)
     draw_score(screen, snake.score, (500, 0))
     for seg in snake.body:
         pygame.draw.rect(screen, snake.color, [seg[0], seg[1], 20, 20], 0)
     pygame.draw.rect(screen, snake.food_color,
                      [snake.food[0], snake.food[1], 20, 20], 0)
 
 
def game_over(screen, fonts, score):
     screen.blit(fonts['game_over'], (250, 100))
     draw_score(screen, score, (290, 200))
     screen.blit(fonts['start'], (220, 310))
     snake = Snake()
     return snake
 
 
def direction_check(move_direction, change_direction):#键位感知
     directions = [['up', 'down'], ['left', 'right']]
     if move_direction in directions[0] and change_direction in directions[1]:
         return change_direction
     elif move_direction in directions[1] and change_direction in directions[0]:
         return change_direction
 
     return move_direction
 
 
def init(fonts):#游戏界面文字布置
     fps_clock = pygame.time.Clock()
     pygame.display.set_caption(TITLE)
     screen = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
     screen.fill((255, 255, 255))
     screen.blit(fonts['welcome'], (177, 100))
     screen.blit(fonts['start'], (195, 310))
     return fps_clock, screen
 
 
def init_board(screen):#边框定制
     board_width = int(WIDTH / SNAKE_SIZE)
     board_height = int(HEIGHT / SNAKE_SIZE)
     color = BOARD_COLOR
     width = 0
     for i in range(board_width):
         pos = i * SNAKE_SIZE, 0, SNAKE_SIZE, SNAKE_SIZE
         pygame.draw.rect(screen, color, pos, width)
         pos = i * SNAKE_SIZE, (board_height -
                                1) * SNAKE_SIZE, SNAKE_SIZE, SNAKE_SIZE
         pygame.draw.rect(screen, color, pos, width)
 
     # 上下边框占用了 Y: 0 26*20
     for i in range(board_height - 1):
         pos = 0, SNAKE_SIZE + i * SNAKE_SIZE, SNAKE_SIZE, SNAKE_SIZE
         pygame.draw.rect(screen, color, pos, width)
         pos = (
             board_width - 1
         ) * SNAKE_SIZE, SNAKE_SIZE + i * SNAKE_SIZE, SNAKE_SIZE, SNAKE_SIZE
         pygame.draw.rect(screen, color, pos, width)
 
 
def font_setting():#游戏初始,游戏结束,游戏胜利界面文字布置
     title_font = pygame.font.SysFont('arial', 32)
     welcome_words = title_font.render('Welcome to revision Snake', True, (0, 0, 0),
                                       (255, 255, 255))
     tips_font = pygame.font.SysFont('arial', 24)
     start_game_words = tips_font.render('Press Enter to Start Game', True,
                                         (0, 0, 0), (255, 255, 255))
     gameover_words = title_font.render('GAME OVER', True, (205, 92, 92),
                                        (255, 255, 255))
     win_words = title_font.render('The snake is long enough and you win!',
                                   True, (0, 0, 205), (255, 255, 255))
     return {
         'welcome': welcome_words,
         'start': start_game_words,
         'game_over': gameover_words,
         'win': win_words
     }
 
 
def main():
     pygame.init()
     fonts = font_setting()
     fps_clock, screen = init(fonts)
 
     snake = Snake()
     direction = snake.move_direction
     while True:
         events = pygame.event.get()
         new_direction = press(events, snake)
         if snake.game_started:
             if new_direction:
                 snake.move_direction = new_direction
             screen.fill((255, 255, 255))
             if not snake.move():
                 snake = game_over(screen, fonts, snake.score)
                 direction = snake.move_direction
             else:
                 game_continue(screen, snake)
         pygame.display.update()
         fps_clock.tick(snake.speed)
     
 
 
if __name__ == '__main__':
     main()
贪吃蛇游戏主体

 

posted @ 2020-06-16 11:17  叶落知秋max  阅读(127)  评论(0编辑  收藏  举报