用PyGame实现贪吃蛇游戏

本文详细介绍使用Python和Pygame库开发贪吃蛇游戏的过程,包括环境搭建、游戏逻辑实现及界面设计等关键步骤。

准备工作

配置环境

使用Anaconda配置新环境。通用代码为:

conda create -n 新建环境名字 python==3.X

我写的代码是

conda create -n GUIexmaple python==3.6

意义为,创建一个名为GUIexample的环境,python版本为3.6

安装PyGame

进入创建好的环境,代码为

activate GUIexample

安装PyGame,代码为

pip install pygame

如何测试?

进入Pycharm后,使用import pygame测试,如果不报错的话,说明pygame安装成功。

开发游戏

这里主要以代码的讲解为主,防止自己以后忘记。

导入模块

import pygame
from snakeClass import Point
from snakeFunction import gen_food, rect
from sys import exit
import random

snakeClasssnakeFunction是我自己写的类对象和函数,先不用管这两个模块。

建立窗口

pygame.init()                                # 初始化
width = 800                        			 # 窗口宽度
hight = 600                                  # 窗口高度
score = 0                                    # 分数记录
window = pygame.display.set_mode((width, hight))  # 初始化一个准备显示的窗口或屏幕
bgColor = (191, 224, 206)                    # 游戏背景颜色
pygame.display.set_caption('贪吃蛇大作战')     # 设置当前窗口标题

.set_mode()后会得到一个准备要显示的窗口或屏幕,已经给出了宽为800,高为600。

.set_caption()设置窗口左上角的标题。

如果此时点击运行的话,屏幕上会生成一个窗口,但是闪一下就没有了。因此需要设置一个循环,让窗口一直在屏幕上显示,保持刷新。并且通过事件监听让程序获得正常退出死循环的功能。全套代码如下:

pygame.init()                                # 初始化
width = 800                        			 # 窗口宽度
hight = 600                                  # 窗口高度
score = 0                                    # 分数记录
window = pygame.display.set_mode((width, hight))  # 初始化一个准备显示的窗口或屏幕
bgColor = (191, 224, 206)                    # 游戏背景颜色
pygame.display.set_caption('贪吃蛇大作战')     # 设置当前窗口标题

gameFlag = True                             # 控制游戏进行的标志
frameRate = 12                               # 控制游戏的帧率
clock = pygame.time.Clock()         # 创建一个对象来帮助跟踪时间
while gameFlag:
    clock.tick(frameRate)                    # 更新clock对象
    for event in pygame.event.get():         # 从队列中获取事件
        if event.type == pygame.QUIT:
            gameFlag = False

得到如下图所示的窗口。
在这里插入图片描述
知道了如何设置窗口后,下面我们需要构造一个登录界面,这个登录界面包括“开始游戏”、“退出游戏”、“关于作者”三个按钮,“贪吃蛇大作战”一个标题,以及一个图标。

设置登录窗口

"""-----------------设置登录窗口的相关参数-----------------"""
startSur = pygame.Surface(window.get_size()) # 生成登录窗口画布
startSur = startSur.convert()
startSurColor = (140, 180, 200)
startSur.fill(startSurColor)

导入要加载的图片

# 加载各个素材图片 并且赋予变量名
title = pygame.image.load("./Images/title.png")
title.convert()
titleWidth, titleHight = title.get_size()

i0 = pygame.image.load("./Images/snake.png")
i0.convert()

i1 = pygame.image.load("./Images/start_black.png")
i1.convert()
i1Width,i1Hight = i1.get_size()
i11 = pygame.image.load("./Images/start_red.png")
i11.convert()

i2 = pygame.image.load("./Images/end_black.png")
i2.convert()
i2Width,i2Hight = i2.get_size()
i21 = pygame.image.load("./Images/end_red.png")
i21.convert()

i3 = pygame.image.load('./Images/author_black.png')
i3.convert()
i3Width,i3Hight = i3.get_size()
i31 = pygame.image.load('./Images/author_red.png')
i31.convert()

这里我用.convert()指令的原因是我生成的按钮图片是透明的,所以不需要再使用.convert_alpha()转换为透明的了。.get_size()函数是为了得到图片的(注意顺序)。

还有需要注意的是图片的路径问题,./的含义就是相对路径,在主函数的路径下面。

构建登录窗口

while loginFlag:
    clock.tick(60)
    buttons = pygame.mouse.get_pressed(3)
    x1, y1 = pygame.mouse.get_pos()
    if x1 >= (width-i1Width)/2 and x1 <= (width+i1Width)/2 and y1 >= (hight-i1Hight)/2+hChange and y1 <= (hight + i1Hight)/2-10+hChange:
        startSur.blit(i11, ((width-i1Width) / 2, (hight-i1Hight) / 2 + hChange))
        if buttons[0]:
            loginFlag = False
            
    elif x1 >= (width-i2Width)/2 and x1 <= (width+i2Width)/2 and y1 >= (hight-i2Hight)/2+i1Hight+10+hChange and y1 <= (hight + i2Hight)/2+i1Hight+hChange:
        startSur.blit(i21, ((width-i2Width) / 2, (hight-i2Hight) / 2 + i1Hight + hItv + hChange))
        if buttons[0]:
            print("游戏退出...")
            pygame.quit()
            exit()

    elif x1 >= (width-i3Width)/2 and x1 <= (width+i3Width)/2 and y1 >= (hight-i3Hight)/2+2*(i1Hight+10)+hChange and y1 <= (hight + i3Hight)/2+2*(i1Hight + 10)+hChange:
        startSur.blit(i31, ((width-i3Width) / 2, (hight-i3Hight) / 2 + 2 * (i1Hight+hItv) + hChange))
    else:
        i0 = pygame.transform.scale(i0, (550,550))
        startSur.blit(title, ((width-titleWidth) / 2, 160))
        startSur.blit(i0, (120, 30))
        startSur.blit(i1, ((width-i1Width) / 2, (hight-i1Hight) / 2 + hChange))
        startSur.blit(i2, ((width-i2Width) / 2, (hight-i2Hight) / 2 + i1Hight + hItv + hChange))
        startSur.blit(i3, ((width-i3Width) / 2, (hight-i3Hight
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值