zoukankan      html  css  js  c++  java
  • Pygame制作答题类游戏的实现

    代码地址如下:
    http://www.demodashi.com/demo/13495.html

    概述

    个人比较喜欢玩这些答题类的游戏,在这类的游戏中其实存在着一些冷知识在里面。练习pygame的过程中,在网络上搜索,几乎没有找到这类游戏的示例教程,就蒙生了制作一个答题游戏的念头,最开始的时候,这个游戏是使用键盘输入的方式来答题的,没有开始界面,没有结束界面,后来几经修改,改为全鼠标操作。打包了exe文件,无需安装python直接点击exe文件也可以使用。

    详细

    主要思路

    游戏一般都有一个显示名称的title页,还有一个关于游戏介绍的界面,以及主要的内容——答题的界面。还有游戏结束时的一些统计数据。预想中的游戏完整是还包含了题库在线获取,有统计榜等内容,但是由于自己没有可以使用的公网地址和存储,这个演示改为单机版。

    准备工作

    开发的过程中,只使用了pygame一个外部库。其他的特性都是使用python自带的。
    本游戏使用到的图片来自网络,做了少量的处理。包括了一张图片作为鼠标样式,一张图片作为开始界面的背景,一张图片作为游戏过程的背景,一张图片作为游戏结束时统计的背景。
    收集一些题目,保存为xml文件,文件的结构如下图:
    xml题库文件的结构
    为增加游戏的可玩性和惊喜度,题量尽量不要少于50题,这里我只是作为测试和演示,只收集了20题内容,基本上是python的基础知识题。

    需要自定义字体,否则将无法显示中文,将字体文件保存在font文件夹中。

    titleFont = pygame.font.Font('font/YaHei.ttf', 150)
    globalFont = pygame.font.Font('font/Hei.ttf', 36)
    questionFont = pygame.font.Font('font/HuaKanSong.ttf', 24)
    answerFont = pygame.font.Font('font/HuaKanSong.ttf', 22)
    helpFont = pygame.font.Font('font/HuaKanSong.ttf', 24)
    

    实现过程的部分代码展示

    1. 自定义鼠标样式代码,概念上就是先获取鼠标的坐标,隐藏原来的鼠标样式,重新定义鼠标的位置是图片的什么位置,我是定义在图片的左上角,然后将该图片画出。这样的步骤就完成了自定义鼠标。

      mouseCursor = pygame.image.load('img/cursor.png').convert_alpha()
      

      载入鼠标的图片时,记得需要转换透明区域,图片的保存也是需要保存为可以保留透明区域的图片格式

      x, y = pygame.mouse.get_pos()  # 获取鼠标的坐标
      mouseCursor = pygame.image.load('img/cursor.png').convert_alpha()  # 载入鼠标的图片
      
      pygame.mouse.set_visible(False)  # 隐藏原来的鼠标样式
      x -= 0
      y -= 0
      SUBFACE.blit(mouseCursor, (x, y))  # 绘画出鼠标样式,并且定义鼠标的坐标
      
    2. 读取题库的实现,题目保存在一个xml文件中。使用内置的xml模块读取该文件,并解析出题目、答案、正确答案等信息。然后再随机取出其中的10道题,形成本次开始游戏的题目。

      assert os.path.exists(filename), '题库文件: %s 不存在,游戏无法执行。' % (filename)
      

      利用assert做断言判断,如果加载的题库文件不存在,直接把游戏奔溃掉,因为如果没有题库这个就什么都玩不了了。

      # 读取xml文件中的题库
      question_data = parse(filename)
      # 得到根节点
      root = question_data.documentElement
      
      game_level = []
      questions = root.getElementsByTagName("question")
      
      for item in questions:
          q_list = {}
          answerList = []
          question = item.getAttribute("title")
          answer_items = item.getElementsByTagName("answer")  # 返回一个列表
          answerList.append(answer_items[0].getElementsByTagName("a")[0].childNodes[0].data)
          answerList.append(answer_items[0].getElementsByTagName("b")[0].childNodes[0].data)
          answerList.append(answer_items[0].getElementsByTagName("c")[0].childNodes[0].data)
          answerList.append(answer_items[0].getElementsByTagName("d")[0].childNodes[0].data)
          correct = item.getElementsByTagName("correct")[0].childNodes[0].data
          q_list['question'] = question
          q_list['answers'] = answerList
          q_list['correct'] = correct
          game_level.append(q_list)
      

      上面的代码会将xml文件中的数据读取出来后存放为一个列表,每一道题是一个字典,包括了题目、四个选择答案、正确的答案三个部分,而选择答案又是一个列表。

      # 生产随机指定数量的题集,利用set的去重特性,这样当set的长度是10时,就是10个不重复的数字
      tmp_level = set()
      while len(tmp_level) < 10:
          randNum = random.randint(0, len(game_level) - 1)
          tmp_level.add(randNum)
      
      new_question = []
      for i in tmp_level:
          new_question.append(game_level[i])
      
      # 因为set的缘故,提取出来的题目是按顺序排列的,需要打乱一次,形成每次游戏时的题目顺序的独特随机性
      random.shuffle(new_question)
      
      return new_question
      

      最后是随机生成指定数量的一组数字,用于获取随机的问题集,由于set()是有序的,在获取了新的随机问题集完成后,还需要再将这个问题集打乱。这样做的目的可以让每次开始游戏时,都存在随机性,就算两次随机选择出来的题目一样,也会因为再次随机打乱而显示不同。
      整个读取文件的函数,是这个游戏的重要部分,其他的内容无非就是界面的显示而已。

    3. 答题控制的逻辑,先获取鼠标的当前位置,当鼠标在答案的方形范围内,就先将答案改变颜色,提示玩家当前选中备选的是已经改变颜色的答案。点击该答案后,就判断和该题的正确答案是否一致,一致返回yes错误返回no,这两个返回的值用于统计答题正确率和分数。

      x, y = pygame.mouse.get_pos()  # 获取鼠标的位置
      pressed = pygame.mouse.get_pressed()  # 获取鼠标的事件
      # 四个答案区域的内容的鼠标鼠标时间控制
      if item1_rect.left < x < item1_rect.right and item1_rect.top < y < item1_rect.bottom:
      item1_image = answerFont.render('1 - ' + level_answer[0], True, color_dict['gold'])
      SURFACE.blit(item1_image, item1_rect)
      for event in pressed:
      if event == 1:
      if level_correct == 1:
      return 'yes'
      else:
      return 'no'
      # 其他三个答案的判断同理,不再重复演示
      
    
    4. 最好把完成的代码使用pyinstaller打包成exe文件,这里我是在一个32位的window系统下打包的,所以文件可以在32位和64位的window系统中直接执行。
    

    pyinstall -F answer.py -i img/delbrucks-brain.ico

    
    
    ### 运行效果与文件截图
    1. 游戏的初始标题界面
    ![标题界面](http://www.demodashi.com/contentImages/image/20180706/qlLTmvLd5LytOAHl7bF.png "标题界面")
    2. 游戏的主界面,也就是游戏界面
    ![主游戏界面](http://www.demodashi.com/contentImages/image/20180706/WnrUjVxRTqXzmbhPFmV.png "主游戏界面")
    3. 游戏的结束统计界面
    ![游戏结束统计界面](http://www.demodashi.com/contentImages/image/20180706/nbBIXeg05srvNmjGc7j.png "游戏结束统计界面")
    4. 关于游戏界面
    ![关于游戏界面](http://www.demodashi.com/contentImages/image/20180706/fD3MsOsboF4h7bL2fLe.png "关于游戏界面")
    5. 项目的结构,font文件夹为游戏需要的字体,img文件夹为用到图片文件
    ![项目结构](http://www.demodashi.com/contentImages/image/20180706/IUhpttyaEeDkdWq01Li.png "项目结构")
    6. 压缩包下载后解压出来是长这个样子
    ![压缩包结构](http://www.demodashi.com/contentImages/image/20180706/Q5g7MmlkOJy6wXZRWX7.png "压缩包结构")
    ### 其他补充
    使用了pyinstaller将整个项目打包成exe文件,可以在不安装python运行环境的情况下运行体验,可以自行修改data.xml文件。修改里面的题目,形成自己新的题库。
    如果需要移植到mac或者linux系统中运行,也是可以的,理论上可能需要修改字体文件即可,但本人未测试。如果需要请自行测试。
    源码里面有一段在测试的时候作弊用的代码,注释掉,没有删除,如果有兴趣可以按照那个思路去做一些所谓的作弊,但其实作为答题游戏,也没有什么可以作弊的,无非就是提示和显示答案。Pygame制作答题类游戏的实现
    
    > 代码地址如下:<br>http://www.demodashi.com/demo/13495.html
    
    
    
    > 注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/demodashi/p/9443408.html
Copyright © 2011-2022 走看看