python实现简单贪吃蛇

该代码实现了一个基于PythonPygame库的贪吃蛇游戏。游戏中包含了食物和蛇两个类,分别处理食物生成和蛇的移动、增长。游戏界面有边框,蛇会因碰到自身或边界而失败。玩家可以通过键盘控制蛇的移动,吃到食物后得分并增长。
摘要由CSDN通过智能技术生成
import math
import pygame
import time
import numpy as np
# 此模块包含游戏所需的常量
from pygame.locals import *

# 设置棋盘的长宽
BOARDWIDTH = 90
BOARDHEIGHT = 50
# 分数
score = 0

# 豆子
class Food(object):

    def __init__(self):
        self.item = (4, 5)
    # 画出食物
    def _draw(self, screen, i, j):
        color = 255, 255, 0
        radius = 10
        width = 0
        position = 10 + 20 * i, 10 + 20 * j
        pygame.draw.circle(screen, color, position, radius, width)
    # 随机产生食物
    def update(self, screen, enlarge, snack):
        if enlarge:
            self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2)
            while self.item in snack.item:
                self.item = np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2)
        self._draw(screen, self.item[0], self.item[1])
# 贪吃蛇
class Snack(object):
    def __init__(self):
        # 开始的蛇形
        self.item = [(11, 25), (10, 25), (9, 25), (8, 25), (7, 25), (6, 25), (5, 25), (4, 25), (3, 25), (2, 25), (1, 25)]
        self.x = 0.0001
        self.y = 0

    def move(self, enlarge):
        if not enlarge:
            self.item.pop()
        # 新蛇头的坐标为旧蛇头坐标加上移动方向的位移
        head = (self.item[0][0] + self.x, self.item[0][1] + self.y)
        # 将新的蛇头坐标插入在 list 最前面
        self.item.insert(0, head)

    def eat_food(self, food):
        global score
        # snack_x,snack_y 蛇头坐标
        # food_x, food_y 食物坐标
        snack_x, snack_y = self.item[0]
        food_x, food_y = food.item
        # 比较蛇头坐标与食物坐标
        if (math.fabs(snack_x - food_x) < 1) and (math.fabs(snack_y - food_y) < 1):
            score += 88888
            return 1
        else:
            return 0

    def toward(self, x, y):
        # 改变蛇头朝向
        if self.x * x >= 0 and self.y * y >= 0:
            self.x = x
            self.y = y

    def get_head(self):
        # 获取蛇头坐标
        return self.item[0]

    def draw(self, screen):
        # 贪吃蛇
        radius = 25
        width = 30
        color = 10, 255, 255
        position = 10 + 20 * self.item[0][0], 10 + 20 * self.item[0][1]
        pygame.draw.circle(screen, color, position, radius, width)
        # 蛇身为实心圆
        radius = 15
        width = 30
        color = 255, 255, 0
        for i, j in self.item[1:]:
            position = 10 + 20 * i, 10 + 20 * j
            pygame.draw.circle(screen, color, position, radius, width)

# 初始界面
def init_board(screen):
    board_width = BOARDWIDTH
    board_height = BOARDHEIGHT
    color = 10, 255, 255
    width = 0
    # width:x, height:y
    # 左右边框占用了 X: 0 35*20
    for i in range(board_width):
        pos = i * 20, 0, 20, 20
        pygame.draw.rect(screen, color, pos, width)
        pos = i * 20, (board_height - 1) * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)
    # 上下边框占用了 Y: 0 *20
    for i in range(board_height - 1):
        pos = 0, 20 + i * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)
        pos = (board_width - 1) * 20, 20 + i * 20, 20, 20
        pygame.draw.rect(screen, color, pos, width)


# 游戏失败
def game_over(snack):
    broad_x, broad_y = snack.get_head()
    flag = 0
    old = len(snack.item)
    new = len(set(snack.item))
    # 游戏失败
    # 咬到自身
    if new < old:
        flag = 1
    # 撞到边框
    if broad_x >= BOARDWIDTH or broad_x <= 0 or math.fabs(broad_x - BOARDWIDTH) < 5:
        flag = 1
    if broad_y >= BOARDHEIGHT or broad_y <= 0 or math.fabs(broad_y - BOARDHEIGHT) < 5:
        flag = 1
    if flag:
        return True
    else:
        return False


# 打印字符
def print_text(screen, font, x, y, text, color=(155, 0, 0)):
    # 在屏幕上打印字符
    # text是需要打印的文本,color为字体颜色
    # (x,y)是文本在屏幕上的位置
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x, y))


# 按键
def press(keys, snack):
    global score
    # K_w 为 pygame.locals 中的常量
    # keys[K_w] 返回 True or False
    # 上移
    if keys[K_w] or keys[K_UP]:
        snack.toward(0, -0.1)
    # 下移
    elif keys[K_s] or keys[K_DOWN]:
        snack.toward(0, 0.1)
    # 左移
    elif keys[K_a] or keys[K_LEFT]:
        snack.toward(-0.1, 0)
    # 右移
    elif keys[K_d] or keys[K_RIGHT]:
        snack.toward(0.1, 0)
    # 重置游戏
    elif keys[K_SPACE]:
        score = 0
        main()
    # 退出游戏
    elif keys[K_ESCAPE]:
        exit()


# 游戏初始化
def game_init():
    # pygame 初始化
    pygame.init()
    # 设置游戏界面大小
    screen = pygame.display.set_mode((BOARDWIDTH * 20, BOARDHEIGHT * 20))
    return screen


# 开始游戏
def game(screen):
    snack = Snack()
    food = Food()
    font = pygame.font.SysFont('SimHei', 70)
    is_fail = 0
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()

        # 填充屏幕
        screen.fill((0, 0, 200))
        init_board(screen=screen)
        # 获得用户按键命令
        keys = pygame.key.get_pressed()
        press(keys, snack)
        # 游戏失败打印提示
        if is_fail:
            font = pygame.font.Font(None, 50)
            font2 = pygame.font.Font(None, 100)
            font3 = pygame.font.Font(None, 30)
            print_text(screen, font, 700, 570, text)
            print_text(screen, font2, 700, 400, "GAME OVER!")
            print_text(screen, font3, 700, 500, "Press 'SPACE' to play again ")
            print_text(screen, font3, 700, 530, "Press 'ESC' to exit the game")
        # 游戏主进程
        if not is_fail:
            enlarge = snack.eat_food(food)
            text = u"score: {}".format(score)
            print_text(screen, font, 0, 0, text)
            food.update(screen, enlarge, snack)
            snack.move(enlarge)
            is_fail = game_over(snack=snack)
            snack.draw(screen)
        # 游戏刷新
        pygame.display.update()
        time.sleep(0.002)


# 主程序
def main():
    screen = game_init()
    game(screen)


if __name__ == '__main__':
    main()


在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值