Pygame实现简易贪吃蛇

部署运行你感兴趣的模型镜像

此文章旨在记录自己学习内容,内容十分基础,还有许多不完善的多体谅 :)


1.Pygame简介

Pygame是一个基于Python的库,专门用于开发视频游戏,尤其是2D游戏。它提供了图形渲染、声音播放、事件处理等功能。

2.源码

import pygame
import sys
import random

# 初始化 Pygame
pygame.init()

# 设置游戏窗口大小
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("贪吃蛇")

# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)

# 初始化设置
size = 20  # 方块大小
score = 0  # 得分
direction = 'RIGHT'  # 初始化方向
change_to = direction
pause = False  # 暂停信号
snake_pos = [[100, 60], [80, 60], [60, 60]]  # 蛇的位置设定
font_path = "C:/Windows/Fonts/msyh.ttc"  # 中文路径
font = pygame.font.Font(font_path, 45)  # 字体默认,字号45
clock = pygame.time.Clock()  # 设置游戏时钟
food_pos = [random.randrange(size, width-size, size), random.randrange(size, height-size, size)]  # 食物位置设定


# 结束字体创建
def game_over():
    text = "最终得分: " + str(score)  # 文本设置
    text_sur = font.render(text, True, (255, 255, 255))  # 文本渲染
    text_rect = text_sur.get_rect()  # 获取文本矩形(位置)
    text_rect.center = (width // 2, height // 2)  # 文本居中展示
    screen.fill((0, 0, 0))
    screen.blit(text_sur, text_rect)  # 输出字符
    pygame.display.flip()


# 实时显示分数
def draw_score(screen, font, score):
    score_text = "Score: " + str(score)
    score_surface = font.render(score_text, True, WHITE)
    screen.blit(score_surface, (10, 10))


# 游戏主循环
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                change_to = 'RIGHT'
            if event.key == pygame.K_LEFT:
                change_to = 'LEFT'
            if event.key == pygame.K_UP:
                change_to = 'UP'
            if event.key == pygame.K_DOWN:
                change_to = 'DOWN'

    # 更新贪吃蛇的位置
    if direction == 'RIGHT':
        snake_pos.insert(0, [snake_pos[0][0] + size, snake_pos[0][1]])
    if direction == 'LEFT':
        snake_pos.insert(0, [snake_pos[0][0] - size, snake_pos[0][1]])
    if direction == 'UP':
        snake_pos.insert(0, [snake_pos[0][0], snake_pos[0][1] - size])
    if direction == 'DOWN':
        snake_pos.insert(0, [snake_pos[0][0], snake_pos[0][1] + size])

    # 验证方向改变是否合法
    if change_to == 'RIGHT' and not direction == 'LEFT':
        direction = 'RIGHT'
    if change_to == 'LEFT' and not direction == 'RIGHT':
        direction = 'LEFT'
    if change_to == 'UP' and not direction == 'DOWN':
        direction = 'UP'
    if change_to == 'DOWN' and not direction == 'UP':
        direction = 'DOWN'

    # 检查是否吃到食物
    if snake_pos[0] == food_pos:
        food_pos = [random.randrange(size, width-size, size), random.randrange(size, height-size, size)]
        if food_pos not in snake_pos:  # 防止食物生成在蛇的身体中
            pass
        else:
            food_pos = [random.randrange(size, width - size, size), random.randrange(size, height - size, size)]
        pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], size, size))
        score += 1
    else:
        snake_pos.pop()

    # 检查是否触边
    snake_body = snake_pos[1:]  # 将蛇的身体部分(除了头部)转换为集合
    if snake_pos[0] in snake_body:  # 如果蛇头在蛇的身体中
        pause = True
    if snake_pos[0][0] < 0 or snake_pos[0][0] >= width:
        pause = True
    if snake_pos[0][1] < 0 or snake_pos[0][1] >= height:
        pause = True
    if pause:
        game_over()
        continue

    # 绘制游戏界面
    screen.fill(BLACK)
    draw_score(screen, font, score)
    for pos in snake_pos:
        pygame.draw.rect(screen, WHITE, pygame.Rect(pos[0], pos[1], size, size))
    pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], size, size))

    # 更新屏幕显示
    pygame.display.flip()

    # 控制游戏速度
    clock.tick(15)

3.代码解析

模块导入

import pygame
import sys
import random

sys:用于访问系统相关的参数和函数

random:用于生成随机数

pygame:用于游戏开发

设置游戏窗口


width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("贪吃蛇")

宽度和高度可以自行更改设定,我这里将游戏窗口设定为800×600像素,并设置窗口标题为“贪吃蛇”。

颜色定义

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)

定义之后需要使用的颜色,如果需要其他颜色,可以查询RGB颜色表添加,更改等等。

初始化游戏设置

size = 20  # 方块大小
score = 0  # 得分
direction = 'RIGHT'  # 初始化方向
change_to = direction
pause = False  # 暂停信号
snake_pos = [[100, 60], [80, 60], [60, 60]]  # 蛇的位置设定
font_path = "C:/Windows/Fonts/msyh.ttc"  # 中文路径
font = pygame.font.Font(font_path, 45)  # 字体默认,字号45
clock = pygame.time.Clock()  # 设置游戏时钟
food_pos = [random.randrange(size, width-size, size), random.randrange(size, height-size, size)]  # 食物位置设定

初始化游戏以及后续需要用到的设置,包括方块大小、得分、方向、蛇的初始位置·、字体路径、游戏时钟以及食物的初始位置等等。其中食物的初始位置我们利用random库里的randrange函数,使其随机生成食物。其中步长设置为方块大小size,其目的在于其坐标能够与蛇头重叠,进而后续判定为食用成功。否则将会出现两者相碰食用失败的情况。而游戏时钟的作用则是后续用来控制游戏的帧率。

函数介绍

def game_over():
    text = "最终得分: " + str(score)  # 文本设置
    text_sur = font.render(text, True, (255, 255, 255))  # 文本渲染
    text_rect = text_sur.get_rect()  # 获取文本矩形(位置)
    text_rect.center = (width // 2, height // 2)  # 文本居中展示
    screen.fill(BLACK)
    screen.blit(text_sur, text_rect)  # 输出字符
    pygame.display.flip()

def draw_score(screen, font, score):
    score_text = "Score: " + str(score)
    score_surface = font.render(score_text, True, WHITE)
    screen.blit(score_surface, (10, 10))

game_over()函数用于游戏结束时,暂停游戏并且展示最终的得分。其中文本设置时,要注意初始化游戏设置里的字体路径,如果路径不对,那么可能会无法正常的输出中文的情况。

draw_score()用于在游戏界面左上角实时显示当前得分。

游戏主循环

事件处理

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                change_to = 'RIGHT'
            if event.key == pygame.K_LEFT:
                change_to = 'LEFT'
            if event.key == pygame.K_UP:
                change_to = 'UP'
            if event.key == pygame.K_DOWN:
                change_to = 'DOWN'

该代码用于处理游戏的事件。接收键盘的输入以及窗口关闭。其中sys.exit()当检测到用户关闭窗口(pygame.QUIT事件)时,这行代码会被调用。它告诉Python解释器立即停止当前程序的执行。

位置更改

    # 更新贪吃蛇的位置
    if direction == 'RIGHT':
        snake_pos.insert(0, [snake_pos[0][0] + size, snake_pos[0][1]])
    if direction == 'LEFT':
        snake_pos.insert(0, [snake_pos[0][0] - size, snake_pos[0][1]])
    if direction == 'UP':
        snake_pos.insert(0, [snake_pos[0][0], snake_pos[0][1] - size])
    if direction == 'DOWN':
        snake_pos.insert(0, [snake_pos[0][0], snake_pos[0][1] + size])

    # 验证方向改变是否合法
    if change_to == 'RIGHT' and not direction == 'LEFT':
        direction = 'RIGHT'
    if change_to == 'LEFT' and not direction == 'RIGHT':
        direction = 'LEFT'
    if change_to == 'UP' and not direction == 'DOWN':
        direction = 'UP'
    if change_to == 'DOWN' and not direction == 'UP':
        direction = 'DOWN'

依据当前方向来更新snake_pos里的坐标,例如向左就将其中每一个数组的x轴坐标减去一个单位长度(size)。在合法改变中,当蛇保持向右移动时,按左方向键不会发生改变,其余的情况以此类推。

检测进食

    if snake_pos[0] == food_pos:
        food_pos = [random.randrange(size, width-size, size), random.randrange(size, height-size, size)]
        if food_pos not in snake_pos:  # 防止食物生成在蛇的身体中
            pass
        else:
            food_pos = [random.randrange(size, width - size, size), random.randrange(size, height - size, size)]
        pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], size, size))
        score += 1
    else:
        snake_pos.pop()

检查蛇头是否与食物位置重合,如果是,则更新食物位置并增加得分。

检测触碰

    snake_body = snake_pos[1:]  # 将蛇的身体部分(除了头部)转换为集合
    if snake_pos[0] in snake_body:  # 如果蛇头在蛇的身体中
        pause = True
    if snake_pos[0][0] < 0 or snake_pos[0][0] >= width:
        pause = True
    if snake_pos[0][1] < 0 or snake_pos[0][1] >= height:
        pause = True
    if pause:
        game_over()
        continue

检查蛇头是否触碰到墙壁或自己的身体,如果是,则游戏结束。

游戏界面绘制

    # 绘制游戏界面
    screen.fill(BLACK)
    draw_score(screen, font, score)
    for pos in snake_pos:
        pygame.draw.rect(screen, WHITE, pygame.Rect(pos[0], pos[1], size, size))
    pygame.draw.rect(screen, RED, pygame.Rect(food_pos[0], food_pos[1], size, size))

    # 更新屏幕显示
    pygame.display.flip()

    # 控制游戏速度
    clock.tick(15)

绘制游戏界面,包括背景得分和食物。

结果展示

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值