下面是框架,请在lua环境下运行。
require "import" import "android.widget.*" import "android.view.*" import "android.os.*" import "android.app.*" import "android.graphics.Typeface" 活动 = activity 布局参数 = { LinearLayout, orientation="vertical", layout_width="fill", layout_height="fill", background="#FFF5F5F5", { TextView, id="标题", text="不只有晴天 ‖ 测试版", textSize="20sp", layout_width="fill", layout_height="wrap", gravity="center", textColor="#FF4081", padding="8dp" }, { LinearLayout, id="属性容器", orientation="vertical", layout_width="fill", layout_height="wrap", padding="8dp", background="#EEEEEE" }, { ScrollView, layout_width="fill", layout_height="0dp", layout_weight=1, { TextView, id="剧情文本", textSize="16sp", layout_width="fill", layout_height="wrap", padding="16dp", textColor="#FF4081" } }, { ScrollView, layout_width="fill", layout_height="200dp", { LinearLayout, id="选项容器", orientation="vertical", layout_width="fill", layout_height="wrap", padding="8dp" } } } 活动.setContentView(loadlayout(布局参数)) 标题.setTypeface(nil, Typeface.BOLD) 剧情文本.setLineSpacing(1.2, 1.0) 游戏数据 = { 角色列表 = { 林小然 = { 介绍 = "同班同学,性格开朗的阳光男孩,篮球社主力队员,喜欢电子游戏和户外运动", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们几乎没有建立任何联系,毕业后就失去了联络。", [30] = "结局:你们保持着普通同学关系,偶尔会在同学聚会上见面。", [60] = "结局:你们成为了好朋友,经常一起打球玩游戏。", [80] = "结局:林小然对你很有好感,但最终谁都没有表白。", [100] = "结局:在一个樱花盛开的日子,林小然红着脸向你表白了!" } }, 苏雨晴 = { 介绍 = "文学社社长,温柔知性的学姐,喜欢阅读和写作,擅长钢琴", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们始终保持着礼貌的距离,毕业后各奔东西。", [30] = "结局:你们偶尔会在图书馆相遇,点头之交。", [60] = "结局:你们成为了可以讨论文学的朋友。", [80] = "结局:苏雨晴送了你一本她亲手写的诗集。", [100] = "结局:毕业典礼上,苏雨晴为你弹奏了一首原创钢琴曲。" } }, 陈默 = { 介绍 = "沉默寡言的转学生,独来独往,但成绩优异,喜欢天文和摄影", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们几乎没有说过话,毕业后就忘记了彼此。", [30] = "结局:你们偶尔会讨论学习问题。", [60] = "结局:你们成为了可以一起看星星的朋友。", [80] = "结局:陈默送了你一张他拍的星空照片。", [100] = "结局:在一个流星雨的夜晚,陈默终于向你敞开心扉。" } }, 赵明远 = { 介绍 = "学生会主席,品学兼优的学长,擅长演讲和辩论,目标明确", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们始终保持着公事公办的关系。", [30] = "结局:你们偶尔会讨论学生会工作。", [60] = "结局:你们成为了可以互相提建议的朋友。", [80] = "结局:赵明远在毕业演讲中提到了你。", [100] = "结局:赵明远放弃了名校offer,选择和你同校。" } }, 周子轩 = { 介绍 = "音乐才子,乐队主唱,性格张扬不羁,有很多粉丝", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们始终是偶像和粉丝的关系。", [30] = "结局:你们偶尔会在音乐教室遇到。", [60] = "结局:你们成为了可以讨论音乐的朋友。", [80] = "结局:周子轩为你写了一首歌。", [100] = "结局:在毕业演唱会上,周子轩当众向你表白。" } }, 夏小柔 = { 介绍 = "邻家女孩类型,活泼可爱,喜欢烘焙和小动物", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们只是普通的邻居关系。", [30] = "结局:你们偶尔会一起上学。", [60] = "结局:你们成为了可以分享点心的小伙伴。", [80] = "结局:夏小柔每天都会给你带自制点心。", [100] = "结局:在一个雨天,夏小柔红着脸递给你心形饼干。" } }, 叶清 = { 介绍 = "美术特长生,气质清冷,喜欢独处写生,擅长国画", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们几乎没有交集。", [30] = "结局:你们偶尔会在美术室遇到。", [60] = "结局:你们成为了可以讨论艺术的朋友。", [80] = "结局:叶清送了你一幅她画的肖像。", [100] = "结局:在毕业画展上,叶清的作品全是你的身影。" } }, 韩雪 = { 介绍 = "学霸型女生,冷静理性,目标是医学院,喜欢解谜游戏", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们只是普通的同学关系。", [30] = "结局:你们偶尔会讨论学习问题。", [60] = "结局:你们成为了可以一起解题的伙伴。", [80] = "结局:韩雪为你设计了一个专属谜题。", [100] = "结局:在毕业典礼上,韩雪解开了自己设下的心结。" } }, 林初夏 = { 介绍 = "体育特长生,田径队主力,性格爽朗,像个假小子", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们几乎没有接触。", [30] = "结局:你们偶尔会在操场遇到。", [60] = "结局:你们成为了可以一起跑步的朋友。", [80] = "结局:林初夏在比赛后把奖牌送给了你。", [100] = "结局:在终点线前,林初夏停下脚步牵起了你的手。" } }, 陆远 = { 介绍 = "校篮球队队长,阳光帅气,有很多追求者,但很专一", 属性 = { 好感度 = 0, 了解度 = 0, 亲密度 = 0, 心动值 = 0, 依赖度 = 0, 信任度 = 0, 默契度 = 0, 回忆度 = 0, 专属度 = 0 }, 结局 = { [0] = "结局:你们只是普通的校友关系。", [30] = "结局:你们偶尔会在篮球场遇到。", [60] = "结局:你们成为了可以一起打球的朋友。", [80] = "结局:陆远在比赛中专门为你投进了一个三分球。", [100] = "结局:在夺冠的瞬间,陆远当众向你表白。" } } }, 基础属性 = { 体力 = 100, 精力 = 100, 心情 = 80, 零花钱 = 1000, 学业 = 60, 魅力 = 40, 气质 = 30, 勇气 = 30, 智慧 = 50 }, 当前角色 = nil, 选择记录 = {}, 场景顺序 = {}, 当前场景 = nil, 日期 = 1 } 剧情配置= { 初始化= { 文本="欢迎来到不只有晴天,请选择你要攻略的角色。", 选项= { { 文本="林小然-阳光开朗的同班同学-男性", 跳转="林小然_开始", 效果=function() 游戏数据.角色列表.林小然.属性.了解度=5 游戏数据.当前角色 = "林小然" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略林小然,一个阳光开朗的同班同学" }, { 文本="苏雨晴-温柔知性的学姐-女性", 跳转="苏雨晴_开始", 效果=function() 游戏数据.角色列表.苏雨晴.属性.了解度=5 游戏数据.当前角色 = "苏雨晴" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略苏雨晴,一个温柔知性的学姐" }, { 文本="陈默-沉默寡言的转学生-男性", 跳转="陈默_开始", 效果=function() 游戏数据.角色列表.陈默.属性.了解度=5 游戏数据.当前角色 = "陈默" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略陈默,一个沉默寡言的转学生" }, { 文本="赵明远-学生会主席学长-男性", 跳转="赵明远_开始", 效果=function() 游戏数据.角色列表.赵明远.属性.了解度=5 游戏数据.当前角色 = "赵明远" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略赵明远,学生会主席学长" }, { 文本="周子轩-音乐才子-男性", 跳转="周子轩_开始", 效果=function() 游戏数据.角色列表.周子轩.属性.了解度=5 游戏数据.当前角色 = "周子轩" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略周子轩,音乐才子" }, { 文本="夏小柔-活泼可爱的邻家女孩-女性", 跳转="夏小柔_开始", 效果=function() 游戏数据.角色列表.夏小柔.属性.了解度=5 游戏数据.当前角色 = "夏小柔" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略夏小柔,活泼可爱的邻家女孩" }, { 文本="叶清-美术特长生-女性", 跳转="叶清_开始", 效果=function() 游戏数据.角色列表.叶清.属性.了解度=5 游戏数据.当前角色 = "叶清" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略叶清,美术特长生" }, { 文本="韩雪-学霸型女生-女性", 跳转="韩雪_开始", 效果=function() 游戏数据.角色列表.韩雪.属性.了解度=5 游戏数据.当前角色 = "韩雪" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略韩雪,学霸型女生" }, { 文本="林初夏-体育特长生-女性", 跳转="林初夏_开始", 效果=function() 游戏数据.角色列表.林初夏.属性.了解度=5 游戏数据.当前角色 = "林初夏" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略林初夏,体育特长生" }, { 文本="陆远-校篮球队队长-男性", 跳转="陆远_开始", 效果=function() 游戏数据.角色列表.陆远.属性.了解度=5 游戏数据.当前角色 = "陆远" table.insert(游戏数据.场景顺序, "初始化") end, 分析="你决定攻略陆远,校篮球队队长" } } }, } 当前剧情 = nil 剧情索引 = 1 剧情字数 = 0 剧情句子 = "" 剧情处理器 = Handler() 选项按钮 = {} function 显示结局报告() if not 游戏数据.当前角色 or not 游戏数据.角色列表[游戏数据.当前角色] then local 提示 = AlertDialog.Builder(活动) 提示.setTitle("提示") 提示.setMessage("游戏数据异常,请重新开始") 提示.setPositiveButton("确定",nil) 提示.show() return end local 角色名 = 游戏数据.当前角色 local 角色数据 = 游戏数据.角色列表[角色名] local 好感度 = 角色数据.属性.好感度 or 0 local 评价等级 = math.min(100, math.floor(好感度/20)*20) local 对话框 = AlertDialog.Builder(活动) local 视图 = LinearLayout(活动) 视图.setOrientation(LinearLayout.VERTICAL) 视图.setPadding(32,32,32,32) local 标题 = TextView(活动) 标题.setText("【"..角色名.."路线完整分析报告】") 标题.setTextSize(18) 标题.setTextColor(0xFFFF4081) 标题.setTypeface(nil, Typeface.BOLD) 标题.setGravity(Gravity.CENTER) 视图.addView(标题) local 滚动视图 = ScrollView(活动) 滚动视图.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) local 内容布局 = LinearLayout(活动) 内容布局.setOrientation(LinearLayout.VERTICAL) local 属性文本 = TextView(活动) 属性文本.setText("\n最终属性值:\n") 属性文本.setTextSize(14) 属性文本.setTypeface(nil, Typeface.BOLD) 内容布局.addView(属性文本) for 属性名, 值 in pairs(角色数据.属性) do local 属性行 = TextView(活动) 属性行.setText(属性名..": "..值) 属性行.setTextSize(12) 属性行.setPadding(0,0,0,4) 内容布局.addView(属性行) end local 结局文本 = TextView(活动) 结局文本.setText("\n\n最终结局:\n"..(角色数据.结局[评价等级] or "你们的关系发展到了一个特别的阶段。")) 结局文本.setTextSize(14) 内容布局.addView(结局文本) local 分析标题 = TextView(活动) 分析标题.setText("\n\n详细选择分析:") 分析标题.setTextSize(14) 分析标题.setTypeface(nil, Typeface.BOLD) 内容布局.addView(分析标题) for _, 场景名 in ipairs(游戏数据.场景顺序) do if 游戏数据.选择记录[场景名] then local 场景 = 剧情配置[场景名] if 场景 and 场景.选项 then for _, 选项 in ipairs(场景.选项) do if 选项.文本 == 游戏数据.选择记录[场景名] and 选项.分析 then local 分析文本 = TextView(活动) 分析文本.setText("\n"..场景名..": "..选项.文本.."\n"..选项.分析) 分析文本.setTextSize(12) 分析文本.setPadding(0,0,0,16) 内容布局.addView(分析文本) end end end end end 滚动视图.addView(内容布局) 视图.addView(滚动视图) 对话框.setView(视图) 对话框.setPositiveButton("重新开始",{ onClick=function() 游戏数据.当前角色 = nil 游戏数据.选择记录 = {} 游戏数据.场景顺序 = {} 游戏数据.日期 = 1 游戏数据.基础属性 = { 体力 = 100, 精力 = 100, 心情 = 80, 零花钱 = 1000, 学业 = 60, 魅力 = 40, 气质 = 30, 勇气 = 30, 智慧 = 50 } for 角色名, 角色 in pairs(游戏数据.角色列表) do 角色.属性.好感度 = 0 角色.属性.了解度 = 0 角色.属性.亲密度 = 0 角色.属性.心动值 = 0 角色.属性.依赖度 = 0 角色.属性.信任度 = 0 角色.属性.默契度 = 0 角色.属性.回忆度 = 0 角色.属性.专属度 = 0 end 显示剧情("初始化") end}) 对话框.setNegativeButton("退出",{ onClick=function() 活动.finish() end}) 对话框.show() end function 更新属性显示() 属性容器.removeAllViews() if not 游戏数据.当前角色 then return end local 基础布局 = LinearLayout(活动) 基础布局.setOrientation(LinearLayout.VERTICAL) 基础布局.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) local 基础标题 = TextView(活动) 基础标题.setText("【基础属性】") 基础标题.setTextSize(14) 基础标题.setTypeface(nil, Typeface.BOLD) 基础标题.setPadding(0,0,0,8) 基础布局.addView(基础标题) local 基础行布局 = LinearLayout(活动) 基础行布局.setOrientation(LinearLayout.HORIZONTAL) local 基础计数 = 0 for 属性名, 值 in pairs(游戏数据.基础属性) do local 属性视图 = TextView(活动) 属性视图.setText(属性名..": "..值) 属性视图.setTextSize(12) 属性视图.setPadding(8,0,8,8) 属性视图.setTextColor(0xFF3399FF) 属性视图.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,1)) 基础行布局.addView(属性视图) 基础计数 = 基础计数 + 1 if 基础计数 % 3 == 0 then 基础布局.addView(基础行布局) 基础行布局 = LinearLayout(活动) 基础行布局.setOrientation(LinearLayout.HORIZONTAL) end end if 基础计数 % 3 ~= 0 then 基础布局.addView(基础行布局) end 属性容器.addView(基础布局) local 角色布局 = LinearLayout(活动) 角色布局.setOrientation(LinearLayout.VERTICAL) 角色布局.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) 角色布局.setPadding(0,16,0,0) local 角色标题 = TextView(活动) 角色标题.setText("【"..游戏数据.当前角色.."】") 角色标题.setTextSize(14) 角色标题.setTypeface(nil, Typeface.BOLD) 角色标题.setPadding(0,0,0,8) 角色布局.addView(角色标题) local 角色行布局 = LinearLayout(活动) 角色行布局.setOrientation(LinearLayout.HORIZONTAL) local 角色计数 = 0 for 属性名, 值 in pairs(游戏数据.角色列表[游戏数据.当前角色].属性) do local 属性视图 = TextView(活动) 属性视图.setText(属性名..": "..值) 属性视图.setTextSize(12) 属性视图.setPadding(8,0,8,8) 属性视图.setTextColor(0xFFFF99CC) 属性视图.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,1)) 角色行布局.addView(属性视图) 角色计数 = 角色计数 + 1 if 角色计数 % 3 == 0 then 角色布局.addView(角色行布局) 角色行布局 = LinearLayout(活动) 角色行布局.setOrientation(LinearLayout.HORIZONTAL) end end if 角色计数 % 3 ~= 0 then 角色布局.addView(角色行布局) end 属性容器.addView(角色布局) end function 随机排序选项(选项表) local 随机选项 = {} for i,v in ipairs(选项表) do 随机选项[i] = v end for i = #随机选项, 2, -1 do local j = math.random(i) 随机选项[i], 随机选项[j] = 随机选项[j], 随机选项[i] end return 随机选项 end function 显示剧情(场景名) if type(场景名) == "function" then 场景名 = 场景名() end 游戏数据.当前场景 = 场景名 当前剧情 = 剧情配置[场景名] if not 当前剧情 then print("错误:找不到场景 "..tostring(场景名)) return end if type(当前剧情.文本) == "function" then 剧情句子 = 当前剧情.文本() else 剧情句子 = 当前剧情.文本 or "" end 剧情索引 = 1 剧情字数 = utf8.len(剧情句子) 剧情文本.setText("") local 随机选项 = 随机排序选项(当前剧情.选项 or {}) 更新选项(随机选项) if 剧情任务 then 剧情处理器.removeCallbacks(剧情任务) end 剧情任务 = function() if 剧情索引 <= 剧情字数 then 剧情文本.append(utf8.sub(剧情句子, 剧情索引, 剧情索引)) 剧情索引 = 剧情索引 + 1 剧情处理器.postDelayed(剧情任务, 40) end end 剧情处理器.post(剧情任务) 更新属性显示() end function 更新选项(选项表) 选项容器.removeAllViews() 选项按钮 = {} for i, 选项 in ipairs(选项表) do local 按钮 = Button(活动) 按钮.setLayoutParams(LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) 按钮.setText(选项.文本 or "选项") 按钮.setTextSize(14) 按钮.setPadding(16,16,16,16) 按钮.setBackgroundResource(android.R.drawable.btn_default) 按钮.setTextColor(0xFF333333) 按钮.onClick = function() if 选项.效果 and type(选项.效果) == "function" then 选项.效果() end if 游戏数据.当前场景 then 游戏数据.选择记录[游戏数据.当前场景] = 选项.文本 table.insert(游戏数据.场景顺序, 游戏数据.当前场景) end if 选项.跳转 then if 选项.跳转 == "显示结局报告" then 显示结局报告() else 显示剧情(选项.跳转) end else 活动.finish() end end 选项容器.addView(按钮) 选项按钮[i] = 按钮 end end 显示剧情("初始化")