本文主要是写的一个贪吃蛇小游戏
目前还没有计分效果
from abc import ABCMeta,abstractmethod
from random import randint
import pygame
GREEN_COLOR =(0,0,255)
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
# 顺时针顺序设置
class Gameobject(object,metaclass=ABCMeta):
def __init__(self,x=0,y=0,color =(0, 0, 0) ):
self._x = x
self._y = y
self._color = color
@property
def x(self):
return self._x
@property
def y(self):
return self._y
@abstractmethod
def draw(self,screen):
pass
class Wall(Gameobject):
def __init__(self,x,y,hight,width,color =(0,0,0)): # pos 元组 一个点
super().__init__(x, y, color)
self._hight = hight
self._width = width
# 默认颜色为黑色
# 初始化
@property
def width(self):
return self._width
@property
def hight(self):
return self._hight
def draw(self,screen): # 1 画围墙 4 是像素
pygame.draw.rect(screen,self._color,
(self._x,self._y,self._width,self._hight),4)
class Food(Gameobject):
def __init__(self,x,y,size,color=(255,189,0)):
super().__init__(x,y,color)
self._size =size
self._hidden = False
def draw(self,screen):
if not self._hidden: # 闪烁
pygame.draw.circle(screen,self._color,
(self._x+self._size//2,self._y + self._size//2 ),self._size//2,0)
# x y是起点位置 size是半径
self._hidden = not self._hidden # 闪烁
class SnakeNode(Gameobject):
def __init__(self,x,y,size,color=GREEN_COLOR):
super().__init__(x,y,color)
self._size = size
@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, (0,0,0), (self._x, self._y, self._size, self._size), 1)
class Snake(Gameobject):
## 如果能使用强关联关系,就不要考虑继承关系
def __init__(self):
super().__init__()
self._dir = LEFT # 蛇的方向
self._nodes = []
self._alive = True
for index in range(5):
node = SnakeNode(290 + index * 20 ,290,20) # 蛇的第一个节点 方向
self._nodes.append(node) # 容器
@property
def dir(self):
return self._dir
@property
def alive(self):
return self._alive
@property
def head(self):
return self._nodes[0]
def change_dir(self,new_dir): # 蛇跑的方向转变
if (self._dir + new_dir) % 2 != 0:
self._dir = new_dir
def move(self):
if self._alive:
snake_dir = self._dir
# 蛇的移动
x,y,size = self.head.x,self.head.y,self.head.size
if snake_dir == UP:
y -= size # 往上跑
elif snake_dir == RIGHT:
x += size # 往右跑
elif snake_dir == DOWN:
y += size
else :
x -= size
new_head = SnakeNode(x,y,size)
self._nodes.insert(0,new_head)
self._nodes.pop() # 删除最后一节
def collide(self,wall): # 判断撞墙
"""
:param wall: 围墙
:return: 撞到围墙返回真 否则返回假
"""
head = self.head
if head.x < wall.x or head.x + head.size > wall.x + wall.width or head.y < wall.y\
or head.y + head.size > wall.y + wall.hight:
self._alive =False
def eat_food(self,food): ## 吃食物
if self.head.x == food.x and self.head.y == food.y:
tail = self._nodes[-1]
self._nodes.append(tail)
return True
return False
# 增加一个记分功能
def eat_me(self): # 咬到自己
pass
def draw(self,screen):
for node in self._nodes:
node.draw(screen)
def main():
def refresh(): ## 函数里面在定义函数 (嵌套)
"""刷新游戏窗口"""
screen.fill((242, 242, 242))
wall.draw(screen) # 3传个消息 在屏幕是画
food.draw(screen)
snake.draw(screen)
pygame.display.flip()
def handle_key_event(key_event):
"""处理按键事件"""
key = key_event.key
if key == pygame.K_F2:
reset_game()
else:
if snake.alive:
new_dir =snake.dir
if key == pygame.K_w:
new_dir = UP
elif key == pygame.K_d:
new_dir = RIGHT
elif key == pygame.K_s:
new_dir = DOWN
elif key == pygame.K_a:
new_dir = LEFT
if new_dir != snake.dir:
snake.change_dir(new_dir)
def create_food(): ##随机生成一个食物点
row = randint(0,29)
col = randint(0,29)
return Food(10 + 20 * col ,10 + 20 * row ,20)
def reset_game():
nonlocal food,snake ## 作用域 有这个才能F2 重新刷新
food = create_food()
snake = Snake()
wall = Wall(10,10,600,600) # 2创建围墙对象
food =create_food()
snake = Snake()
pygame.init()
screen = pygame.display.set_mode((620, 620)) # 窗口大小 620个像素(620个点)
pygame.display.set_caption('贪吃蛇')
screen.fill((242,242,242)) # 必须两个括号 里面 放元组 或列表的意思
pygame.display.flip()
clock = pygame.time.Clock()
running = 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 snake.alive:
refresh() # 4刷新界面
clock.tick(6) # 20帧/1s
if snake.alive:
snake.move()
snake.collide(wall)
if snake.eat_food(food):
food = create_food()
pygame.quit()
if __name__ == '__main__':
main()