专栏首页Crossin的编程教室用python写一个简单的贪吃蛇游戏

用python写一个简单的贪吃蛇游戏

不知道有多少同学跟我一样,最初接触编程的动机就是为了自己做个游戏玩?

Python 虽然并不是一个“为游戏而生”的语言,但也有着自己的游戏引擎。最常用的就是 pygame。另外还有一个知名游戏引擎 cocos2d,它的最初版本就是基于 python 的 cocos2d-python。这两个引擎我们都有过案例,其中 pygame 更是做过一个较为详尽的入门教程 --《打飞机》小游戏,链接见文末。

今天要给大家分享的是一个 pygame 写的“贪吃蛇”小游戏:

“贪吃蛇”这个小游戏在编程学习中的常客,因为:

1. 简单,最基本的游戏元素只需要蛇和食物两个就可以进行了。(打飞机还需要三个元素呢,想想分别是什么?)方向的话只要上下左右4个固定方向就可以了。

2. 有基本的数据结构面向对象的思想在其中。游戏开发本身就会用到很多面向对象的概念,而蛇的身体又是一个天然的“链表”结构,太适合用来练习数据结构了。

另外比较有趣的一点是,Python 这个单词在英语里就是蟒蛇的意思,贪吃蛇可以算是“同名游戏”了。

很多学校里程序开发课程的作业都会有贪吃蛇的选题,也经常会有同学问到我们相关的代码。(诺基亚手机对这款游戏也是情有独钟。)之前我做过一个《贪吃蛇大作战》的 Python 版本,基于 cocos2d-python 开发。但那个对于初学者来说有些复杂了。这次是由我们的助教 @清风小筑 开发的一个更加适合初学者学习的简易版本。

对于整个开发过程及代码的详细说明,我们都写在了文档里,一并上传了 github。需要的同学可自行下载练习,可尝试更改蛇的速度、颜色,添加多个食物等。(获取地址请在公众号 Crossin的编程教室 里回复关键字 贪吃蛇

这里我们做个简要介绍:

此代码基于 pygame 开发,所以运行前请确保你的 Python 里已成功安装 pygame。然后直接运行代码中的 mySnake.py 即可开始游戏。

除了最终的代码外,我们还特意分解了几个过程中的 py 文件,供想要自己开发的同学参考。

开发思路

游戏开发通常都会采用面向对象的设计。这里我们有三个类:食物,另外还有背景(用来绘制格子)。

游戏的主循环里主要依次做这么几件事:

  1. 获取键盘事件
  2. 绘制背景
  3. 更新蛇的位置
  4. 画蛇、食物
  5. 碰撞检测
  6. 屏幕刷新

蛇和食物的绘制都是通过 pygame 里的 Surface 对象实现,绘制不同颜色的格子。

蛇的身体使用 Rect 对象,通过 list 保存。

蛇的移动是这个游戏的核心操作。我们没有选择修改蛇的位置,而是每次移动时,根据蛇的前进方向增加一个头部节点,其余位置都向前移动一个节点,并删除尾端节点,这样就等于实现了蛇的移动。如果是吃到了食物,就在尾部再加上节点,就实现了增长。

游戏中要做碰撞检测,这个用 pygame 的 colliderect 就行。我们要判断:1.撞墙了没?2.撞自己了没?3.撞到食物了没?然后分别做不同的处理

游戏主循环的核心代码:

while going:
    lastt = clock.tick(60) # 帧率 60
    dt += lastt # 累计时间
    c += 1
    # 0 键盘按压等事件响应
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_UP and validDirect != 0: direct = 1 # 按了向上 1 并且当前方向不是向下 0 ,则向上
            elif event.key == K_DOWN and validDirect != 1: direct = 0 # 向上 1 ,向下 0
            elif event.key == K_LEFT and validDirect != 2: direct = 3 # 向左 3, 向右 2
            elif event.key == K_RIGHT and validDirect != 3: direct = 2 
    # 0.1 画全屏的黑色背景
    screen.fill(black)
    # 1 判断是否移动
    if dt > interval: # 移动的时间间隔
        validDirect = direct
        dt = 0 # 初始化时间
        endPop = s.move(snake,direct)
    # 1.1 画蛇
    for i in snake:
        screen.blit(s.ball, i)
    # 2 画线条
    b.drawGrid(screen)
    # 3.1 分数更新
    scoret=b.scoref.render(str(score), True, (255, 255, 255)) # 实时得分
    screen.blit(scoret, (0, 0)) # 实时分数
    scoret2=b.scoref.render('best:'+str(best), True, (255, 255, 255)) # 最佳得分
    screen.blit(scoret2, (width-6*edge, 0)) # 最佳分数
    # 3.2 食物
    screen.blit(f.food, foodr) # 根据 fr(Rect 对象) 更新 food(Surface 对象) 位置 ,绘图
    # 4 判断撞击
    clli = s.strike(snake,foodr)
    if clli == 0: # 撞墙 撞自己
        going = False
    elif clli == 1: # 吃果实
        snake.append(endPop) # 长尾巴
        score += 1
        if not f.get_foodpos(foodr,snake): going = False # 生成 food 新位置, 如果占满全屏,则退出
    # 5 屏幕刷新
    pygame.display.flip() # 显示图形

完整代码和详细说明比较长,就不都贴在这里了,大家可以下载项目到本地后查看及运行。获取项目地址请在公众号 Crossin的编程教室 里回复关键字 贪吃蛇

文中代码由 清风小筑 完成

本文分享自微信公众号 - Crossin的编程教室(crossincode),作者:清风小筑

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 简单三步,用 Python 发邮件

    0. 前言 发送电子邮件是个很常见的开发需求。比如你写了个监控天气的脚本,发现第二天要下雨,或者网站上关注的某个商品降价了,就可以发个邮件到邮箱来提醒自己。 使...

    Crossin先生
  • 获取编程新技能的5个技巧

    “你是怎么学会所有这些框架和语言的?”,最近在黑客马拉松上一个朋友问我。 “其实,很简单,只要用你想学的东西去创建一个合适又值得的项目就行了,”我回答说。 “真...

    Crossin先生
  • 【Pygame 第9课】 一大波飞机

    又到周一了,小伙伴们周末过得可好?是不是有人刚刚结束了无聊的暑假,又开始丰富多彩的校园生活了? 上周最后的课里说了,这次我们要来加入一大波飞机正在接近的效果。这...

    Crossin先生
  • 互联设备如何改变制造业

    10.16.18-How-Connected-Devices-are-Changing-the-Manufacturing-Industry-1068x656_...

    用户4122690
  • PHP开发人员对JAVA的WEB开发入门(初版-基础知识)

    静儿
  • Android基础:Fragment,看这篇就够了

    Fragment 作为 Android 最基本,最重要的基础概念之一。本文从为什么出现 Fragment 开始,介绍了相关的方方面面。

    天天P图攻城狮
  • ViewPager与Fragment那些事儿

    本文会讲解: 1.viewPager与Fragment使用过程中,偶现页面混乱问题的可能原因以及解决方案。 2.notifyDataSetChange方法在v...

    MelonTeam
  • Android高频面试专题 - 基础篇(二)Fragment

    Fragment是Activity中用户界面的一个行为或者是一部分。主要是支持在大屏幕上动态和更为灵活的去组合或是交换UI组件,通过将Activity的布局分割...

    Android扫地僧
  • RocketMQ系列(六)批量发送与过滤

    今天我们再来看看RocketMQ的另外两个小功能,消息的批量发送和过滤。这两个小功能提升了我们使用RocketMQ的效率。

    小忽悠
  • 关于数字雨特效的学习

    关于数字雨特效的学习 数字雨特效在很多场景都得到应用,看起来非常具有科技感。因此,一次偶然的机会在CSDN中学习了如何制作特效雨,下面分享一下学习数字特效雨的...

    崔笑颜

扫码关注云+社区

领取腾讯云代金券