找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 108|回复: 0

[教程] 【新手教程】做一个带倒计时 + 随机抽题的答题考试系统

[复制链接]
发表于 2026-4-3 12:55:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 枝树 于 2026-4-3 12:55 编辑

前言
这个教程面向刚接触 Ren'Py、想在视觉小说里加入答题 / 考试玩法的创作者。
最终实现的核心功能:
  • 随机抽题(不重复)+ 选项随机打乱顺序
  • 单题限时倒计时,超时自动触发惩罚机制
  • 全流程数据记录(正确率、超时次数、剧情专属数值)
  • 答题结果直接对接后续剧情分支 / 多结局



[目录]
  • 模块 1:全局变量初始化
  • 模块 2:倒计时屏幕 + 超时惩罚机制
  • 模块 3:考试入口(正式 / 模拟双模式)
  • 模块 4:题目循环核心逻辑
  • 模块 5:题库编写 + 随机选项实现
  • 模块 6:结局分支对接



模块 1:全局变量初始化
第一步先把所有要用到的变量定义好,放在任意.rpy文件的最顶部即可,作用是全程记录玩家的答题数据。
[RenPy] 纯文本查看 复制代码
default answer_time = 15    # 单题限时(秒)
default remain_time = 15    # 单题剩余时间
default sum_time = 0        # 答题总耗时
# 答题数据统计
default correct = 0         # 答对题数
default zhonger = 0         # 恶搞选项计数(可替换成任意剧情数值)
default evil = 0            # 超时题数(惩罚计数)
default trueend = 0         # 真结局触发数值
# 题库相关
default current_q_list = [] # 存放本轮随机抽取的题目编号
default show_q_index = 1    # 给玩家展示的当前题号
# 结局解锁(persistent为永久存档,重启游戏也不会重置)
default persistent.choose_ed1 = False
default persistent.choose_ed2 = False
# 引入随机数库(抽题、打乱选项必须)
init python:
    import random


模块 2:倒计时屏幕 + 超时惩罚机制
用 Ren'Py 的 Screen 功能做一个常驻的倒计时显示,同时处理超时逻辑,最后 3 秒会变红警告,时间到自动跳惩罚。

[RenPy] 纯文本查看 复制代码
# ========== 2. 倒计时屏幕 ==========
screen show_timer():
    zorder 100 # 把图层拉到最高,避免被背景/立绘挡住(解决倒计时不显示的bug)
    # 倒计时显示:剩余3秒变红警告
    if remain_time <= 3:
        text "⚠️ 剩余:[remain_time] 秒 ⚠️" xalign 0.9 yalign 0.1 size 24 color "#ff0000" bold True
    else:
        text "剩余时间:[remain_time] 秒" xalign 0.9 yalign 0.1 size 22 color "#ffffff" bold True
    # 每秒自动减1,时间到跳超时惩罚
    timer 1.0 repeat True:
        action If(
            remain_time > 0,
            SetVariable("remain_time", remain_time - 1),
            Jump("timeout_penalty")
        )
# ========== 超时惩罚处理 ==========
label timeout_penalty:
    hide screen show_timer # 关闭倒计时
    $ evil += 1            # 超时计数+1
    $ show_q_index += 1    # 题号+1,跳过本题
    $ sum_time += 15       # 耗时计入总时长
    jump exam_loop # 直接回到循环,进入下一题


模块 3:考试入口(正式 / 模拟双模式)
这里做了两个模式,新手可以先测试模拟模式,逻辑更简单;正式模式可以对接剧情和结局。


[RenPy] 纯文本查看 复制代码
# ========== 3. 正式考试入口 ==========
label exam:
    play music "roar of water dargon.mp3" # 替换成你的考试BGM
    """欢迎来到【最终测试】!
    每题限时15秒!
    顺带一提,超时的坏宝宝会有惩罚哦~"""

    # 每次进入考试,重置所有数据
    $ correct = 0
    $ sum_time = 0
    $ evil = 0
    $ zhonger = 0
    $ show_q_index = 1
    
    # 随机抽题:从1-30号题库里,随机抽9道不重复的题
    $ current_q_list = random.sample(range(1, 31), 9)
    jump exam_loop # 进入答题循环

# ========== 模拟考试入口(无惩罚、无剧情,纯练习) ==========
label examsimulate:
    "欢迎来到【模拟测试】!"
    $ show_q_index = 1
    # 随机抽题:从1-30号题库里,随机抽5道不重复的题
    $ current_q_list = random.sample(range(1, 31), 5)

    jump exam_loopsimulate # 进入模拟答题循环



模块 4:题目循环核心逻辑
这是整个系统的心脏,负责自动出题、重置计时、调用题目、统计数据,实现一套题自动连续考完。


[RenPy] 纯文本查看 复制代码
# ========== 4. 正式考试循环逻辑 ==========
label exam_loop:
    show class # 替换成你的考试背景
    # 检查是否还有题目:没题了就结束考试
    if not current_q_list:
        hide screen show_timer
        jump After_Exam

    # 从抽好的题目列表里,取出一道题
    $ rand_num = current_q_list.pop()
    "==========【第 [show_q_index] 题】=========="
    # 重置本题倒计时,显示计时器
    $ remain_time = 15
    show screen show_timer
    # 调用对应题号的题目(自动匹配q1、q2...q30)
    call expression "q" + str(rand_num)
    # 答完题后,统计耗时和题号
    $ sum_time += (15 - remain_time)
    $ show_q_index += 1

    jump exam_loop # 回到循环,进入下一题

# ========== 模拟考试循环逻辑(简化版) ==========
label exam_loopsimulate:
    show class # 替换成你的考试背景
    # 检查是否还有题目
    if not current_q_list:
        hide screen show_timer
        jump After_Examsimulate
    # 取出题目
    $ rand_num = current_q_list.pop()
    "==========【第 [show_q_index] 题】=========="
    # 调用题目
    call expression "q" + str(rand_num)
    # 题号+1
    $ show_q_index += 1
    jump exam_loopsimulate


模块 5:题库编写 + 随机选项实现
一个题目对应一个label,用列表实现选项随机打乱,同时可以给每个选项设置不同的数值,对接剧情。


[RenPy] 纯文本查看 复制代码
# ========== 5. 题库示例 ==========
# 第1题
label q1:
    # 选项格式:("选项文本", 正确得分, 剧情数值)
    $ q_data = [
        ("发达的运动器官", 0, 0), 
        ("能光合的器官", 0, 0), 
        ("防失水结构", 1, 0), # 正确选项,得分+1
        ("河神契约", 0, 1)     # 恶搞选项,剧情值+1
    ]
    $ random.shuffle(q_data)  # 随机打乱选项顺序
    
    # 出题菜单
    menu:
        "水生生物成功登陆演化的关键结构是什么?"
        "[q_data[0][0]]":
            $ correct += q_data[0][1]
            $ zhonger += q_data[0][2]         
        "[q_data[1][0]]":
            $ correct += q_data[1][1]
            $ zhonger += q_data[1][2]
        "[q_data[2][0]]":
            $ correct += q_data[2][1]
            $ zhonger += q_data[2][2]
        "[q_data[3][0]]":
            $ correct += q_data[3][1]
            $ zhonger += q_data[3][2]
    
    # 答完题隐藏倒计时,返回循环
    hide screen show_timer
    return

# 第2题、第3题...以此类推,复制上面的模板改内容即可
label q2:
    # 你的题目内容
    return


模块 6:结局分支对接
考完试后,用之前统计的correct、evil、zhonger等数值,做不同的剧情分支和结局。


[RenPy] 纯文本查看 复制代码
# ========== 6. 正式考试结算画面 ==========
label After_Exam:
    stop music
    hide class
    "考试结束!"
    "..."

    # 分支1:超时过多,触发坏结局
    if evil > 5:
        call evilend
    # 分支2:触发真结局
    elif trueend !=0 or zhonger >=7:
        "你的答题表现,触发了隐藏剧情!"
        # 你的真结局剧情
        call gameend
        $ persistent.choose_ed1 = True
    # 分支3:普通结局,按正确率分剧情
    else:
        if correct >= 7:
            "考得不错!顺利通关!"
            # 你的好结局剧情
        elif correct >= 5:
            "发挥一般,勉强通关~"
            # 你的普通结局剧情
        else:
            "正确率太低,触发了洪水结局!"
            # 你的坏结局剧情
        $ persistent.choose_ed2 = True
    return

# ========== 模拟考试结算 ==========
label After_Examsimulate:
    hide class
    "测试结束!"
    "正确题数:[correct] / 5"

    if correct >= 4:
        "太棒了!学霸!"
    elif correct >= 2:
        "还不错,继续努力!"
    else:
        "小子,继续加油啊"
    return







您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号 )

GMT+8, 2026-4-15 09:09 , Processed in 0.021211 second(s), 8 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表