Python编写贪吃蛇小游戏

xiaoxiao2021-02-28  38

2018.3.15 晴 天气越来越热 要穿T恤了

今天一天就编了一个小游戏:贪吃蛇。 

面向对象这个逻辑是必须要学会的,has a , is a, 这些关系要弄明白,封装,继承,多态,是面向对象的三个属性。今天的贪吃蛇代码基本上是完成了,验证是否碰壁,是否追尾,添加字体,添加弹窗,开始新的游戏,这几个功能基本都是按照自己的逻辑写的,用了个easygui类来弹窗,我觉得挺有意思的。 还有一个排行榜没做,我得考虑一下是用存档的方式还是在游戏进行的时候用一个列表存数据(重开游戏就清空了)

 

 

代码如下:

 

import pygame from abc import ABCMeta, abstractclassmethod from random import randint from pygame.locals import * import easygui Black_color = (0, 0, 0) Food_color = (236, 189, 187) Green_color = (0, 255, 0) # 顺时针或者逆时针 UP = 0 RIGHT = 1 DOWN = 2 LEFT = 3 class GameObject(object, metaclass=ABCMeta): def __init__(self, x, y, color): self._x = x self._y = y self._color = color @property def x(self): return self._x @property def y(self): return self._y @abstractclassmethod def draw(self, screen): pass class Snake(GameObject): def __init__(self): self._dir = LEFT self._nodes = [] self.has_eat_food = False for index in range(5): node = SnakeNode(290 + index * 20, 250, 20) self._nodes.append(node) @property def dir(self): return self._dir def change_dir(self, new_dir): if (self._dir + new_dir) % 2 != 0: self._dir = new_dir def draw(self, screen): for node in self._nodes: node.draw(screen) def move(self): head = self._nodes[0] sdir = self._dir x, y, size = head.x, head.y, head.size if sdir == UP: y -= size elif sdir == RIGHT: x += size elif sdir == DOWN: y += size else: x -= size new_head = SnakeNode(x, y, size) self._nodes.insert(0, new_head) if self.has_eat_food: self.has_eat_food = False else: self._nodes.pop() def is_over(self): '''撞墙返回真,否则返回假''' head = self._nodes[0] x, y, size = head.x, head.y, head.size if x > 600 or x < 10 or y > 600 or y < 10: return True return False def eat_food(self, food): head = self._nodes[0] if food.x == head.x and food.y == head.y: self.has_eat_food = True return True return False def eat_me(self): for a in range(4, len(self._nodes)): if self._nodes[0].x == self._nodes[a].x and self._nodes[0].y == self._nodes[a].y: return True return False class SnakeNode(GameObject): def __init__(self, x, y, size, color=Green_color): super().__init__(x, y, color) self._size = size self._color = color @property def size(self): return self._size def draw(self, screen): pygame.draw.rect(screen, self._color, (self._x, self._y, self._size, self._size), 0) pygame.draw.rect(screen, Black_color, (self._x, self._y, self._size, self._size), 1) class Wall(GameObject): def __init__(self, x, y, width, height, color=Black_color): super().__init__(x, y, color) self._width = width self._height = height @property def width(self): return self._width @property def height(self): return self._height def draw(self, screen): pygame.draw.rect(screen, self._color, (self._x, self._y, self._width, self._height), 4) class Food(GameObject): def __init__(self, x, y, size, color=Food_color): super().__init__(x, y, color) self._size = size self._hide = False def draw(self, screen): if not self._hide: pygame.draw.circle(screen, self._color, (self._x + self._size // 2, self._y + self._size // 2), self._size // 2, 0) # 处理圆和半径的中心点 否则无法相遇 self._hide = not self._hide def main(): def refresh(): '''刷新游戏窗口''' screen.fill((242, 242, 242)) snake.draw(screen) wall.draw(screen) food.draw(screen) pygame.display.flip() def handle_key_event(key_event): key = key_event.key if key == ord('w'): new_dir = UP elif key == ord('d'): new_dir = RIGHT elif key == ord('s'): new_dir = DOWN elif key == ord('a'): new_dir = LEFT else: new_dir = key if new_dir != snake.dir: snake.change_dir(new_dir) def create_food(): row = randint(1, 28) col = randint(1, 28) return Food(10 + 20 * row, 10 + 20 * col, 20) def count_txt(snake): score = len(snake._nodes) - 5 my_font = pygame.font.SysFont('楷体', 60) game_over = my_font.render('GAME OVER', False, [0, 0, 0]) score = my_font.render('score:' + str(score), False, [255, 0, 0]) screen.blit(score, (400, 30)) screen.blit(game_over, (180, 260)) pygame.display.flip() wall = Wall(10, 10, 600, 600) food = create_food() snake = Snake() pygame.init() screen = pygame.display.set_mode((620, 620)) pygame.display.set_caption('贪吃蛇') background = screen.fill((242, 242, 242)) pygame.display.flip() clock = pygame.time.Clock() running = True over = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: handle_key_event(event) if over: refresh() clock.tick(20) if over: snake.move() if snake.eat_food(food): food = create_food() if snake.is_over() or snake.eat_me(): count_txt(snake) Yes_or_No = easygui.buttonbox("不好意思,游戏结束", choices=['我不服我还要玩', '我不玩了886']) if Yes_or_No == '我不服我还要玩': snake = Snake() pygame.event.clear() else: over = False pygame.quit() if __name__ == '__main__': main()  

 

 

代码量还是挺大的,逻辑比五子棋好理解一点,五子棋那个判断胜负确实有点绕,但是贪吃蛇基本把面向对象的东西都用到了,需要细嚼慢咽地去理解使用。

 

 

转载请注明原文地址: https://www.6miu.com/read-2624517.html

最新回复(0)