Pygame经典游戏:贪吃蛇

------------★Pygame系列教程★------------

Pygame经典游戏:贪吃蛇

Pygame教程01:初识pygame游戏模块

Pygame教程02:图片的加载+缩放+旋转+显示操作

Pygame教程03:文本显示+字体加载+transform方法

Pygame教程04:draw方法绘制矩形、多边形、圆、椭圆、弧线、直线和线条等

Pygame教程05:帧动画原理+边界值检测,让小球来回上下运动

Pygame教程06:Event事件的类型+处理方法+监听鼠标事件

Pygame教程07:键盘常量+键盘事件的2种捕捉方式

Pygame教程08:使用键盘方向键,控制小球,上下左右移动。

Pygame教程09:font.render文本内容,如何自动换行显示

1.游戏玩法介绍:

a.如果玩家按下了回车键(K_RETURN)开始游戏,如果死了,按回车键之后,重新开始游戏。

b.如果玩家按下了空格键(K_SPACE),并且游戏没有结束,则切换游戏的暂停状态。如果游戏原本在运行,现在会暂停;如果原本暂停,现在会恢复运行。

c.处理方向键或W/A/S/D键: 接下来的几个elif块处理蛇的移动方向。这里使用了一个变量b来确保蛇在改变方向时不会立即反向移动(例如,按下向上键后立刻按下向下键)。

K_w或K_UP表示向上移动。

K_s或K_DOWN表示向下移动。

K_a或K_LEFT表示向左移动。

K_d或K_RIGHT表示向右移动。

python 复制代码
# -*- coding: utf-8 -*-
# @Author : 小红牛
# 微信公众号:WdPython
import random
import sys
import time
import pygame
from pygame.locals import *
from collections import deque

SCREEN_WIDTH = 600      # 屏幕宽度
SCREEN_HEIGHT = 480     # 屏幕高度
SIZE = 20               # 小方格大小
LINE_WIDTH = 1          # 网格线宽度

# 游戏区域的坐标范围
SCOPE_X = (0, SCREEN_WIDTH // SIZE - 1)
SCOPE_Y = (2, SCREEN_HEIGHT // SIZE - 1)

# 食物的分值及颜色
FOOD_STYLE_LIST = [(10, (255, 100, 100)), (20, (100, 255, 100)), (30, (100, 100, 255))]

LIGHT = (100, 100, 100)
DARK = (200, 200, 200)      # 蛇的颜色
BLACK = (0, 0, 0)           # 网格线颜色
RED = (200, 30, 30)         # 红色,GAME OVER 的字体颜色
BGCOLOR = (40, 40, 60)      # 背景色


def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
    imgText = font.render(text, True, fcolor)
    screen.blit(imgText, (x, y))


# 初始化蛇
def init_snake():
    snake = deque()
    snake.append((2, SCOPE_Y[0]))
    snake.append((1, SCOPE_Y[0]))
    snake.append((0, SCOPE_Y[0]))
    return snake


def create_food(snake):
    food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
    food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
    while (food_x, food_y) in snake:
        # 如果食物出现在蛇身上,则重来
        food_x = random.randint(SCOPE_X[0], SCOPE_X[1])
        food_y = random.randint(SCOPE_Y[0], SCOPE_Y[1])
    return food_x, food_y


def get_food_style():
    return FOOD_STYLE_LIST[random.randint(0, 2)]


def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('贪吃蛇')

    font1 = pygame.font.SysFont('SimHei', 24)  # 得分的字体
    font2 = pygame.font.Font(None, 72)  # GAME OVER 的字体
    fwidth, fheight = font2.size('GAME OVER')

    # 如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAME OVER
    # b 变量就是用于防止这种情况的发生
    b = True

    # 蛇
    snake = init_snake()
    # 食物
    food = create_food(snake)
    food_style = get_food_style()
    # 方向
    pos = (1, 0)

    game_over = True
    start = False       # 是否开始,当start = True,game_over = True 时,才显示 GAME OVER
    score = 0           # 得分
    orispeed = 0.5      # 原始速度
    speed = orispeed
    last_move_time = None
    pause = False       # 暂停

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == KEYDOWN:
                if event.key == K_RETURN:
                    if game_over:
                        start = True
                        game_over = False
                        b = True
                        snake = init_snake()
                        food = create_food(snake)
                        food_style = get_food_style()
                        pos = (1, 0)
                        # 得分
                        score = 0
                        last_move_time = time.time()
                elif event.key == K_SPACE:
                    if not game_over:
                        pause = not pause
                elif event.key in (K_w, K_UP):
                    # 这个判断是为了防止蛇向上移时按了向下键,导致直接 GAME OVER
                    if b and not pos[1]:
                        pos = (0, -1)
                        b = False
                elif event.key in (K_s, K_DOWN):
                    if b and not pos[1]:
                        pos = (0, 1)
                        b = False
                elif event.key in (K_a, K_LEFT):
                    if b and not pos[0]:
                        pos = (-1, 0)
                        b = False
                elif event.key in (K_d, K_RIGHT):
                    if b and not pos[0]:
                        pos = (1, 0)
                        b = False

        # 填充背景色
        screen.fill(BGCOLOR)
        # 画网格线 竖线
        for x in range(SIZE, SCREEN_WIDTH, SIZE):
            pygame.draw.line(screen, BLACK, (x, SCOPE_Y[0] * SIZE), (x, SCREEN_HEIGHT), LINE_WIDTH)
        # 画网格线 横线
        for y in range(SCOPE_Y[0] * SIZE, SCREEN_HEIGHT, SIZE):
            pygame.draw.line(screen, BLACK, (0, y), (SCREEN_WIDTH, y), LINE_WIDTH)

        if not game_over:
            curTime = time.time()
            if curTime - last_move_time > speed:
                if not pause:
                    b = True
                    last_move_time = curTime
                    next_s = (snake[0][0] + pos[0], snake[0][1] + pos[1])
                    if next_s == food:
                        # 吃到了食物
                        snake.appendleft(next_s)
                        score += food_style[0]
                        speed = orispeed - 0.03 * (score // 100)
                        food = create_food(snake)
                        food_style = get_food_style()
                    else:
                        if SCOPE_X[0] <= next_s[0] <= SCOPE_X[1] and SCOPE_Y[0] <= next_s[1] <= SCOPE_Y[1] \
                                and next_s not in snake:
                            snake.appendleft(next_s)
                            snake.pop()
                        else:
                            game_over = True

        # 画食物
        if not game_over:
            # 避免 GAME OVER 的时候把 GAME OVER 的字给遮住了
            pygame.draw.rect(screen, food_style[1], (food[0] * SIZE, food[1] * SIZE, SIZE, SIZE), 0)

        # 画蛇
        for s in snake:
            pygame.draw.rect(screen, DARK, (s[0] * SIZE + LINE_WIDTH, s[1] * SIZE + LINE_WIDTH,
                                            SIZE - LINE_WIDTH * 2, SIZE - LINE_WIDTH * 2), 0)

        print_text(screen, font1, 30, 7, f'速度: {score//100}')
        print_text(screen, font1, 450, 7, f'得分: {score}')

        if game_over:
            if start:
                print_text(screen, font2, (SCREEN_WIDTH - fwidth) // 2, (SCREEN_HEIGHT - fheight) // 2, 'GAME OVER', RED)

        pygame.display.update()


if __name__ == '__main__':
    main()

完毕!!感谢您的收看

----------★★历史博文集合★★----------

我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具 NumPy Pygame

相关推荐
AI视觉网奇1 小时前
麒麟系统播放图片 速度比较
开发语言·python·pygame
EanoJiang4 小时前
仿神秘海域/美末环境交互的程序化动画学习
游戏·c#
岁忧9 小时前
(nice!!!)(LeetCode 每日一题) 679. 24 点游戏 (深度优先搜索)
java·c++·leetcode·游戏·go·深度优先
★YUI★14 小时前
学习游戏制作记录(制作系统与物品掉落系统)8.16
学习·游戏·ui·unity·c#
lingzhilab21 小时前
零知开源——基于STM32F103RBT6与ADXL362三轴加速度计的体感迷宫游戏设计与实现
游戏
绝缘体11 天前
折扣大牌点餐api接口对接适合本地生活吗?
大数据·网络·搜索引擎·pygame
代码改变世界100861 天前
像素风球球大作战 HTML 游戏
前端·游戏·html
YF云飞2 天前
Unity音频管理:打造沉浸式游戏音效
游戏·unity·游戏引擎·游戏程序·个人开发
王廷胡_白嫖帝2 天前
Qt猜数字游戏项目开发教程 - 从零开始构建趣味小游戏
开发语言·qt·游戏
m0_552200822 天前
《UE5_C++多人TPS完整教程》学习笔记43 ——《P44 奔跑混合空间(Running Blending Space)》
c++·游戏·ue5