← 返回

应用详情

📦

星辰编年史

版本 v2 · 4.1 KB
ID: star_chronicles
⬇ 下载 CIP 🔍 返回列表
📝 应用描述
校园奇幻恋爱 · 好感度分支剧情
📋 详细信息
应用ID star_chronicles
名称 星辰编年史
版本 v2
文件大小 4.1 KB
上传时间 2026-07-29 20:50:47
状态 ✅ 已启用
权限 storage
💡 界面预览 (main.lua)
📄 Lua 源码
-- ============================================================
--  《星辰编年史·未响应的告白》  Oldchat CIP 移植版(稳定修复)
-- ============================================================

-- -------- 角色定义 --------
local CHARACTERS = {
    snow  = { name = "绫濑雪奈", emoji = "❄️", color = "#60a5fa" },
    shi   = { name = "天野诗织", emoji = "🎵", color = "#fbbf24" },
    tsuki = { name = "月读冥",   emoji = "🌙", color = "#a78bfa" }
}

-- -------- 游戏状态 --------
local state = {
    scene = "start",
    affection = { snow = 0, shi = 0, tsuki = 0 },
    flags = {}
}

-- -------- 存储读写 --------
function saveState()
    local data = {
        scene = state.scene,
        affection = state.affection,
        flags = state.flags
    }
    app.storage_set("game_state", app.json_encode(data))
end

function loadState()
    local raw = app.storage_get("game_state")
    if raw then
        local ok, data = pcall(app.json_decode, raw)
        if ok and data then
            state.scene = data.scene or "start"
            state.affection = data.affection or { snow=0, shi=0, tsuki=0 }
            state.flags = data.flags or {}
            return true
        end
    end
    return false
end

-- -------- 重置游戏 --------
function resetGame()
    state.scene = "start"
    state.affection = { snow = 0, shi = 0, tsuki = 0 }
    state.flags = {}
    app.storage_remove("game_state")
    render("start")
end

-- -------- UI 更新 --------
function updateAffectionDisplay()
    local parts = {}
    for id, ch in pairs(CHARACTERS) do
        local val = state.affection[id] or 0
        table.insert(parts, string.format("%s %s : %d", ch.emoji, ch.name, val))
    end
    app.set_text("affection", table.concat(parts, "  |  "))
end

-- -------- 选项处理 --------
local currentOptions = {}

function handleOption(index)
    local opt = currentOptions[index]
    if not opt then return end

    if opt.effects then
        for id, delta in pairs(opt.effects) do
            local old = state.affection[id] or 0
            state.affection[id] = math.max(0, math.min(1000, old + delta))
        end
    end

    if opt.next == "reset" then
        resetGame()
        return
    end

    if opt.next then
        render(opt.next)
    else
        app.toast("故事继续……")
    end
end

-- -------- 场景渲染(带安全检查) --------
function render(sceneId)
    -- 如果场景不存在,自动重置到开始
    if not scenes[sceneId] then
        app.toast("场景不存在,已重置")
        state.scene = "start"
        saveState()
        render("start")
        return
    end

    local scene = scenes[sceneId]
    if not scene then
        app.toast("场景数据无效,已重置")
        resetGame()
        return
    end

    app.set_text("narrator", scene.narrator or "")
    local speakerText = ""
    if scene.speaker and CHARACTERS[scene.speaker] then
        speakerText = CHARACTERS[scene.speaker].name .. ":"
    end
    app.set_text("speaker", speakerText)
    app.set_text("message", scene.message or "")
    app.set_text("chapter", scene.chapter or "")

    updateAffectionDisplay()

    local opts = scene.options
    if type(opts) == "function" then
        opts = opts()
    end
    if not opts then opts = {} end
    currentOptions = opts

    for i = 1, 4 do
        local btnId = "opt" .. i
        if i <= #opts then
            app.set_text(btnId, opts[i].label or "选项")
            app.set_visible(btnId, true)
            app.set_enabled(btnId, true)
        else
            app.set_visible(btnId, false)
        end
    end

    state.scene = sceneId
    saveState()
end

-- -------- 场景定义 --------
local scenes = {}

scenes.start = {
    chapter = "✦ 序章",
    narrator = "星澜学园 · 新学期",
    message = "昨夜,一颗流星划破天际。\n你站在窗前,心中涌起一阵莫名的悸动。",
    options = {
        { label = "✦ 前往学园", next = "intro" }
    }
}

scenes.intro = {
    chapter = "第一章 · 流星",
    narrator = "—— 校门口 · 樱花树下 ——",
    message = "三位少女同时看向你,她们的情感颜色在晨光中闪烁。",
    options = {
        { label = "❄️ 走向雪奈", next = "snow_1", effects = { snow = 10 } },
        { label = "🎵 走向诗织", next = "shi_1",   effects = { shi = 10 } },
        { label = "🌙 走向冥",   next = "tsuki_1", effects = { tsuki = 10 } }
    }
}

-- 雪奈路线
scenes.snow_1 = {
    chapter = "第二章 · 静谧之蓝",
    speaker = "snow",
    message = "雪奈微微垂下眼帘,声音很轻:\n「……你也感觉到了,对吗?」",
    options = {
        { label = "「你还好吗?看起来有点累。」", next = "snow_2", effects = { snow = 20 } },
        { label = "「那颗星……和你有关?」", next = "snow_2", effects = { snow = 10 } }
    }
}
scenes.snow_2 = {
    speaker = "snow",
    message = "她露出一丝难得的微笑:\n「……谢谢你,你是第一个会这么问我的人。」",
    options = {
        { label = "「我会一直陪着你。」", next = "snow_final", effects = { snow = 30 } },
        { label = "「以后有问题可以找我。」", next = "snow_final", effects = { snow = 20 } }
    }
}
scenes.snow_final = {
    chapter = "第六章 · 星朔之夜",
    speaker = "snow",
    message = "雪奈站在星光下,向你伸出手:\n「……你愿意和我一起,成为真正的自己吗?」",
    options = function()
        local aff = state.affection.snow or 0
        if aff >= 150 then
            return { { label = "✦ 接受告白", next = "ending_true_snow" } }
        elseif aff >= 80 then
            return { { label = "✦ 接受告白", next = "ending_normal_snow" } }
        else
            return { { label = "✦ 接受告白", next = "ending_bad_snow" } }
        end
    end
}

-- 诗织路线
scenes.shi_1 = {
    chapter = "第二章 · 活力之橙",
    speaker = "shi",
    message = "诗织眼睛亮晶晶的:\n「嘿嘿~我就知道你也会在意!那颗流星超帅的!」",
    options = {
        { label = "「你许了什么愿?」", next = "shi_2", effects = { shi = 20 } },
        { label = "「你总是这么有精神啊。」", next = "shi_2", effects = { shi = 10 } }
    }
}
scenes.shi_2 = {
    speaker = "shi",
    message = "她忽然压低声音,罕见地认真:\n「……秘密。不过——如果是你,我愿意告诉你。」",
    options = {
        { label = "「那告诉我吧。」", next = "shi_final", effects = { shi = 30 } },
        { label = "「……还是保持神秘吧。」", next = "shi_final", effects = { shi = 15 } }
    }
}
scenes.shi_final = {
    chapter = "第六章 · 星朔之夜",
    speaker = "shi",
    message = "诗织站在聚光灯下,歌声温柔:\n「这首只唱给你听的歌——你愿意一直听下去吗?」",
    options = function()
        local aff = state.affection.shi or 0
        if aff >= 150 then
            return { { label = "✦ 接受告白", next = "ending_true_shi" } }
        elseif aff >= 80 then
            return { { label = "✦ 接受告白", next = "ending_normal_shi" } }
        else
            return { { label = "✦ 接受告白", next = "ending_bad_shi" } }
        end
    end
}

-- 冥路线
scenes.tsuki_1 = {
    chapter = "第二章 · 紫罗兰之瞬",
    speaker = "tsuki",
    message = "冥的目光沉静如水:\n「……你看见了。那颗星的颜色。」",
    options = {
        { label = "「你也是……共感者?」", next = "tsuki_2", effects = { tsuki = 20 } },
        { label = "「星的颜色……?」", next = "tsuki_2", effects = { tsuki = 10 } }
    }
}
scenes.tsuki_2 = {
    speaker = "tsuki",
    message = "她微微勾了勾嘴角:\n「……我看到的,是紫罗兰色的光。你呢?」",
    options = {
        { label = "「我看到的……是你。」", next = "tsuki_final", effects = { tsuki = 30 } },
        { label = "「……和你一样。」", next = "tsuki_final", effects = { tsuki = 20 } }
    }
}
scenes.tsuki_final = {
    chapter = "第六章 · 星朔之夜",
    speaker = "tsuki",
    message = "冥将星砂轻轻放入你掌心:\n「……你愿意成为我的星辰吗?」",
    options = function()
        local aff = state.affection.tsuki or 0
        if aff >= 150 then
            return { { label = "✦ 接受告白", next = "ending_true_tsuki" } }
        elseif aff >= 80 then
            return { { label = "✦ 接受告白", next = "ending_normal_tsuki" } }
        else
            return { { label = "✦ 接受告白", next = "ending_bad_tsuki" } }
        end
    end
}

-- 结局场景(通用)
local function ending_scene(title, desc)
    return {
        chapter = "✦ " .. title,
        narrator = "—— 结局 ——",
        message = desc,
        options = {
            { label = "✦ 重新开始", next = "reset" }
        }
    end
end

scenes.ending_true_snow   = ending_scene("真结局 · 星辰守护", "雪奈与你紧握双手,星光永恒。\n「从今以后,我的星光只为你而亮。」")
scenes.ending_normal_snow = ending_scene("普通结局 · 记忆轨迹", "雪奈获得了自由,却失去了那些记忆。\n你们重新认识,但星光已逝。")
scenes.ending_bad_snow    = ending_scene("坏结局 · 星尘消散", "雪奈的身影消散在星光中,你再也找不到那片静谧的蓝。")

scenes.ending_true_shi    = ending_scene("真结局 · 星辰守护", "诗织的歌声传遍学园,她终于做回了自己。\n「从今以后,我只唱给你一个人听。」")
scenes.ending_normal_shi  = ending_scene("普通结局 · 记忆轨迹", "诗织回到舞台,依旧戴着面具。\n她隐约记得你,却记不清那些约定。")
scenes.ending_bad_shi     = ending_scene("坏结局 · 星尘消散", "诗织的歌声戛然而止,她化作星光消散在夜空。")

scenes.ending_true_tsuki  = ending_scene("真结局 · 星辰守护", "冥的眼中不再只有悲悯,她找到了属于自己的光芒。\n「……从今以后,我的星辰就是你了。」")
scenes.ending_normal_tsuki= ending_scene("普通结局 · 记忆轨迹", "冥继续她的医学之路,偶尔仰望星空时会感到一阵怀念。")
scenes.ending_bad_tsuki   = ending_scene("坏结局 · 星尘消散", "冥选择了消散,你再也无法触及那片紫罗兰。")

-- -------- 页面布局 --------
local page = ui.page({
    title = "星辰编年史",
    children = {
        ui.text({ id = "chapter", text = "", size = 14, color = "#888888", margin = 4 }),
        ui.text({ id = "narrator", text = "", size = 13, color = "#aaaaaa", margin = 4, center = true }),
        ui.text({ id = "speaker",  text = "", size = 16, color = "#ffffff", margin = 4 }),
        ui.text({ id = "message",  text = "", size = 15, color = "#f0f0f0", margin = 8 }),
        ui.text({ id = "affection", text = "", size = 13, color = "#cccccc", margin = 6 }),
        ui.button({ id = "opt1", text = "", on_click = function() handleOption(1) end, margin = 4 }),
        ui.button({ id = "opt2", text = "", on_click = function() handleOption(2) end, margin = 4 }),
        ui.button({ id = "opt3", text = "", on_click = function() handleOption(3) end, margin = 4 }),
        ui.button({ id = "opt4", text = "", on_click = function() handleOption(4) end, margin = 4 })
    }
})

-- -------- 启动入口 --------
if not loadState() then
    state.scene = "start"
end
render(state.scene)   -- 如果场景无效,内部会自动重置

return page
⬇ 下载 CIP 文件 🔍 返回列表