【童年经典小游戏】使用Python实现经典贪吃蛇游戏

使用Python实现经典贪吃蛇游戏

贪吃蛇(Snake)作为一个经典的小游戏,从早期的手机游戏到网页小游戏,一直深受玩家的喜爱。本文将详细介绍如何使用Python来实现一个简化版的贪吃蛇游戏,包括所需库的选择、游戏逻辑的设计、关键代码的剖析,以及如何对代码进行拓展和优化。

简介

贪吃蛇的游戏规则相对简单:玩家通过控制蛇的移动方向,让蛇吃掉场景中的食物,每吃到一个食物,蛇身会增长一节,同时得分增加。当蛇撞到墙壁或自身时,游戏结束。虽然逻辑简单,但是实现起来需要兼顾用户交互、动画刷新和碰撞检测等多个层面的问题。

实现思路与准备

游戏框架与库选择

实现贪吃蛇有多种途径,这里我们将使用Python的Pygame库来完成,它是一个基于SDL的简单易用的游戏开发框架。Pygame的优势在于:

  • 易于安装与使用
  • 提供处理图形、输入事件、声音等的API
  • 社区资源丰富

游戏基本逻辑

  1. 初始化游戏场景:定义窗口大小、背景颜色、刷新率等基本参数。
  2. 表示贪吃蛇:可以使用列表来表示蛇的身体,每个元素代表一个“块”的坐标(如网格坐标)。蛇头位于列表末尾,列表头部为蛇尾。
  3. 控制方向:通过键盘事件获取上下左右方向键的输入,更改蛇移动的方向。
  4. 移动与增长:每帧更新蛇头位置。如果吃到食物,不移除蛇尾(长度增加),否则移除蛇尾,保持长度。
  5. 食物生成:在随机位置生成食物,确保不与蛇身重叠。
  6. 碰撞检测:检测蛇头是否碰到边界或自身身体块,如是则游戏结束。
  7. 得分与显示:在窗口中显示当前得分、游戏状态等信息。

代码实现

完整代码

下面是一个简单版本的贪吃蛇代码示例。请确保本机已安装pygame库,可通过pip install pygame命令安装。

import pygame
import random
import sys

# 初始化Pygame
pygame.init()

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

# 游戏窗口尺寸与标题
WIDTH, HEIGHT = 600, 400
BLOCK_SIZE = 20  # 蛇与食物的大小
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")

clock = pygame.time.Clock()

# 字体设置
font = pygame.font.SysFont(None, 30)

def draw_text(msg, color, x, y):
    text = font.render(msg, True, color)
    screen.blit(text, [x, y])

def create_food(snake_list):
    while True:
        x = random.randint(0, (WIDTH // BLOCK_SIZE) - 1) * BLOCK_SIZE
        y = random.randint(0, (HEIGHT // BLOCK_SIZE) - 1) * BLOCK_SIZE
        if [x, y] not in snake_list:
            return [x, y]

def game_loop():
    # 初始参数
    game_over = False
    game_close = False

    # 初始蛇位置与移动方向
    x = WIDTH // 2
    y = HEIGHT // 2
    x_change = 0
    y_change = 0

    snake_list = []
    snake_length = 1

    food = create_food(snake_list)
    score = 0

    while not game_over:
        while game_close:
            screen.fill(BLACK)
            draw_text("游戏结束,按 Q 退出 或 C 重来", RED, WIDTH//4, HEIGHT//3)
            draw_text(f"得分: {score}", WHITE, WIDTH//4, HEIGHT//3 + 40)
            pygame.display.update()

            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        game_over = True
                        game_close = False
                    if event.key == pygame.K_c:
                        return  # 重新开始

        # 方向控制
        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_LEFT and x_change == 0:
                    x_change = -BLOCK_SIZE
                    y_change = 0
                elif event.key == pygame.K_RIGHT and x_change == 0:
                    x_change = BLOCK_SIZE
                    y_change = 0
                elif event.key == pygame.K_UP and y_change == 0:
                    y_change = -BLOCK_SIZE
                    x_change = 0
                elif event.key == pygame.K_DOWN and y_change == 0:
                    y_change = BLOCK_SIZE
                    x_change = 0

        # 更新蛇头位置
        x += x_change
        y += y_change

        # 边界检测
        if x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT:
            game_close = True

        screen.fill(BLACK)
        # 绘制食物
        pygame.draw.rect(screen, GREEN, [food[0], food[1], BLOCK_SIZE, BLOCK_SIZE])

        # 更新蛇身体列表
        snake_head = [x, y]
        snake_list.append(snake_head)
        if len(snake_list) > snake_length:
            del snake_list[0]

        # 蛇头碰到身体检测
        for segment in snake_list[:-1]:
            if segment == snake_head:
                game_close = True

        # 绘制蛇
        for segment in snake_list:
            pygame.draw.rect(screen, WHITE, [segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE])

        draw_text(f"得分: {score}", WHITE, 10, 10)
        pygame.display.update()

        # 判断是否吃到食物
        if x == food[0] and y == food[1]:
            food = create_food(snake_list)
            snake_length += 1
            score += 10

        clock.tick(10)  # 控制游戏帧率

def main():
    while True:
        game_loop()

if __name__ == "__main__":
    main()

代码关键点解析

初始化与游戏窗口

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")
  • pygame.init()初始化Pygame。
  • set_mode创建游戏窗口,set_caption为窗口标题。
  • clock = pygame.time.Clock()用于控制游戏的刷新帧率。

贪吃蛇的表示与移动

snake_list = []
snake_length = 1
  • snake_list列表用于存储蛇每个节的坐标,如[ [x1, y1], [x2, y2], … ],末尾为蛇头。
  • 每次移动时将新的头部坐标加入snake_list末尾,如果没有吃到食物,则移除首元素(蛇尾),达到移动效果。

食物的生成

def create_food(snake_list):
    while True:
        x = random.randint(0, (WIDTH // BLOCK_SIZE) - 1) * BLOCK_SIZE
        y = random.randint(0, (HEIGHT // BLOCK_SIZE) - 1) * BLOCK_SIZE
        if [x, y] not in snake_list:
            return [x, y]
  • 随机生成网格点作为食物位置,保证不与蛇身重叠。
  • 每次吃到食物后重新调用此函数获得新位置。

碰撞检测与游戏结束

if x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT:
    game_close = True
  • 检测蛇头坐标是否超出游戏区域,如是则表示撞墙,游戏结束。
for segment in snake_list[:-1]:
    if segment == snake_head:
        game_close = True
  • 检查蛇头是否与身体其它部分重叠,若是则游戏结束。

运行代码

首先在桌面创建一个文本文件,将代码复制进去,然后重命名为.py文件

之后我们打开终端(win+r)输入cmd
然后右键文件属性,找到路径
在cmd中输入 cd 文件路径,就可以进入到相应的路径中去,之后输入

Python 文件名

在这里插入图片描述

上方向键:向上移动
下方向键:向下移动
左方向键:向左移动
右方向键:向右移动
游戏目标是让蛇吃掉出现的绿色方块(食物)。每当蛇吃到食物:
蛇身长度会增加一格。
得分会增加10分。
需要注意的要点:
切勿让蛇头碰到游戏窗口的边界,否则游戏结束。
不要让蛇头碰到自己身体的其他部分,否则游戏结束。
当游戏结束时,屏幕上会显示相应提示,可按 C 键重新开始,或按 Q 键退出游戏。

中文不显示问题解决

下面的链接作者会教你如何下载字体
https://gitcode.com/open-source-toolkit/c55ef/overview?utm_source=tools_gitcode&index=top&type=card&&null
在这里插入图片描述

# -*- coding: utf-8 -*-
import pygame
import random
import sys

# 初始化Pygame
pygame.init()

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

# 游戏窗口尺寸与标题
WIDTH, HEIGHT = 600, 400
BLOCK_SIZE = 20  # 蛇与食物的大小
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")

clock = pygame.time.Clock()

# 使用支持中文的字体(需准备支持中文的字体文件,如simhei.ttf放在同目录下)
font = pygame.font.Font("simhei.ttf", 30)

def draw_text(msg, color, x, y):
    text = font.render(msg, True, color)
    screen.blit(text, [x, y])

def create_food(snake_list):
    while True:
        x = random.randint(0, (WIDTH // BLOCK_SIZE) - 1) * BLOCK_SIZE
        y = random.randint(0, (HEIGHT // BLOCK_SIZE) - 1) * BLOCK_SIZE
        if [x, y] not in snake_list:
            return [x, y]

def game_loop():
    # 初始参数
    game_over = False
    game_close = False

    # 初始蛇位置与移动方向
    x = WIDTH // 2
    y = HEIGHT // 2
    x_change = 0
    y_change = 0

    snake_list = []
    snake_length = 1

    food = create_food(snake_list)
    score = 0

    while not game_over:
        while game_close:
            screen.fill(BLACK)
            draw_text("游戏结束,按 Q 退出 或 C 重来", RED, WIDTH//4, HEIGHT//3)
            draw_text(f"得分: {score}", WHITE, WIDTH//4, HEIGHT//3 + 40)
            pygame.display.update()

            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        game_over = True
                        game_close = False
                    elif event.key == pygame.K_c:
                        return  # 重新开始
                elif event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

        # 方向控制
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                # 避免180度掉头:当向左移动时不允许直接向右,向上时不允许直接向下,反之亦然
                if event.key == pygame.K_LEFT and x_change == 0:
                    x_change = -BLOCK_SIZE
                    y_change = 0
                elif event.key == pygame.K_RIGHT and x_change == 0:
                    x_change = BLOCK_SIZE
                    y_change = 0
                elif event.key == pygame.K_UP and y_change == 0:
                    y_change = -BLOCK_SIZE
                    x_change = 0
                elif event.key == pygame.K_DOWN and y_change == 0:
                    y_change = BLOCK_SIZE
                    x_change = 0

        # 如果蛇还未开始移动,则不更新位置(防止游戏开始后立即结束)
        if x_change == 0 and y_change == 0:
            # 等待用户进行第一次方向输入
            pygame.display.update()
            clock.tick(10)
            continue

        # 更新蛇头位置
        x += x_change
        y += y_change

        # 边界检测
        if x < 0 or x >= WIDTH or y < 0 or y >= HEIGHT:
            game_close = True

        screen.fill(BLACK)
        # 绘制食物
        pygame.draw.rect(screen, GREEN, [food[0], food[1], BLOCK_SIZE, BLOCK_SIZE])

        # 更新蛇身体列表
        snake_head = [x, y]
        snake_list.append(snake_head)
        if len(snake_list) > snake_length:
            del snake_list[0]

        # 蛇头碰到身体检测
        for segment in snake_list[:-1]:
            if segment == snake_head:
                game_close = True

        # 绘制蛇
        for segment in snake_list:
            pygame.draw.rect(screen, WHITE, [segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE])

        draw_text(f"得分: {score}", WHITE, 10, 10)
        pygame.display.update()

        # 判断是否吃到食物
        if x == food[0] and y == food[1]:
            food = create_food(snake_list)
            snake_length += 1
            score += 10

        clock.tick(10)  # 控制游戏帧率

def main():
    while True:
        game_loop()

if __name__ == "__main__":
    main()

拓展与优化建议

添加音效:在吃食物或游戏结束时播放音效。
难度调节:增加游戏关卡或根据得分提升蛇的移动速度。
UI美化:换成更精美的图片作为蛇身和食物贴图。
排行榜功能:记录每次游戏的分数,并在游戏结束时显示历史最高分。

总结

通过本篇博客的学习,我们了解了如何借助Python与Pygame实现一个简单的贪吃蛇游戏。从基础的游戏循环、蛇与食物的数据结构设计,到碰撞检测与绘制画面,都有了一个清晰的实现范例。未来,您可以在这个基础上添加更多特性,打造一款更丰富、更有趣的游戏体验,当然这仅仅是一个小案例,若想要完整的实现,可以看看建议,或者结合其他游戏开发工具,unity,虚幻等
请添加图片描述

### 回答1: 好的,下面是一个简单的Python单机小游戏贪吃蛇实现过程: 1. 导入必要的模块 ```python import pygame import random ``` 2. 初始化Pygame ```python pygame.init() ``` 3. 设置游戏窗口大小和标题 ```python window_width = 640 window_height = 480 game_window = pygame.display.set_mode((window_width, window_height)) pygame.display.set_caption('Snake Game') ``` 4. 定义颜色和字体 ```python white = (255, 255, 255) black = (0, 0, 0) red = (255, 0, 0) font = pygame.font.SysFont(None, 25) ``` 5. 定义贪吃蛇和食物的初始位置和大小 ```python block_size = 10 snake_speed = 15 def snake(snake_list, block_size): for x_y in snake_list: pygame.draw.rect(game_window, black, [x_y[0], x_y[1], block_size, block_size]) def message_to_screen(msg, color): screen_text = font.render(msg, True, color) game_window.blit(screen_text, [window_width/6, window_height/6]) def gameLoop(): game_exit = False game_over = False lead_x = window_width/2 lead_y = window_height/2 lead_x_change = 0 lead_y_change = 0 snake_list = [] snake_length = 1 food_x = round(random.randrange(0, window_width-block_size)/10.0)*10.0 food_y = round(random.randrange(0, window_height-block_size)/10.0)*10.0 while not game_exit: while game_over == True: game_window.fill(white) message_to_screen('Game over, press Q to quit or C to play again', red) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_q: game_exit = True game_over = False elif event.key == pygame.K_c: gameLoop() for event in pygame.event.get(): if event.type == pygame.QUIT: game_exit = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: lead_x_change = -block_size lead_y_change = 0 elif event.key == pygame.K_RIGHT: lead_x_change = block_size lead_y_change = 0 elif event.key == pygame.K_UP: lead_y_change = -block_size lead_x_change = 0 elif event.key == pygame.K_DOWN: lead_y_change = block_size lead_x_change = 0 if lead_x >= window_width or lead_x < 0 or lead_y >= window_height or lead_y < 0: game_over = True lead_x += lead_x_change lead_y += lead_y_change game_window.fill(white) pygame.draw.rect(game_window, red, [food_x, food_y, block_size, block_size]) snake_head = [] snake_head.append(lead_x) snake_head.append(lead_y) snake_list.append(snake_head) if len(snake_list) > snake_length: del snake_list[0] for each_segment in snake_list[:-1]: if each_segment == snake_head: game_over = True snake(snake_list, block_size) pygame.display.update() if lead_x == food_x and lead_y == food_y: food_x = round(random.randrange(0, window_width-block_size)/10.0)*10.0 food_y = round(random.randrange(0, window_height-block_size)/10.0)*10.0 snake_length += 1 clock.tick(snake_speed) pygame.quit() quit() ``` 6. 调用游戏主函数 ```python gameLoop() ``` 这样一个简单的Python单机小游戏贪吃蛇就完成了。希望对您有所帮助! ### 回答2: 贪吃蛇是一款经典的单机小游戏使用Python语言编写可以实现这个游戏。下面我将简单介绍一下实现贪吃蛇游戏所需的主要步骤: 1. 导入相关的模块:使用Pythonpygame模块实现游戏窗口的创建和操作。 2. 定义蛇的初始位置和长度:可以使用列表来表示蛇的身体,列表中的每一项表示蛇身的一个部分的坐标。初始时可以定义一个长度为3的蛇,即初始时有三个坐标。 3. 设置游戏的主循环:使用pygame模块的事件循环来实现游戏的核心逻辑。在每一次循环中检测用户的操作,判断是否按下了方向键,如果按下方向键则改变蛇头的方向,同时更新蛇的位置。 4. 监测蛇头和食物的碰撞:在游戏的主循环中检测蛇头的位置是否与食物的位置重叠,如果重叠则蛇的长度加一,并在后面添加一个新的蛇身坐标。同时生成一个新的食物,并将其位置显示在屏幕上的随机位置。 5. 监测蛇头与蛇身的碰撞:每当蛇移动一步,都需要检测蛇头和蛇身的碰撞情况。如果蛇头和蛇身的任何一个部分的位置重合,则游戏结束。 6. 更新游戏界面:在每一次循环结束后,将蛇的身体和食物的位置更新显示在屏幕上。 以上是实现贪吃蛇游戏的主要步骤,具体的实现细节可以根据个人的想法进行扩展和优化,比如可以增加难度级别、计分系统等。希望这个简单的回答能帮助到你理解贪吃蛇游戏实现过程。 ### 回答3: 贪吃蛇是一个非常经典的单机小游戏,通过使用Python编程语言可以很好地实现。 首先,我们需要使用Pygame库来创建游戏窗口,并且设置蛇的移动规则、食物的生成和蛇与食物的交互。游戏窗口的大小、背景等可以根据个人喜好进行设置。 接下来,我们可以定义蛇的初始位置和长度,并且设置蛇的运动方向。每当蛇吃到食物时,蛇的长度会增加,并且在新的位置生成食物。蛇的运动方向由玩家控制,可以通过键盘的方向键来控制移动。 在游戏过程中,需要判断蛇是否吃到食物或者是否吃到自己的身体,这可以通过检查蛇的位置和碰撞检测来实现。如果蛇吃到食物,则增加长度,并且生成新的食物,如果蛇吃到自己的身体,则游戏结束。 游戏还可以设置计分系统,每当蛇吃到食物时,计分会增加,并且在游戏界面上显示出来。当蛇吃到自己的身体或者撞到边界时,游戏结束,最终会显示玩家的得分。 为了增加游戏的难度和趣味性,我们可以设置蛇的速度随着长度的增加而加快,或者在游戏界面上放置一些障碍物,需要蛇绕过。 总结一下,使用Python编程语言可以很方便地实现贪吃蛇这个经典的单机小游戏,并且可以通过设置窗口、蛇的移动规则、食物的生成和交互、碰撞检测、计分系统等来增加游戏的乐趣和挑战。这个游戏是编程初学者非常适合练手的项目,也是可以让玩家回忆童年经典游戏的一种方式。
评论 150
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馒头学python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值