Python贪吃蛇游戏详细讲解-带源码-可直接运行

之前写了个python对象和类、封装继承等基础知识,太枯燥,这次补充一个简单的Python源码,更直观的理解,并加以运用。

基础知识讲解在这里:Python基础-面向对象、对象和类、封装、继承、多态、项目练习

一、先了解下Pygame

Pygame是一个基于Python的游戏开发库,它提供了一系列的工具和接口,使开发人员能够轻松地创建各种类型的游戏,包括2D游戏和简单的3D游戏。在使用Pygame之前,您需要先安装Pygame库。您可以通过以下命令在命令行中安装Pygame:

pip install pygame

二、Pygame框架及步骤

  1. 初始化:先初始化Pygame。 创建窗口:创建窗口是游戏开发的第一步。可使用Pygame提供的set_mode()方法创建一个窗口。
  2. 处理事件:在Pygame中,所有的操作都是通过事件来实现的。可以使用event.get()方法获取所有的事件,并通过事件类型来判断用户的操作。
  3. 更新窗口:在绘制完图形后,需要使用pygame.display.update()方法来更新窗口,使得用户能够看到最新的游戏画面。
  4. 控制游戏帧率:在Pygame中,游戏帧率是非常重要的,可以使用Pygame提供的Clock类来控制游戏的帧率。
  5. 键盘和鼠标输入:在游戏中,键盘和鼠标输入也是非常重要的操作。可以使用Pygame提供的key模块和mouse模块来检测键盘和鼠标的输入。
    基础框架代码。
import pygame
import sys
SCREEN_X = 600
SCREEN_Y = 600

def main():
    pygame.init() # 初始化游戏引擎
    screen_size = (SCREEN_X, SCREEN_Y) # 设置游戏窗口的大小
    screen = pygame.display.set_mode(screen_size) # 创建游戏窗口
    pygame.display.set_caption('Snake') # 设置标题
    clock = pygame.time.Clock() # 控制游戏帧率
    
    while True: # 死循环,确保窗口一直显示
	    for event in pygame.event.get(): # 遍历所有事件
	        if event.type == pygame.QUIT: # 如果单击关闭窗口
	            sys.exit()

	    pygame.display.update() # 更新窗口
        clock.tick(5) # 控制游戏帧率
    # 游戏退出

if __name__ == '__main__':
    main()

三、snake 类、属性及方法

蛇类
方法: 增加/删除 、死亡判断、移动、改变方向
基本框架:

# 点以25为单位
class Snake:
    # 初始化各种需要的属性 [开始时默认向右/身体块x5]
    def __init__(self):
        self.dirction = pygame.K_RIGHT
        self.body = []
        for x in range(5):
            self.addnode()

    # 无论何时 都在前端增加蛇块
    def addnode(self):
    # 删除最后一个块
    def delnode(self):
    # 死亡判断
    def isdead(self):
    # 移动!
    def move(self):
    # 改变方向 但是左右、上下不能被逆向改变
    def changedirection(self, curkey):

四、food 类、属性及方法

食物类
方法: 放置/移除
基本框架:

class Food:
    def __init__(self):
        self.rect = pygame.Rect(-25, 0, 25, 25)
    # 移除实物
    def remove(self):
    # 放置实物
    def set(self):

先看下运行后的游戏界面,有点丑,各位可以继续美化:
在这里插入图片描述

五、完整代码

import pygame
import sys
import random

# 全局定义
SCREEN_X = 600
SCREEN_Y = 600

# 蛇类
# 点以25为单位
class Snake:
    # 初始化各种需要的属性 [开始时默认向右/身体块x5]
    def __init__(self):
        self.dirction = pygame.K_RIGHT
        self.body = []
        for x in range(5):
            self.addnode()

    # 无论何时 都在前端增加蛇块
    def addnode(self):
        left, top = (0, 0)
        if self.body:
            left, top = (self.body[0].left, self.body[0].top)
        node = pygame.Rect(left, top, 25, 25)
        if self.dirction == pygame.K_LEFT:
            node.left -= 25
        elif self.dirction == pygame.K_RIGHT:
            node.left += 25
        elif self.dirction == pygame.K_UP:
            node.top -= 25
        elif self.dirction == pygame.K_DOWN:
            node.top += 25
        self.body.insert(0, node)

    # 删除最后一个块
    def delnode(self):
        self.body.pop()

    # 死亡判断
    def isdead(self):
        # 撞墙
        if self.body[0].x not in range(SCREEN_X):
            return True
        if self.body[0].y not in range(SCREEN_Y):
            return True
        # 撞自己
        if self.body[0] in self.body[1:]:
            return True
        return False

    # 移动!
    def move(self):
        self.addnode()
        self.delnode()

    # 改变方向 但是左右、上下不能被逆向改变
    def changedirection(self, curkey):
        LR = [pygame.K_LEFT, pygame.K_RIGHT]
        UD = [pygame.K_UP, pygame.K_DOWN]
        if curkey in LR + UD:
            if (curkey in LR) and (self.dirction in LR):
                return
            if (curkey in UD) and (self.dirction in UD):
                return
            self.dirction = curkey

# 食物类
# 方法: 放置/移除
# 点以25为单位
class Food:
    def __init__(self):
        self.rect = pygame.Rect(-25, 0, 25, 25)

    def remove(self):
        self.rect.x = -25

    def set(self):
        if self.rect.x == -25:
            allpos = []
            # 不靠墙太近 25 ~ SCREEN_X-25 之间
            for pos in range(25, SCREEN_X - 25, 25):
                allpos.append(pos)
            self.rect.left = random.choice(allpos)
            self.rect.top = random.choice(allpos)
            print(self.rect)

def show_text(screen, pos, text, color, font_bold=False, font_size=60, font_italic=False):
    # 获取系统字体,并设置文字大小
    cur_font = pygame.font.SysFont("宋体", font_size)
    # 设置是否加粗属性
    cur_font.set_bold(font_bold)
    # 设置是否斜体属性
    cur_font.set_italic(font_italic)
    # 设置文字内容
    text_fmt = cur_font.render(text, 1, color)
    # 绘制文字
    screen.blit(text_fmt, pos)

def main():
    pygame.init() # 初始化游戏引擎
    screen_size = (SCREEN_X, SCREEN_Y) # 设置游戏窗口的大小
    screen = pygame.display.set_mode(screen_size) # 创建游戏窗口
    pygame.display.set_caption('Snake') # 设置标题
    clock = pygame.time.Clock() # 控制游戏帧率
    scores = 0
    isdead = False

    # 蛇/食物
    snake = Snake()
    food = Food()

    while True: # 死循环,确保窗口一直显示
        for event in pygame.event.get(): # 遍历所有事件
            if event.type == pygame.QUIT: # 如果单击关闭窗口
                sys.exit()
            if event.type == pygame.KEYDOWN:
                snake.changedirection(event.key)
                # 死后按space重新
                if event.key == pygame.K_SPACE and isdead:
                    return main()
        # 填充窗口颜色
        screen.fill((0, 0, 0))

        # 画蛇身 / 每一步+1分
        if not isdead:
            scores += 1
            snake.move()
        for rect in snake.body:
            pygame.draw.rect(screen, (0, 255, 0), rect, 0)

        # 显示死亡文字
        isdead = snake.isdead()
        if isdead:
            show_text(screen, (100, 200), 'YOU DEAD!', (227, 29, 18), False, 100)
            show_text(screen, (150, 260), 'press space to try again...', (0, 0, 22), False, 30)

        # 食物处理 / 吃到+50分
        # 当食物rect与蛇头重合,吃掉 -> Snake增加一个Node
        if food.rect == snake.body[0]:
            scores += 50
            food.remove()
            snake.addnode()

        # 食物投递
        food.set()
        pygame.draw.rect(screen, (255, 0, 127), food.rect, 0)
        # 显示分数文字
        show_text(screen, (50, 500), 'Scores: ' + str(scores), (255, 0, 0))

        pygame.display.update()
        clock.tick(5)

if __name__ == '__main__':
    main()

既然都看到这里了,请点赞+关注鼓励一下,后续继续更新。

  • 30
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
贪吃蛇游戏是一种经典的街机游戏,玩家需要控制一条蛇在游戏界面上移动,吃掉尽可能多的食物,同时避免撞到墙壁或自己的身体。下面是一个简单的Python贪吃蛇游戏讲解: 首先,我们需要导入所需的模块,包括pygame和random: ```python import pygame import random ``` 然后,我们需要初始化游戏并设置游戏窗口的大小: ```python pygame.init() window_width = 800 window_height = 600 window = pygame.display.set_mode((window_width, window_height)) pygame.display.set_caption("贪吃蛇游戏") ``` 接下来,我们需要定义蛇的初始位置和身体: ```python snake_x = window_width / 2 snake_y = window_height / 2 snake_body = [[snake_x, snake_y]] ``` 然后,我们需要定义食物的初始位置: ```python food_x = round(random.randrange(0, window_width - 20) / 20) * 20 food_y = round(random.randrange(0, window_height - 20) / 20) * 20 ``` 接下来,我们需要定义游戏的主循环,其中包括事件处理、蛇的移动和碰撞检测等: ```python running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 蛇的移动逻辑 # ... # 碰撞检测逻辑 # ... # 绘制游戏界面 # ... pygame.display.update() ``` 在蛇的移动逻辑中,我们需要根据玩家的输入来改变蛇的移动方向。可以使用pygame的键盘事件来实现: ```python keys = pygame.key.get_pressed() if keys[pygame.K_UP]: # 向上移动 # ... elif keys[pygame.K_DOWN]: # 向下移动 # ... elif keys[pygame.K_LEFT]: # 向左移动 # ... elif keys[pygame.K_RIGHT]: # 向右移动 # ... ``` 在碰撞检测逻辑中,我们需要检测蛇是否吃到了食物或撞到了墙壁或自己的身体: ```python # 检测蛇是否吃到了食物 if snake_x == food_x and snake_y == food_y: # 增加蛇的长度 # ... # 检测蛇是否撞到了墙壁或自己的身体 if snake_x < 0 or snake_x >= window_width or snake_y < 0 or snake_y >= window_height: # 游戏结束 # ... if [snake_x, snake_y] in snake_body[1:]: # 游戏结束 # ... ``` 在绘制游戏界面的逻辑中,我们需要绘制蛇和食物的位置: ```python # 绘制蛇的身体 for segment in snake_body: pygame.draw.rect(window, (0, 255, 0), (segment[0], segment[1], 20, 20)) # 绘制食物 pygame.draw.rect(window, (255, 0, 0), (food_x, food_y, 20, 20)) ``` 最后,我们需要在游戏结束时显示得分并退出游戏: ```python # 显示得分 # ... pygame.quit() ``` 这只是一个简单的贪吃蛇游戏讲解,实际的游戏逻辑可能更加复杂。你可以根据自己的需求和想法来扩展和改进这个游戏

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一码当前

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

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

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

打赏作者

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

抵扣说明:

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

余额充值