基于Pygame实现简单的贪吃蛇游戏


Posted in Python onDecember 06, 2021

导入相关的包

import pygame, sys, random
from pygame.locals import *

设置屏幕大小以及基本参数

设置屏幕大小为400*400,mainClock = pygame.time.Clock()用来设置时间同步,不会根据计算机的运行来决定运行多少次, mainClock.tick(1) 一秒只会运行一次,设置了屏幕的底色为白色。

# 定义屏幕的宽高
WIDTH = 400
HEIGHT = 400
# 初始化屏幕 设置窗口标题
surface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
pygame.display.set_caption('贪吃蛇')

pygame.init()
mainClock = pygame.time.Clock()

# 定义使用的颜色
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)


while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    surface.fill(WHITE)
    pygame.display.update()
    mainClock.tick(1)

基于Pygame实现简单的贪吃蛇游戏

设置贪吃蛇的位置,以及移动的大小

这里设置了贪吃蛇的长度和起始位置,和食物和蛇的宽度,这里必须设置为可以被食物和蛇的宽度整除的数,这样才能保证蛇能到任意的位置

# 设置蛇的初始长度
snakeWidth = 4
# 设置蛇的起始位置为(40,40)
snakeX = 40
snakeY = 40
# 食物和蛇的宽度设置为8
FOODSNAKEWIDTH = 8
# 定义四个方向
moveLeft = False
moveRight = False
moveUp = False
moveDown = False
# 定义初始的方向
moveRight = True


def getSnake():
    # 设置蛇的初始长度为4,并设置蛇的初始位置为(40,40)
    # 因为贪吃蛇会拐弯,所以将蛇设置为一个列表
    snake = []
    for i in range(snakeWidth):
        snake.append(pygame.Rect(snakeX + i * FOODSNAKEWIDTH, snakeY, FOODSNAKEWIDTH, FOODSNAKEWIDTH))
    return snake


# 贪吃蛇
snake = getSnake()

绘制蛇

surface.fill(WHITE)
for s in snake:
    pygame.draw.rect(surface, BLACK, s)

让蛇动起来

这里将蛇列表最后一位移除,然后将第一位的位置根据方向加减坐标

snake.pop()
    newTop = copy.deepcopy(snake[0])
    # 改变蛇的位置
    if moveRight:
        newTop.left += FOODSNAKEWIDTH
    if moveLeft:
        newTop.left -= FOODSNAKEWIDTH
    if moveUp:
        newTop.top -= FOODSNAKEWIDTH
    if moveDown:
        newTop.top += FOODSNAKEWIDTH

    snake.insert(0, newTop)

基于Pygame实现简单的贪吃蛇游戏

这样会有一个问题,如果超出屏幕呢,我们将超出屏幕,那么就会消失,我们只需要你移动第一个元素的时候,如果超出则将元素移动另一个位置。

# 改变蛇的位置
    if moveRight:
        if newTop.right == WIDTH:
            newTop.left = 0
        else:
            newTop.left += FOODSNAKEWIDTH
    if moveLeft:
        if newTop.left == 0:
            newTop.right == WIDTH
        else:
            newTop.left -= FOODSNAKEWIDTH
    if moveUp:
        if newTop.top == 0:
            newTop.bottom = HEIGHT
        else:
            newTop.top -= FOODSNAKEWIDTH
    if moveDown:
        if newTop.bottom == HEIGHT:
            newTop.top = 0
        else:
            newTop.top += FOODSNAKEWIDTH

实现贪吃蛇拐弯

为了实现对应的功能,我们将方向变量改为一个变量,这样我们方便修改方向

# 定义四个方向
# moveLeft moveRight moveUp moveDown
# 定义初始的方向
snakeDirection = "moveRight"
  ----
  省略的代码
  ----
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                if snakeDirection == "moveRight":
                    snake.reverse()
                snakeDirection = "moveLeft"
            if event.key == K_RIGHT:
                if snakeDirection == "moveLeft":
                    snake.reverse()
                snakeDirection = "moveRight"
            if event.key == K_UP:
                if snakeDirection == "moveDown":
                    snake.reverse()
                snakeDirection = "moveUp"
            if event.key == K_DOWN:
                if snakeDirection == "moveUp":
                    snake.reverse()
                snakeDirection = "moveDown"

为了方便看到效果,我将mainClock.tick(1) 设置为mainClock.tick(3)

基于Pygame实现简单的贪吃蛇游戏

实现随机食物

这里用了很啰嗦的代码,我自己也看不下去,有点含糊,这里为了简单只设计了一个食物,遍历屏幕上不是贪吃蛇的可以放食物的集合,然后随机生成一个食物。

if len(foods) < foodnum:

        canFoodColl = []
        # 获取当前不是贪吃蛇的位置集合
        for x in range(sizeNum):
            for y in range(sizeNum):
                foodExist = True
                for sn in snake:
                    if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top:
                        foodExist = False
                        break
                if foodExist:
                    canFoodColl.append({'x': x, 'y': y})
        f = canFoodColl[random.randint(0, len(canFoodColl))]
        foods.append(pygame.Rect(f['x'], f['y'], FOODSNAKEWIDTH, FOODSNAKEWIDTH))

基于Pygame实现简单的贪吃蛇游戏

吃食物

这里用 colliderect判断二者是否相撞,然后食物集合置空,不减去贪吃蛇集合的最后一个元素。

if len(foods) < foodnum:

        canFoodColl = []
        # 获取当前不是贪吃蛇的位置集合
        for x in range(sizeNum):
            for y in range(sizeNum):
                foodExist = True
                for sn in snake:
                    if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top:
                        foodExist = False
                        break
                if foodExist:
                    canFoodColl.append({'x': x, 'y': y})
        f = canFoodColl[random.randint(0, len(canFoodColl))]
        foods.append(pygame.Rect(f['x'] * FOODSNAKEWIDTH, f['y'] * FOODSNAKEWIDTH, FOODSNAKEWIDTH, FOODSNAKEWIDTH))
        print(f['x'])
        print(f['y'])
    else:
        if newTop.colliderect(foods[0]):
            foods = []
            eatFlg = True
        print('xxx')

基于Pygame实现简单的贪吃蛇游戏

完整代码 

import pygame, sys, random
from pygame.locals import *
import copy

# 定义屏幕的宽高
WIDTH = 400
HEIGHT = 400
# 初始化屏幕 设置窗口标题
surface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
pygame.display.set_caption('贪吃蛇')

pygame.init()
mainClock = pygame.time.Clock()

# 定义使用的颜色
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)

# 设置蛇的初始长度
snakeWidth = 4
# 设置蛇的起始位置为(40,40)
snakeX = 40
snakeY = 40
# 食物和蛇的宽度设置为8
FOODSNAKEWIDTH = 8
# 定义四个方向
# moveLeft moveRight moveUp moveDown
# 定义初始的方向
snakeDirection = "moveRight"

# 食物区间
foods = []
# 用去宽度处以对应的 大小,减去1 就是食物矩形起点可以存在的区间
#sizeNum = HEIGHT / FOODSNAKEWIDTH - 1
# 这里为了减少计算
sizeNum = 39
# 为了简单我们只设置一个食物
foodnum = 1


def getSnake():
    # 设置蛇的初始长度为4,并设置蛇的初始位置为(40,40)
    # 因为贪吃蛇会拐弯,所以将蛇设置为一个列表
    snake = []
    for i in range(snakeWidth):
        snake.append(pygame.Rect(snakeX + i * FOODSNAKEWIDTH, snakeY, FOODSNAKEWIDTH, FOODSNAKEWIDTH))
    return snake


# 贪吃蛇
snake = getSnake()

while True:

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                if snakeDirection == "moveRight":
                    snake.reverse()
                snakeDirection = "moveLeft"
            if event.key == K_RIGHT:
                if snakeDirection == "moveLeft":
                    snake.reverse()
                snakeDirection = "moveRight"
            if event.key == K_UP:
                if snakeDirection == "moveDown":
                    snake.reverse()
                snakeDirection = "moveUp"
            if event.key == K_DOWN:
                if snakeDirection == "moveUp":
                    snake.reverse()
                snakeDirection = "moveDown"
    surface.fill(WHITE)
    for s in snake:
        pygame.draw.rect(surface, BLACK, s)
    for f in foods:
        pygame.draw.rect(surface, GREEN, f)
    pygame.display.update()


    # 是否吃了食物
    eatFlg = False

    newTop = copy.deepcopy(snake[0])
    # 改变蛇的位置
    if snakeDirection == "moveRight":
        if newTop.right == WIDTH:
            newTop.left = 0
        else:
            newTop.left += FOODSNAKEWIDTH
    if snakeDirection == "moveLeft":
        if newTop.left == 0:
            newTop.right = WIDTH
        else:
            newTop.left -= FOODSNAKEWIDTH
    if snakeDirection == "moveUp":
        if newTop.top == 0:
            newTop.bottom = HEIGHT
        else:
            newTop.top -= FOODSNAKEWIDTH
    if snakeDirection == "moveDown":
        if newTop.bottom == HEIGHT:
            newTop.top = 0
        else:
            newTop.top += FOODSNAKEWIDTH

    if len(foods) < foodnum:

        canFoodColl = []
        # 获取当前不是贪吃蛇的位置集合
        for x in range(sizeNum):
            for y in range(sizeNum):
                foodExist = True
                for sn in snake:
                    if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top:
                        foodExist = False
                        break
                if foodExist:
                    canFoodColl.append({'x': x, 'y': y})
        f = canFoodColl[random.randint(0, len(canFoodColl))]
        foods.append(pygame.Rect(f['x'] * FOODSNAKEWIDTH, f['y'] * FOODSNAKEWIDTH, FOODSNAKEWIDTH, FOODSNAKEWIDTH))
        print(f['x'])
        print(f['y'])
    else:
        if newTop.colliderect(foods[0]):
            foods = []
            eatFlg = True
        print('xxx')



    snake.insert(0, newTop)
    if not eatFlg:
        snake.pop()

    mainClock.tick(3) 

以上就是基于Pygame实现简单的贪吃蛇游戏的详细内容,更多关于Pygame 贪吃蛇游戏的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python写的PHPMyAdmin暴力破解工具代码
Aug 06 Python
Python实现将n个点均匀地分布在球面上的方法
Mar 12 Python
Django验证码的生成与使用示例
May 20 Python
Python实现冒泡排序的简单应用示例
Dec 11 Python
详解Python核心对象类型字符串
Feb 11 Python
python实现对csv文件的列的内容读取
Jul 04 Python
Flask模拟实现CSRF攻击的方法
Jul 24 Python
python  Django中的apps.py的目的是什么
Oct 15 Python
python训练数据时打乱训练数据与标签的两种方法小结
Nov 08 Python
Python输出\u编码将其转换成中文的实例
Dec 15 Python
Python设计模式之观察者模式原理与用法详解
Jan 16 Python
python 实现让字典的value 成为列表
Dec 16 Python
Python可变集合和不可变集合的构造方法大全
Dec 06 #Python
Python实现视频中添加音频工具详解
Dec 06 #Python
Python实现GIF动图以及视频卡通化详解
Python实现照片卡通化
用Python爬取英雄联盟的皮肤详细示例
Python+腾讯云服务器实现每日自动健康打卡
Dec 06 #Python
python 管理系统实现mysql交互的示例代码
You might like
福利彩票幸运号码自动生成器
2006/10/09 PHP
php语言中使用json的技巧及json的实现代码详解
2015/10/27 PHP
laravel框架实现去掉URL中index.php的方法
2019/10/12 PHP
深入理解JS中的变量及作用域、undefined与null
2014/03/04 Javascript
jQuery中prependTo()方法用法实例
2015/01/08 Javascript
js中this的用法实例分析
2015/01/10 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
只要1K 纯JS脚本送你一朵3D红色玫瑰
2016/08/09 Javascript
JavaScript 中对象的深拷贝
2016/12/04 Javascript
nodejs入门教程五:连接数据库的方法分析
2017/04/24 NodeJs
js 两个日期比较相差多少天的实例
2017/10/19 Javascript
总结JavaScript在IE9之前版本中内存泄露问题
2018/04/28 Javascript
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
使用python加密自己的密码
2015/08/04 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
使用python Telnet远程登录执行程序的方法
2019/01/26 Python
python调用c++传递数组的实例
2019/02/13 Python
python定时检测无响应进程并重启的实例代码
2019/04/22 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
window环境pip切换国内源(pip安装异常缓慢的问题)
2019/12/31 Python
python异步Web框架sanic的实现
2020/04/27 Python
翻转数列python实现,求前n项和,并能输出整个数列的案例
2020/05/03 Python
HTML5 video进入全屏和退出全屏的实现方法
2020/07/28 HTML / CSS
印度尼西亚最大的电商平台:Tokopedia(印尼版淘宝)
2017/12/02 全球购物
您在慕尼黑的跑步商店:Lauf-bar
2019/10/11 全球购物
可靠的数据流传输TCP
2016/03/15 面试题
优秀通讯员事迹材料
2014/01/28 职场文书
2014年单位植树节活动方案
2014/03/23 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
办公室岗位职责
2015/02/04 职场文书
2014年个人年终总结
2015/03/09 职场文书
黄埔军校观后感
2015/06/10 职场文书
投诉书格式范本
2015/07/02 职场文书
如何用RabbitMQ和Swoole实现一个异步任务系统
2021/05/29 PHP
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技