Compare commits

..

219 Commits

Author SHA1 Message Date
MrZ626
b1fc121a46 0.10.7:15P更新 2020-08-31 23:11:25 +08:00
MrZ626
8e2b49d529 修改15p进入方法 2020-08-31 23:11:13 +08:00
MrZ626
653d81d5f8 取消font文件追踪 2020-08-31 23:09:56 +08:00
MrZ626
fea9da1710 部分控件重排版 2020-08-31 21:46:51 +08:00
MrZ626
0f9fe54957 15p退出按钮忘了放好 2020-08-31 21:46:26 +08:00
MrZ626
851c34dc46 删行末空格 2020-08-31 16:56:04 +08:00
MrZ626
f162733f82 攻击特效和徽章特效并入sysFX 2020-08-31 16:52:26 +08:00
MrZ626
91b2e0b9db 在倒计时阶段按一些按键会报错 2020-08-31 16:41:59 +08:00
MrZ626
7e2af7fe2e 同场景代码整合到scenes.lua 2020-08-31 16:41:05 +08:00
MrZ626
331d932c9e 修改设置值域后虚拟按键透明度过低 2020-08-30 00:41:40 +08:00
MrZ626
c28a467529 15p返回按钮 2020-08-30 00:34:51 +08:00
MrZ626
edfe100027 15puzzle 2020-08-29 22:59:24 +08:00
MrZ626
e370cc42ec 场景事件函数全局化,准备场景文件独立 2020-08-29 11:51:27 +08:00
MrZ626
5024851ed2 统一sceneTemp的local变量名 2020-08-29 02:57:09 +08:00
MrZ626
ac5c6ef7b4 修复挖掘模式涨行不刷新ghost 2020-08-29 02:56:01 +08:00
MrZ626
ea1fe0237c 正方形按钮控件省略宽度信息 2020-08-28 11:39:20 +08:00
MrZ626
b9722dcca1 ghost和center透明度可调,部分设置值域改为[0%,100%],控件交互优化,滑条显示当前值 2020-08-27 03:52:13 +08:00
MrZ626
f6ff36c142 控制设置页面预览显示bug 2020-08-27 03:51:27 +08:00
MrZ626
ecf037f27d 0.10.6:CC更新 2020-08-26 00:22:54 +08:00
MrZ626
cf5844a2af O卡住的时候旋转不刷新锁定延迟 2020-08-26 00:22:04 +08:00
MrZ626
b2f8abb884 修改中文的tips 2020-08-26 00:21:24 +08:00
MrZ626
128ab01cf0 cc适配代码调整 2020-08-26 00:21:19 +08:00
MrZ626
a62945a71d cc库文件夹添加进gitignore 2020-08-25 02:24:27 +08:00
MrZ626
9ff8cd3aaa 修改UVRY的踢墙表 2020-08-25 02:21:37 +08:00
MrZ626
b1306ac220 隐形-瞬隐模式强制关闭瞬落/锁定特效 2020-08-25 02:21:32 +08:00
MrZ626
57a89c3859 代码/注释整理 2020-08-25 02:21:26 +08:00
MrZ626
610d953803 修复没开软件锁报错 2020-08-25 02:21:12 +08:00
MrZ626
b788f26f50 修复cc不能用的问题 2020-08-25 02:14:24 +08:00
MrZ626
e5f489fbab 代码整理,修复一个读取问题 2020-08-23 00:16:59 +08:00
MrZ626
4786ab59b0 代码整理 2020-08-23 00:16:30 +08:00
MrZ626
8c7e2da69a 软件锁加新功能和彩蛋 2020-08-23 00:16:04 +08:00
MrZ626
f511aa2f6f 软件锁也可显示tip 2020-08-23 00:15:29 +08:00
MrZ_26
46b119601b Merge pull request #22 from Gompyn/AndroidCC
CC for Android(and Linux)
2020-08-22 15:58:37 +08:00
MrZ_26
d4238da156 Merge pull request #21 from Gompyn/resolve-conflict-with-MrZ626/master
adapt cold-clear 45d5276 and update field when block placement is wrong
2020-08-22 15:55:44 +08:00
MrZ_26
f9cf35f746 输入重置码也可解锁游戏 2020-08-22 02:19:14 +08:00
MrZ_26
94519ba147 0.10.5:特效更新 2020-08-22 02:17:48 +08:00
MrZ_26
e397bdcd12 重构createMoveFX 2020-08-22 02:11:29 +08:00
MrZ_26
e8f0efb22c 代码小调整 2020-08-22 02:04:52 +08:00
MrZ_26
7ecadb0ff1 几个设置大标题样式统一 2020-08-22 01:57:06 +08:00
Gompyn
097129bd08 Merge branch 'master' into resolve-conflict-with-MrZ626/master 2020-08-21 20:36:22 +08:00
MrZ_26
59377efa0c 降低两个马拉松的S评级要求 2020-08-21 17:30:23 +08:00
MrZ_26
4040afbbd9 瞬移特效独立为瞬降和移动(旋转)特效,增加移动特效滑条,各特效范围均为0~5 2020-08-21 00:34:39 +08:00
MrZ_26
d362e1cb54 超高死亡高度改为42 2020-08-21 00:30:47 +08:00
MrZ_26
ff9647bd00 修复垃圾行上涨不刷新ghost 2020-08-21 00:30:09 +08:00
MrZ_26
eb2cff0016 调整各评级颜色 2020-08-19 20:51:19 +08:00
MrZ_26
858f2c673b 暂停界面数据排版微调 2020-08-19 20:50:52 +08:00
MrZ_26
4b9cd0cd06 蓝色更亮一点 2020-08-19 20:50:25 +08:00
MrZ_26
7e2c76bf77 调整JLI的踢墙表 2020-08-19 17:48:17 +08:00
MrZ_26
4b02f3b9ee 复原之前自制蓝屏报错界面 2020-08-19 00:21:26 +08:00
MrZ_26
3f7a09ef71 fan背景完善 2020-08-19 00:06:09 +08:00
MrZ_26
fd580dcadc new English translation by @MattMayuga#8789 2020-08-18 23:06:02 +08:00
MrZ_26
6d64590a12 声音设置页面标题颜色浅了 2020-08-18 21:54:50 +08:00
MrZ_26
e5be25b481 有消行延迟+出块等待时连续硬降出现神秘现象 2020-08-18 21:54:29 +08:00
MrZ_26
7f28278378 挖完后下一波8行会立刻升起 2020-08-18 00:38:50 +08:00
MrZ_26
a7112094f6 加入扇子背景 2020-08-18 00:38:28 +08:00
MrZ_26
37d0a106a9 修复粘贴序列bug,可以用键盘复制粘贴 2020-08-17 17:17:52 +08:00
MrZ_26
731bdab8b2 群号修改 2020-08-17 00:42:36 +08:00
MrZ_26
eabf1242aa wing背景细节调整 2020-08-16 22:47:02 +08:00
MrZ_26
ef857643c8 再微调i踢墙表(顺顺逆式) 2020-08-16 22:28:51 +08:00
MrZ_26
2cf64541f2 支持加载部分老版本存档,软件锁界面出现时机调整,按钮位置调整 2020-08-16 21:01:34 +08:00
MrZ_26
b2ba8a84e9 可交互背景系统试验(给无尽挖掘装上了) 2020-08-16 01:19:46 +08:00
MrZ_26
78e3aa2532 staff添加user670,格式规范 2020-08-16 00:31:33 +08:00
MrZ_26
84e253fd8b 调整混战模式玩家边框颜色影响区域,根据锁延刷新模式决定锁延指示条颜色 2020-08-16 00:31:25 +08:00
MrZ_26
1c4d89c425 雷达图OPM参数改为ADPM 2020-08-15 21:48:04 +08:00
MrZ_26
720e7c6c06 无尽挖掘连挖提示语 2020-08-15 19:46:24 +08:00
MrZ_26
e8902d578a 换字库 2020-08-15 18:15:19 +08:00
MrZ_26
e70b6d3218 微调i的踢墙表 2020-08-15 17:53:12 +08:00
MrZ_26
dded42aeef 整理代码 2020-08-15 17:52:08 +08:00
MrZ_26
6cccf2604c 重命名大多数背景 2020-08-15 17:23:59 +08:00
Gompyn
c72dedf7cf try load CCloaders one by one
it will try all available CCloaders in game.love and go back to 9S
if all CCloaders are not available
2020-08-15 02:37:16 +08:00
MrZ_26
f26888beaa 微调yygq语言 2020-08-14 20:20:57 +08:00
MrZ_26
ce4ba0cefd 每次启动游戏ai是一样的块序 2020-08-14 18:23:12 +08:00
MrZ_26
0885f3bfb3 修改100/400/1000L的评级要求 2020-08-14 17:13:02 +08:00
MrZ_26
becc092192 0.10.4:漏洞修复 2020-08-14 00:25:00 +08:00
MrZ_26
185862eabf 锁延机制错误(重构锁延代码) 2020-08-13 23:59:26 +08:00
MrZ_26
19ce62997b 代码整理 2020-08-13 23:53:07 +08:00
MrZ_26
d8c096b06b 修复拼图模式序列准备错误(改了自定义忘了改这个) 2020-08-13 21:43:05 +08:00
MrZ_26
aa836c7028 修复游戏结束后马上暂停并解除还会自动暂停(之前没修好) 2020-08-13 02:42:03 +08:00
MrZ_26
e5e378fa07 更改减速debug模式速度 2020-08-13 02:33:31 +08:00
MrZ_26
230514e34a 一条tip 2020-08-13 02:33:03 +08:00
MrZ_26
d196d73448 修复提前硬降失效 2020-08-13 02:09:30 +08:00
MrZ_26
cb98a9094a 修复计算器切场景bug 2020-08-12 22:57:43 +08:00
MrZ_26
ec036037fe 0.10.4:漏洞修复 2020-08-12 21:56:02 +08:00
MrZ_26
882769bb71 修改场景模块方法名 2020-08-12 21:45:42 +08:00
MrZ_26
ba43e5e6a7 软件锁变量名修改 2020-08-12 18:47:00 +08:00
MrZ_26
09c56d74bd 代码整理 2020-08-12 18:46:52 +08:00
MrZ_26
c78630a31e linter查出的几个小问题 2020-08-12 18:43:42 +08:00
MrZ_26
d46d111900 0.10.3:软件锁 2020-08-12 00:04:48 +08:00
MrZ_26
87d6e0b501 回放时暂停不打断玩家操作 2020-08-12 00:02:26 +08:00
MrZ_26
45430a6a4a 修复禁断连c4wtrain的成绩为随机(我傻逼) 2020-08-11 23:22:57 +08:00
MrZ_26
7f8a10327b 剩余锁延重置次数指示器改为长方形 2020-08-11 18:28:19 +08:00
MrZ_26
bebe4b96a3 设置添加软件锁,debug界面改为重置界面,进入方法调整 2020-08-11 17:57:57 +08:00
MrZ_26
c1fd22f0b4 场景系统逻辑微调 2020-08-11 00:35:26 +08:00
MrZ_26
0f204e8659 取消按钮喵叫 2020-08-11 00:34:40 +08:00
MrZ_26
9529597a0d 取消"找不到语音"的print 2020-08-11 00:32:19 +08:00
MrZ_26
392ec9abab 加载完毕标记 2020-08-11 00:31:37 +08:00
MrZ_26
d0c7e14f74 "声明"变量 2020-08-11 00:26:44 +08:00
MrZ_26
3cd86472f8 修复回放也计入排行榜 2020-08-10 23:18:21 +08:00
MrZ_26
1e6e3d0d50 时间tip报错 2020-08-10 19:00:25 +08:00
MrZ_26
ed89685925 语音音量设置连续 2020-08-10 01:44:26 +08:00
MrZ_26
971dce6a66 极简提示音量放大 2020-08-10 01:44:00 +08:00
MrZ_26
5de78e924d 取消quickR设置,修改游戏设置布局,增加相关tip 2020-08-10 01:43:39 +08:00
MrZ_26
de0de3a771 修复无尽挖掘报错,小改垃圾行出现代码 2020-08-10 01:37:49 +08:00
MrZ_26
f2cf2ce29b 纠正部分rank文件转换错误,转换老版本lastPlay 2020-08-09 22:02:14 +08:00
MrZ_26
397cdd3e75 文字小改 2020-08-09 18:32:45 +08:00
MrZ_26
5b7dd0cfdd 修改T,F,U,T5的踢墙表 2020-08-09 18:32:38 +08:00
MrZ_26
15b413040d 修复游戏结束后马上暂停并解除还会自动暂停 2020-08-09 14:40:01 +08:00
MrZ_26
e746cf7bb1 死亡预警在两个方向的宽度调整 2020-08-09 14:32:30 +08:00
MrZ_26
e4258dad42 方块生成音设置滑条改为连续 2020-08-09 02:33:34 +08:00
MrZ_26
156a1f92be 自定义序列的问号位置摆正,添加序列/场地重置音效 2020-08-09 02:25:02 +08:00
MrZ_26
77af980255 打错字 2020-08-09 02:21:25 +08:00
MrZ_26
d4cd90cfea 模式文件中改用玩家的随机而非系统随机,便于正确回放 2020-08-09 02:02:43 +08:00
MrZ_26
10c3157ad1 库名改为全大写 2020-08-09 01:31:54 +08:00
MrZ_26
0c3a91fc7c 修复刷新锁延时不刷新落延 2020-08-09 01:31:02 +08:00
MrZ_26
a3ecfeb59a 修复画图切换到custom可返回bug,二者之间切换样式更换 2020-08-09 01:30:53 +08:00
MrZ_26
243fa72f98 文字微调,退出游戏场景时保存数据文件 2020-08-09 01:30:45 +08:00
MrZ_26
67835a722b 0.10.2:锁延修复 2020-08-09 00:31:14 +08:00
MrZ_26
e07287223c 触屏特效修复 2020-08-09 00:08:23 +08:00
MrZ_26
94214abc01 锁延机制再修改(应该不能偷鸡了) 2020-08-09 00:03:34 +08:00
MrZ_26
38d8d73d82 进出debug模式问题 2020-08-08 23:57:28 +08:00
MrZ_26
fd6dfda9c4 更新字体 2020-08-08 23:57:21 +08:00
MrZ_26
7f3edeaacf 将失败换为游戏结束 2020-08-08 23:55:56 +08:00
MrZ_26
8de924cd82 0.10.1:漏洞修复 2020-08-08 16:05:49 +08:00
MrZ_26
3a866bab1f 修改retro皮肤的骨块 2020-08-08 16:05:12 +08:00
MrZ_26
be1b6175b2 回放录像包含设置数据 2020-08-08 15:16:00 +08:00
MrZ_26
8ff5202a1f 控制设置das/arr预览错误 2020-08-08 15:11:03 +08:00
MrZ_26
7867f55610 玩家属性新增minY,y_img更名imgY,修改锁延刷新机制 2020-08-08 02:39:29 +08:00
MrZ_26
9f6a3057f5 玩家act函数addL/R更名zangiL/R 2020-08-08 02:15:48 +08:00
MrZ_26
2424ba692e 调试模式下键盘功能制不完全失效 2020-08-08 01:53:56 +08:00
MrZ_26
0278f13583 旋转中心相对坐标向左下修正负一 2020-08-08 01:46:58 +08:00
MrZ_26
dc5aa83cfb 修复序列生成器 2020-08-08 01:38:46 +08:00
MrZ_26
dd32518ee3 按R重开重置濒死警告 2020-08-08 01:36:31 +08:00
MrZ_26
e9acad55da 光标点击动画 2020-08-06 16:03:50 +08:00
MrZ_26
e7191267be 新皮肤 2020-08-06 02:55:56 +08:00
MrZ_26
018687ad19 均匀音量调节 2020-08-06 02:50:28 +08:00
MrZ_26
8aa40bc200 新tip库 2020-08-06 02:48:31 +08:00
MrZ_26
7224a709b4 音乐微调 2020-08-06 02:47:43 +08:00
MrZ_26
79ccc353a1 删除测试用print,攻击统计误差修复 2020-08-05 01:06:17 +08:00
MrZ_26
139330b4c4 删除用于更新窗口的tickEvent,放在主循环内间隔检测 2020-08-05 01:00:46 +08:00
MrZ_26
0c13f412c4 历史记录页面按钮样式,网格按钮尺寸,增加回放按钮 2020-08-05 01:00:16 +08:00
MrZ_26
b27318eecf 在加载模式时检测是否有非法rank 2020-08-05 00:59:03 +08:00
MrZ_26
d888db9195 仅在开局和退出当前游戏时更新统计 2020-08-05 00:58:43 +08:00
MrZ_26
d7136d0f1c 更好地使用scr变量,debug用print独立,鼠标触发圆形波纹 2020-08-05 00:58:23 +08:00
MrZ_26
31f5875fe2 bgm重新排序 2020-08-05 00:28:20 +08:00
MrZ_26
0437bff488 修复GM模式通关怪异现象 2020-08-04 23:47:07 +08:00
MrZ_26
01154db8fa 换BGM 2020-08-04 23:46:44 +08:00
MrZ_26
31ff756bb1 新语言:yygq 2020-08-04 23:44:23 +08:00
MrZ_26
5d74d980e9 0.10.0:回放更新 2020-08-03 16:45:08 +08:00
MrZ_26
25fe724bf8 整理注释 2020-08-03 16:37:43 +08:00
MrZ_26
8b1e406c42 优化复制场地代码 2020-08-03 16:18:22 +08:00
MrZ_26
6ced348734 新过场动画 2020-08-03 16:15:41 +08:00
MrZ_26
858e320434 彩色自定义序列 2020-08-03 16:13:59 +08:00
MrZ_26
7773fca23a 序列复制粘贴,回放 2020-08-03 16:08:21 +08:00
MrZ_26
5a5c843ed9 简洁按钮 2020-08-03 16:02:37 +08:00
MrZ_26
798f691b4c 统一注释位置 2020-08-03 04:16:54 +08:00
MrZ_26
1cbd9e717a stage显示数字错误 2020-08-03 04:01:24 +08:00
MrZ_26
4b010e29b8 更换极简错误音效 2020-08-03 03:45:48 +08:00
MrZ_26
19ea11ffc2 控件动效优化 2020-08-03 03:45:01 +08:00
MrZ_26
c547095169 20G初心评级调整+清除数据 2020-08-02 18:22:28 +08:00
MrZ_26
edfe626988 倒计时条位置微调 2020-08-02 01:57:33 +08:00
MrZ_26
4fb7d3482a debug菜单重置数据 2020-08-01 22:39:13 +08:00
Gompyn
5342d4f6d6 make CC update field *after* locking 2020-07-31 17:19:36 +08:00
MrZ_26
330396b736 注释首字母大写 2020-07-31 00:35:43 +08:00
MrZ_26
cef926707a 改注释 2020-07-30 23:12:12 +08:00
MrZ_26
ecc88ec360 取消垂直同步 2020-07-30 22:44:35 +08:00
Gompyn
6641d402c0 Fix variable scope 2020-07-30 14:30:17 +08:00
MrZ_26
6b547eed22 100L/400L评级改动 2020-07-30 01:08:54 +08:00
MrZ_26
1545d30edd 更新后跳转 2020-07-30 01:07:45 +08:00
MrZ_26
61277c60dd 玩家掉落动画修复 2020-07-30 00:16:45 +08:00
Gompyn
86ffc4a207 add CC on android (and Linux btw) 2020-07-29 16:04:35 +08:00
Gompyn
71130bbced make cc update field when block placement is wrong 2020-07-29 15:01:38 +08:00
Gompyn
17d670a1ba adapt cold-clear 45d5276 2020-07-29 14:47:49 +08:00
MrZ_26
3260afcac2 帧率控制代码换回之前的 2020-07-29 02:33:40 +08:00
MrZ_26
e5ed78bac8 暂停界面布局微调 2020-07-29 02:32:51 +08:00
MrZ_26
bd619fc4f4 文本修改 2020-07-28 01:36:56 +08:00
MrZ_26
71960756d1 CC刷新场地细节 2020-07-28 01:36:35 +08:00
MrZ_26
3bef016019 0.9.3:性能优化,细节修改 2020-07-27 00:14:57 +08:00
MrZ_26
4bff742b98 0.9.2:全局更新 2020-07-23 22:16:02 +08:00
MrZ_26
b97319afe0 0.9.2:方向键选择控件 2020-07-23 15:12:17 +08:00
MrZ_26
bb2c732529 0.9.2:调试界面,新背景,布局微调 2020-07-23 00:42:47 +08:00
MrZ_26
ae650bd1ff 0.9.2:调试界面,新背景,布局微调 2020-07-21 00:16:15 +08:00
MrZ_26
ee99943ed9 0.9.1:next音效 2020-07-20 00:06:31 +08:00
MrZ_26
60cbc83313 新tips,修复手机旋屏bug,各种调平,统计数据简化 2020-07-19 21:33:03 +08:00
MrZ_26
74bc1a2544 bug修复,水印修改,20G上级调平 2020-07-18 01:05:10 +08:00
MrZ_26
7b35d69be1 允许用键盘编辑序列 2020-07-17 17:37:48 +08:00
MrZ_26
f29fc7081a 0.9.0:自定义序列 2020-07-17 02:08:26 +08:00
MrZ_26
882b841d3f 界面美化/死亡动画/自定义序列编辑器 2020-07-15 23:22:44 +08:00
MrZ_26
3d22f5d8ca 强化水印&系统优化 2020-07-09 19:39:06 +08:00
MrZ_26
a3302ab2bc Zframework finished 2020-07-08 20:26:28 +08:00
MrZ_26
cdd5194108 [change file directory] 2020-07-05 14:56:58 +08:00
MrZ_26
40de030cae [Z-framework stand alone ready] 2020-07-05 14:46:02 +08:00
MrZ_26
e1d92a166b 0.8.24: Bug Fixed 2020-06-14 15:21:20 +08:00
MrZ_26
99b55b72e0 0.8.23: Details Update 2020-06-07 01:06:31 +08:00
MrZ_26
08883b952f 0.8.22:Shader Update 2020-05-28 15:16:38 +08:00
MrZ_26
76fab86692 player generator优化 2020-05-23 00:09:53 +08:00
MrZ_26
725eb4e26f 0.8.22pre1 2020-05-23 00:05:04 +08:00
MrZ_26
486a64cca3 0.8.21: Bug Fixed 2020-05-23 00:04:21 +08:00
FinnTenzor
8e5f6f8b7c 在不影响newXXXPlayer逻辑的情况下调整函数体 为RemotePlayer预留位置 2020-05-21 17:09:39 +08:00
Finn
c0149d5830 Merge pull request #1 from MrZ626/master
0.8.19/20: Fantastic Global Update II
2020-05-21 16:32:44 +08:00
MrZ_26
28d5136e95 0.8.19/20: Fantastic Global Update II 2020-05-21 01:12:17 +08:00
MrZ_26
2768fa748b 0.8.18:Details Update II 2020-05-01 02:33:36 +08:00
MrZ_26
00026bc46b 0.8.17:Details Update 2020-04-30 01:23:11 +08:00
MrZ_26
7d63386410 0.8.16Fantastic Global Update 2020-04-30 01:23:11 +08:00
MrZ_26
e88553bc00 0.8.15Bug Fixed 2020-04-30 01:23:11 +08:00
MrZ_26
4652be7067 0.8.14 2020-04-30 01:23:11 +08:00
MrZ_26
ed0f8031d0 0.8.13 2020-04-30 01:23:11 +08:00
MrZ_26
15df07ae3f 0.8.12 2020-04-30 01:22:06 +08:00
MrZ_26
57857ceb67 0.8.11 2020-02-22 00:47:35 +08:00
MrZ_26
527352ce15 0.8.10 2020-02-20 00:44:51 +08:00
MrZ_26
b8f57f5a1c 0.8.9 2020-02-19 17:41:23 +08:00
MrZ_26
d02048f0dc 0.8.8 2020-02-18 23:05:10 +08:00
MrZ_26
4da080c6f5 0.8.7 2020-02-14 19:26:57 +08:00
MrZ_26
5f62127f28 0.8.6 2020-02-14 00:22:15 +08:00
MrZ_26
f6835c2118 0.8.5- 2020-02-12 23:49:24 +08:00
MrZ_26
3155bc48ef 0.8.4α 2020-02-04 20:33:46 +08:00
MrZ_26
c1b334963b 0.8.3α 2020-02-04 19:41:15 +08:00
MrZ_26
0dbdc9fe42 0.8.2+α 2020-02-04 19:40:51 +08:00
MrZ_26
324435d51a 0.8.2α 2020-02-04 19:40:34 +08:00
MrZ_26
1c384ca51a 0.8.2α 2020-02-04 19:40:21 +08:00
219 changed files with 18725 additions and 9344 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
lib
font.ttf

BIN
BGM/distortion.ogg Normal file

Binary file not shown.

BIN
BGM/far.ogg Normal file

Binary file not shown.

BIN
BGM/how feeling.ogg Normal file

Binary file not shown.

BIN
BGM/oxygen.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SFX/click.ogg Normal file

Binary file not shown.

BIN
SFX/enter.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
SFX/finesseError.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_1.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_2.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_3.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_4.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_5.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_6.ogg Normal file

Binary file not shown.

BIN
SFX/spawn_7.ogg Normal file

Binary file not shown.

BIN
SFX/virtualKey.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
SFX/welcome_sfx.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
VOICE/egg_1.ogg Normal file

Binary file not shown.

BIN
VOICE/egg_2.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
VOICE/nya_happy_4.ogg Normal file

Binary file not shown.

BIN
VOICE/nya_sad_1.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
VOICE/welcome_voc.ogg Normal file

Binary file not shown.

442
Zframework/bg.lua Normal file
View File

@@ -0,0 +1,442 @@
local gc=love.graphics
local int,ceil,rnd,abs=math.floor,math.ceil,math.random,math.abs
local max,min,sin,cos=math.max,math.min,math.sin,math.cos
local ins,rem=table.insert,table.remove
local BG
local scr=scr
local BGvars={_G=_G,SHADER=SHADER}
local back={}
back.none={
draw=function()
gc.clear(.15,.15,.15)
end,
}
back.grey={
draw=function()
gc.clear(.3,.3,.3)
end,
}
back.glow={
init=function()
t=0
end,
update=function(dt)
t=t+dt
end,
draw=function()
local t=(sin(t*.5)+sin(t*.7)+sin(t*.9+1)+sin(t*1.5)+sin(t*2+10))*.08
gc.clear(t,t,t)
end,
}--Light-dark
back.rgb={
init=function()
t=0
end,
update=function(dt)
t=t+dt
end,
draw=function()
gc.clear(
sin(t*1.2)*.15+.2,
sin(t*1.5)*.15+.2,
sin(t*1.9)*.15+.2
)
end,
}--Changing pure color
back.flink={
init=function()
t=0
end,
update=function(dt)
t=t+dt
end,
draw=function()
local t=.13-t%3%1.7
if t<.2 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
end,
}--Flash after random time
local wingColor={
{0., .9, .9,.626},
{.3, 1., .3,.626},
{.9, .9, 0.,.626},
{1., .5, 0.,.626},
{1., .3, .3,.626},
{.5, 0., 1.,.626},
{.3, .3, 1.,.626},
{0., .9, .9,.626},
}
back.wing={
init=function()
gc.setDefaultFilter("linear","linear")
bar=gc.newCanvas(41,1)
gc.push("transform")
gc.origin()
gc.setCanvas(bar)
for x=0,20 do
gc.setColor(1,1,1,x/11)
gc.rectangle("fill",x,0,1,1)
gc.rectangle("fill",41-x,0,1,1)
end
gc.setCanvas()
gc.pop()
BG.resize()
end,
resize=function()
crystal={}
W,H=scr.w,scr.h
for i=1,16 do
crystal[i]={
x=i<9 and W*.05*i or W*.05*(28-i),
y=H*.1,
a=0,
va=0,
f=i<9 and .012-i*.0005 or .012-(17-i)*.0005
}
end
end,
update=function()
for i=1,16 do
local B=crystal[i]
B.a=B.a+B.va
B.va=B.va*.986-B.a*B.f
end
end,
draw=function()
gc.clear(.06,.06,.06)
local sy=H*.8
for i=1,8 do
gc.setColor(wingColor[i])
local B=crystal[i]
gc.draw(bar,B.x,B.y,B.a,1,sy,20,0)
B=crystal[17-i]
gc.draw(bar,B.x,B.y,B.a,1,sy,20,0)
end
end,
event=function(level)
for i=1,8 do
local B=crystal[i]
B.va=B.va+.001*level*(1+rnd())
B=crystal[17-i]
B.va=B.va-.001*level*(1+rnd())
end
end,
discard=function()
bar,crystal=nil
end,
}--Flandre's wing
local _
back.fan={
init=function()
fan=_G.title_fan
t=0
petal={}
BG.resize()
end,
resize=function()
CX,CY=scr.w/2,scr.h/2
W,H=scr.w,scr.h
end,
update=function()
t=t+1
if t%10==0 then
ins(petal,{
x=scr.w*rnd(),
y=0,
vy=2+rnd()*2,
vx=rnd()*2-.5,
rx=4+rnd()*4,
ry=4+rnd()*4,
})
end
for i=#petal,1,-1 do
local P=petal[i]
P.y=P.y+P.vy
if P.y>H then
rem(petal,i)
else
P.x=P.x+P.vx
P.vx=P.vx+rnd()*.01
P.rx=max(min(P.rx+rnd()-.5,10),2)
P.ry=max(min(P.ry+rnd()-.5,10),2)
end
end
end,
draw=function()
gc.push("transform")
gc.translate(CX,CY+20*sin(t*.02))
gc.scale(scr.k)
gc.clear(.1,.1,.1)
gc.setLineWidth(320)
gc.setColor(.3,.2,.3)
gc.arc("line","open",0,420,500,-.8*3.1416,-.2*3.1416)
gc.setLineWidth(4)
gc.setColor(.7,.5,.65)
gc.arc("line","open",0,420,660,-.799*3.1416,-.201*3.1416)
gc.arc("line","open",0,420,340,-.808*3.1416,-.192*3.1416)
gc.line(-281,224,-530,30.5)
gc.line(281,224,530,30.5)
gc.setLineWidth(6)
gc.setColor(.55,.5,.6)
local F=fan
for i=1,8 do
gc.polygon("line",F[i])
end
gc.setLineWidth(2)
gc.setColor(.6,.3,.5)
gc.origin()
for i=1,#petal do
local P=petal[i]
gc.ellipse("fill",P.x,P.y,P.rx,P.ry)
end
gc.pop()
end,
discard=function()
petal=nil
end,
}
back.aura={
init=function()
t=rnd()*3600
BG.resize(scr.w,scr.h)
end,
resize=function(w,h)
SHADER.aura:send("w",scr.W)
SHADER.aura:send("h",h*scr.dpi)
end,
update=function(dt)
t=t+dt
end,
draw=function()
SHADER.aura:send("t",t)
gc.setShader(SHADER.aura)
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.setShader()
end,
}--Cool liquid background
back.bg1={
init=function()
t=0
BG.resize(scr.w)
end,
resize=function(w)
SHADER.gradient1:send("w",scr.W)
end,
update=function(dt)
t=t+dt
end,
draw=function()
SHADER.gradient1:send("t",t)
gc.setShader(SHADER.gradient1)
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.setShader()
end,
}--Horizonal red-blue gradient
back.bg2={
init=function()
t=0
BG.resize(nil,scr.h)
end,
resize=function(w,h)
SHADER.gradient2:send("h",h*scr.dpi)
end,
update=function(dt)
t=t+dt
end,
draw=function()
SHADER.gradient2:send("t",t)
gc.setShader(SHADER.gradient2)
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.setShader()
end,
}--Vertical red-green gradient
back.rainbow={
init=function()
t=0
BG.resize(scr.w,scr.h)
end,
resize=function(w,h)
SHADER.rgb1:send("w",scr.W)
SHADER.rgb1:send("h",h*scr.dpi)
end,
update=function(dt)
t=t+dt
end,
draw=function()
SHADER.rgb1:send("t",t)
gc.setShader(SHADER.rgb1)
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.setShader()
end,
}--Colorful RGB
back.rainbow2={
init=function()
t=0
BG.resize(scr.w,scr.h)
end,
resize=function(w,h)
SHADER.rgb2:send("w",scr.W)
SHADER.rgb2:send("h",h*scr.dpi)
end,
update=function(dt)
t=t+dt
end,
draw=function()
SHADER.rgb2:send("t",t)
gc.setShader(SHADER.rgb2)
gc.rectangle("fill",0,0,scr.w,scr.h)
gc.setShader()
end,
}--Blue RGB
back.lightning={
init=function()
t=0
end,
update=function(dt)
t=t+dt
end,
draw=function()
local t=2.5-t%20%6%2.5
if t<.3 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
end,
}--Lightning
local blocks=require("parts/mino")
local scs=require("parts/spinCenters")
back.lightning2={
init=function()
t=0
colorLib=_G.SKIN.libColor
colorSet=_G.setting.skin
blockImg=_G.TEXTURE.miniBlock
end,
update=function(dt)
t=t+dt
end,
draw=function()
local t=1.2-t%10%3%1.2
if t<.3 then gc.clear(t,t,t)
else gc.clear(0,0,0)
end
local R=7-int(t*.5)%7
local _=colorLib[colorSet[R]]
gc.setColor(_[1],_[2],_[3],.1)
gc.draw(blockImg[R],640,360,t%3.1416*6,400,400,scs[R][0][2]-.5,#blocks[R][0]-scs[R][0][1]+.5)
end,
}--Fast lightning + spining tetromino
local matrixT={}for i=1,50 do matrixT[i]={}for j=1,50 do matrixT[i][j]=love.math.noise(i,j)+2 end end
back.matrix={
init=function()
t=rnd()*3600
end,
update=function(dt)
t=t+dt
end,
draw=function()
gc.scale(scr.k)
gc.clear(.15,.15,.15)
local Y=ceil(scr.H/80)
for x=1,ceil(scr.W/80)do
for y=1,Y do
gc.setColor(1,1,1,sin(x+matrixT[x][y]*t)*.1+.1)
gc.rectangle("fill",80*x,80*y,-80,-80)
end
end
gc.scale(1/scr.k)
end,
}
back.space={
init=function()
stars={}
W,H=scr.w+20,scr.h+20
BG.resize(scr.w,scr.h)
end,
resize=function(w,h)
local S=stars
for i=1,1260,5 do
local s=rnd(26,40)*.1
S[i]=s*scr.k --Size
S[i+1]=rnd(W)-10 --X
S[i+2]=rnd(H)-10 --Y
S[i+3]=(rnd()-.5)*.01*s --Vx
S[i+4]=(rnd()-.5)*.01*s --Vy
end
end,
update=function(dt)
local S=stars
--Star moving
for i=1,1260,5 do
S[i+1]=(S[i+1]+S[i+3])%W
S[i+2]=(S[i+2]+S[i+4])%H
end
end,
draw=function()
gc.clear(.2,.2,.2)
if not stars[1]then return end
gc.translate(-10,-10)
gc.setColor(.8,.8,.8)
for i=1,1260,5 do
local s=stars
local x,y=s[i+1],s[i+2]
s=s[i]
gc.rectangle("fill",x,y,s,s)
end
gc.translate(10,10)
end,
discard=function()
stars=nil
end,
}
--Make BG vars invisible
for _,bg in next,back do
if not bg.init then bg.init= NULL end setfenv(bg.init ,BGvars)
if not bg.resize then bg.resize= NULL end setfenv(bg.resize ,BGvars)
if not bg.update then bg.update= NULL end setfenv(bg.update ,BGvars)
if not bg.draw then bg.draw= NULL end setfenv(bg.draw ,BGvars)
if not bg.event then bg.event= NULL end setfenv(bg.event ,BGvars)
if not bg.discard then bg.discard=NULL end setfenv(bg.discard ,BGvars)
end
BG={
cur="none",
resize=NULL,
update=NULL,
draw=back.none.draw,
}
function BG.send(data)
if BG.event then
BG.event(data)
end
end
function BG.set(bg,data)
if bg==BG.cur or not setting.bg then return end
if BG.discard then
BG.discard()
collectgarbage()
end
BG.cur=bg
bg=back[bg]
BG.init=bg.init or NULL
BG.resize=bg.resize or NULL
BG.update=bg.update or NULL
BG.draw=bg.draw or NULL
BG.event=bg.event or NULL
BG.discard=bg.discard or NULL
BG.init()
end
return BG

93
Zframework/bgm.lua Normal file
View File

@@ -0,0 +1,93 @@
local min=math.min
local rem=table.remove
local function fadeOut(id)
local src=BGM.list[id]
local v=src:getVolume()-.025*setting.bgm
src:setVolume(v>0 and v or 0)
if v<=0 then
src:stop()
return true
end
end
local function fadeIn(id)
local src=BGM.list[id]
local v=setting.bgm
v=min(v,src:getVolume()+.025*v)
src:setVolume(v)
if v>=setting.bgm then return true end
end
local BGM={
--nowPlay=[str:playing ID]
--suspend=[str:pausing ID]
--playing=[src:playing SRC]
}
BGM.list={
"blank",
"race","push","way","reason",
"newera","oxygen","infinite",
"secret7th","secret8th",
"shining terminal","distortion","far",
"rockblock","cruelty","final","8-bit happiness","end",
"how feeling",
}
BGM.len=#BGM.list
function BGM.loadOne(N)
N=BGM.list[N]
local file="/BGM/"..N..".ogg"
if love.filesystem.getInfo(file)then
BGM.list[N]=love.audio.newSource(file,"stream")
BGM.list[N]:setLooping(true)
BGM.list[N]:setVolume(0)
end
end
function BGM.loadAll()
for i=1,#BGM.list do
BGM.loadOne(i)
end
end
function BGM.play(s)
if setting.bgm==0 then
BGM.playing=BGM.list[s]
BGM.suspend,BGM.nowPlay=s
return
elseif not s or not BGM.list[s]then
return
end
if BGM.nowPlay~=s then
if BGM.nowPlay then TASK.new(fadeOut,BGM.nowPlay)end
TASK.changeCode(fadeIn,fadeOut)
TASK.removeTask_data(s)
BGM.nowPlay,BGM.suspend=s
TASK.new(fadeIn,s)
BGM.playing=BGM.list[s]
BGM.playing:play()
end
end
function BGM.freshVolume()
if BGM.playing then
local v=setting.bgm
if v>0 then
BGM.playing:setVolume(v)
if BGM.suspend then
BGM.playing:play()
BGM.nowPlay,BGM.suspend=BGM.suspend
end
else
if BGM.nowPlay then
BGM.playing:pause()
BGM.suspend,BGM.nowPlay=BGM.nowPlay
end
end
end
end
function BGM.stop()
if BGM.nowPlay then
TASK.new(fadeOut,BGM.nowPlay)
end
TASK.changeCode(fadeIn,fadeOut)
BGM.playing,BGM.nowPlay=nil
end
return BGM

38
Zframework/color.lua Normal file
View File

@@ -0,0 +1,38 @@
local color={
red={1,0,0},
green={0,1,0},
blue={.2,.2,1},
yellow={1,1,0},
magenta={1,0,1},
cyan={0,1,1},
grey={.6,.6,.6},
lRed={1,.5,.5},
lGreen={.5,1,.5},
lBlue={.6,.7,1},
lCyan={.5,1,1},
lMagenta={1,.5,1},
lYellow={1,1,.5},
lPurple={.8,.4,1},
lOrange={1,.7,.3},
lGrey={.8,.8,.8},
dRed={.6,0,0},
dGreen={0,.6,0},
dBlue={0,0,.6},
dCyan={0,.6,.6},
dMagenta={.6,0,.6},
dYellow={.6,.6,0},
dPurple={.3,0,.6},
dOrange={.6,.4,0},
dGrey={.3,.3,.3},
black={0,0,0},
orange={1,.6,0},
pink={1,0,.6},
grass={.6,1,0},
water={0,1,.6},
white={1,1,1},
purple={.5,0,1},
}
return color

224
Zframework/file.lua Normal file
View File

@@ -0,0 +1,224 @@
local fs=love.filesystem
local int,max,min=math.floor,math.max,math.min
local sub,find=string.sub,string.find
local toN,toS=tonumber,tostring
local concat=table.concat
local function splitS(s,sep)
local t,n={},1
repeat
local p=find(s,sep)or #s+1
t[n]=sub(s,1,p-1)
n=n+1
s=sub(s,p+#sep)
until #s==0
return t
end
local tabs={
[0]="",
"\t",
"\t\t",
"\t\t\t",
"\t\t\t\t",
"\t\t\t\t\t",
}
local function dumpTable(L,t)
local s
if t then
s="{\n"
else
s="return{\n"
t=1
end
local count=1
for k,v in next,L do
local T=type(k)
if T=="number"then
if k==count then
k="";count=count+1
else
k="["..k.."]="
end
elseif T=="string"then
if find(k,"[^0-9a-zA-Z_]")then
k="[\""..k.."\"]="
else
k=k.."="
end
elseif T=="boolean"then k="["..k.."]="
else assert(false,"Error key type!")
end
T=type(v)
if T=="number"then v=tostring(v)
elseif T=="string"then v="\""..v.."\""
elseif T=="table"then v=dumpTable(v,t+1)
elseif T=="boolean"then v=tostring(v)
else assert(false,"Error data type!")
end
s=s..tabs[t]..k..v..",\n"
end
return s..tabs[t-1].."}"
end
local function addToTable(G,base)--Refresh default base with G-values
for k,v in next,G do
if type(v)==type(base[k])then
if type(v)=="table"then
addToTable(v,base[k])
else
base[k]=v
end
end
end
end
local files={
data= fs.newFile("data.dat"),
setting=fs.newFile("settings.dat"),
VK= fs.newFile("virtualkey.dat"),
keyMap= fs.newFile("key.dat"),
unlock= fs.newFile("unlock.dat"),
}
local FILE={}
function FILE.loadRecord(N)
local F=fs.newFile(N..".dat")
if F:open("r")then
local s=loadstring(F:read())
F:close()
if s then
setfenv(s,{})
return s()
else
return{}
end
end
end
function FILE.saveRecord(N,L)
local F=fs.newFile(N..".dat")
F:open("w")
local _,mes=F:write(dumpTable(L))
F:flush()F:close()
if not _ then
TEXT.show(text.recSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
function FILE.delRecord(N)
fs.remove(N..".dat")
end
function FILE.loadUnlock()
local F=files.unlock
if F:open("r")then
local s=F:read()
if s:sub(1,6)~="return"then s="return{"..s.."}"end
s=loadstring(s)
F:close()
if s then
setfenv(s,{})
modeRanks=s()
end
end
end
function FILE.saveUnlock()
local F=files.unlock
F:open("w")
local _,mes=F:write(dumpTable(modeRanks))
F:flush()F:close()
if not _ then
TEXT.show(text.unlockSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
function FILE.loadData()
local F=files.data
if F:open("r")then
local s=F:read()
if s:sub(1,6)~="return"then
s="return{"..s:gsub("\n",",").."}"
end
s=loadstring(s)
F:close()
if s then
setfenv(s,{})
local S=s()
addToTable(S,stat)
end
end
end
function FILE.saveData()
local F=files.data
F:open("w")
local _,mes=F:write(dumpTable(stat))
F:flush()F:close()
if not _ then
TEXT.show(text.statSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
function FILE.loadSetting()
local F=files.setting
if F:open("r")then
local s=F:read()
if s:sub(1,6)~="return"then
s="return{"..s:gsub("\n",",").."}"
end
s=loadstring(s)
F:close()
if s then
setfenv(s,{})
addToTable(s(),setting)
end
end
end
function FILE.saveSetting()
local F=files.setting
F:open("w")
local _,mes=F:write(dumpTable(setting))
F:flush()F:close()
if _ then TEXT.show(text.settingSaved,1140,650,40,"sudden",.5)
else TEXT.show(text.settingSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
function FILE.loadKeyMap()
local F=files.keyMap
if F:open("r")then
local s=loadstring(F:read())
F:close()
if s then
setfenv(s,{})
addToTable(s(),keyMap)
end
end
end
function FILE.saveKeyMap()
local F=files.keyMap
F:open("w")
local _,mes=F:write(dumpTable(keyMap))
F:flush()F:close()
if _ then TEXT.show(text.keyMapSaved,1140,650,26,"sudden",.5)
else TEXT.show(text.keyMapSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
function FILE.loadVK()
local F=files.VK
if F:open("r")then
local s=loadstring(F:read())
F:close()
if s then
setfenv(s,{})
addToTable(s(),VK_org)
end
end
end
function FILE.saveVK()
local F=files.VK
F:open("w")
local _,mes=F:write(dumpTable(VK_org))
F:flush()F:close()
if _ then TEXT.show(text.VKSaved,1140,650,26,"sudden",.5)
else TEXT.show(text.VKSavingError..(mes or"unknown error"),1140,650,20,"sudden",.5)
end
end
return FILE

41
Zframework/img.lua Normal file
View File

@@ -0,0 +1,41 @@
local IMG={
batteryImage="/mess/power.png",
title="mess/title.png",
title_color="mess/title_colored.png",
dialCircle="mess/dialCircle.png",
dialNeedle="mess/dialNeedle.png",
badgeIcon="mess/badge.png",
spinCenter="mess/spinCenter.png",
ctrlSpeedLimit="mess/ctrlSpeedLimit.png",
speedLimit="mess/speedLimit.png",
pay1="mess/pay1.png",
pay2="mess/pay2.png",
miyaCH="miya/ch.png",
miyaF1="miya/f1.png",
miyaF2="miya/f2.png",
miyaF3="miya/f3.png",
miyaF4="miya/f4.png",
electric="mess/electric.png",
hbm="mess/hbm.png",
}
local list={}
local count=0
for k,v in next,IMG do
count=count+1
list[count]=k
end
function IMG.getCount()
return count
end
function IMG.loadOne(_)
local N=list[_]
IMG[N]=love.graphics.newImage("/image/"..IMG[N])
end
function IMG.loadAll()
for i=1,count do
IMG.loadOne(i)
end
end
return IMG

1434
Zframework/init.lua Normal file

File diff suppressed because it is too large Load Diff

2452
Zframework/languages.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,9 @@
--https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows
local gc=love.graphics
local C=gc.clear
local shadowMapShader=gc.newShader("shadowMapShader.cs")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("lightRenderShader.cs")--Shader for rendering blurred lights and shadows.
Lights={}--Lightsource objects
local Lights=Lights
--Private--
local shadowMapShader=gc.newShader("Zframework/shader/shadowMap.glsl")--Shader for caculating the 1D shadow map.
local lightRenderShader=gc.newShader("Zframework/shader/lightRender.glsl")--Shader for rendering blurred lights and shadows.
local Lights={}--Lightsource objects
local function move(L,x,y)
L.x,L.y=x,y
end
@@ -20,61 +18,72 @@ local function destroy(L)
L.renderCanvas:release()
end
local function draw(L)
--Initialization
local r,g,b,a=love.graphics.getColor()
gc.setCanvas(L.blackCanvas)C()
gc.setCanvas(L.shadowCanvas)C()
gc.setCanvas(L.renderCanvas)C()
lightRenderShader:send("xresolution",L.size);
shadowMapShader:send("yresolution",L.size);
--初始化数据
--Get up-left of light
local X=L.x-L.size*.5
local Y=L.y-L.size*.5
--整束光的左上角
--Render solid
gc.translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn)
gc.translate(X,Y)
--渲染遮光物
--Render shade canvas by solid
gc.setShader(shadowMapShader)
gc.setCanvas(L.shadowCanvas)
gc.draw(L.blackCanvas)
--根据遮光物渲染阴影画布
--Render light canvas by shade
gc.setShader(lightRenderShader)
gc.setCanvas(L.renderCanvas)
gc.draw(L.shadowCanvas,0,0,0,1,L.size)
--根据阴影画布渲染光画布
--Ready to final render
gc.setShader()gc.setCanvas()gc.setBlendMode("add")
--准备渲染
--Render to screes
gc.setColor(r,g,b,a)
gc.draw(L.renderCanvas,X,Y+L.size,0,1,-1)
--渲染到屏幕
--Reset
gc.setBlendMode("alpha")
--复位
end
--Public--
function drawLight()
local LIGHT={}
function LIGHT.draw()
for i=1,#Lights do
Lights[i]:draw()
end
end
function clearLight(L)
for i=1,#Lights do
function LIGHT.clear(L)
for i=#Lights,1,-1 do
Lights[i]:destroy()
Lights[i]=nil
end
end
function addLight(x,y,R,F)
function LIGHT.add(x,y,R,F)
local id=#Lights+1
Lights[id]={
--Methods
id=id,
x=x,y=y,size=R,
blackCanvas=gc.newCanvas(R,R),--遮挡物画布
shadowCanvas=gc.newCanvas(R,1),--1D视深画布
renderCanvas=gc.newCanvas(R,R),--灯光画布
blackFn=F,--遮挡物绘图函数
--方法
blackCanvas=gc.newCanvas(R,R),--Solid canvas
shadowCanvas=gc.newCanvas(R,1),--1D vis-depth canvas
renderCanvas=gc.newCanvas(R,R),--Light canvas
blackFn=F,--Solid draw funcion
move=move,
setPow=setPow,
draw=draw,
destroy=destroy,
}
end
end
return LIGHT

104
Zframework/scene.lua Normal file
View File

@@ -0,0 +1,104 @@
local gc=love.graphics
local abs=math.abs
local scr=scr
sceneInit,sceneBack={},{}
local sceneInit,sceneBack=sceneInit,sceneBack
sceneInit.quit=love.event.quit
local SCN={
cur="load",--Current scene
swapping=false,--If Swapping
stat={
tar=nil, --Swapping target
style=nil, --Swapping style
mid=nil, --Loading point
time=nil, --Full swap time
draw=nil, --Swap draw func
},
seq={"quit","slowFade"},--Back sequence
}--Scene datas, returned
function SCN.swapUpdate()
local S=SCN.stat
S.time=S.time-1
if S.time==S.mid then
SCN.init(S.tar,SCN.cur)
collectgarbage()
--Scene swapped this moment
end
if S.time==0 then
SCN.swapping=false
end
end
function SCN.init(s,org)
if sceneInit[s]then sceneInit[s](org)end
SCN.cur=s
WIDGET.set(Widgets[s])
end
function SCN.push(tar,style)
if not SCN.swapping then
local m=#SCN.seq
SCN.seq[m+1]=tar or SCN.cur
SCN.seq[m+2]=style or"fade"
end
end
function SCN.pop()
local _=SCN.seq
_[#_],_[#_-1]=nil
end
local swap={
none={1,0,NULL},--swap time, change time, draw function
flash={8,1,function()gc.clear(1,1,1)end},
fade={30,15,function(t)
local t=t>15 and 2-t/15 or t/15
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,scr.W,scr.H)
end},
fade_togame={120,20,function(t)
local t=t>20 and(120-t)/100 or t/20
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,scr.W,scr.H)
end},
slowFade={180,90,function(t)
local t=t>90 and 2-t/90 or t/90
gc.setColor(0,0,0,t)
gc.rectangle("fill",0,0,scr.W,scr.H)
end},
swipe={30,15,function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(3-2*t)*2-1
local w=scr.W
gc.rectangle("fill",t*w,0,w,scr.H)
end},
}--Scene swapping animations
function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
local S=SCN.stat
if not SCN.swapping and tar~=SCN.cur then
SCN.swapping=true
if not style then style="fade"end
S.tar=tar
S.style=style
local swap=swap[style]
S.time=swap[1]
S.mid=swap[2]
S.draw=swap[3]
end
end
function SCN.go(tar,style)--Normal scene swapping, can back
SCN.push()SCN.swapTo(tar,style)
end
function SCN.back()
--Leave scene
if sceneBack[SCN.cur] then sceneBack[SCN.cur]()end
--Poll&Back to previous Scene
local m=#SCN.seq
if m>0 then
SCN.swapTo(SCN.seq[m-1],SCN.seq[m])
SCN.seq[m],SCN.seq[m-1]=nil
end
end
return SCN

97
Zframework/sfx.lua Normal file
View File

@@ -0,0 +1,97 @@
local rem=table.remove
local SFX={}
SFX.list={
"welcome_sfx",
"click","enter",
"finesseError","finesseError_long",
--Stereo sfxs(cannot set position)
"virtualKey",
"button","swipe",
"ready","start","win","fail","collect",
"spawn_1","spawn_2","spawn_3","spawn_4","spawn_5","spawn_6","spawn_7",
"move","rotate","rotatekick","hold",
"prerotate","prehold",
"lock","drop","fall",
"reach",
"ren_1","ren_2","ren_3","ren_4","ren_5","ren_6","ren_7","ren_8","ren_9","ren_10","ren_11","ren_mega",
"clear_1","clear_2","clear_3","clear_4",
"spin_0","spin_1","spin_2","spin_3",
"emit","blip_1","blip_2",
"clear",
"error",
--Mono sfxs
}
function SFX.loadOne(_)
_,SFX.list[_]=SFX.list[_]
SFX.list[_]={love.audio.newSource("/SFX/".._..".ogg","static")}
end
function SFX.loadAll()
for i=1,#SFX.list do
SFX.loadOne(i)
end
end
function SFX.fieldPlay(s,v,P)
SFX.play(s,v,(P.curX+P.sc[2]-5.5)*.15)
end
function SFX.play(s,vol,pos)
if setting.sfx==0 then return end
local S=SFX.list[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*setting.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(((vol or 1)*setting.sfx)^1.626)
S:play()
end
function SFX.fplay(s,vol,pos)
local S=SFX.list[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*setting.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(vol^1.626)
S:play()
end
function SFX.reset()
for _,L in next,sfx do
for i=#v,2,-1 do
if not L[i]:isPlaying()then
rem(L,i)
end
end
end
end
return SFX

14
Zframework/shader.lua Normal file
View File

@@ -0,0 +1,14 @@
local function N(file)
return love.graphics.newShader("Zframework/shader/"..file..".glsl")
end
return{
-- glow=gc.newShader("Zframework/shader/glow.cs"),
alpha=N("alpha"),
warning=N("warning"),
aura=N("aura"),
gradient1=N("grad1"),--Horizonal red-blue gradient
gradient2=N("grad2"),--Vertical red-green gradient
rgb1=N("rgb1"),--Colorful RGB
rgb2=N("rgb2"),--Blue RGB
}

View File

@@ -0,0 +1,4 @@
extern float a;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
return vec4(1.,1.,1.,sign(Texel(text,pos).a)*a);
}

View File

@@ -0,0 +1,42 @@
#define PI 3.1415926535897932384626
extern float w,h;
extern float t;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float x=scr_pos.x/w;
float y=scr_pos.y/h;
float dx,dy;
vec3 V=vec3(0.);
dx=0.5+cos(t*3.*0.26)*0.4-x;
dy=0.5-sin(t*3.*0.62)*0.4-y;
dx=sqrt(dx*dx+dy*dy);
V.r=V.r+smoothstep(1.26,0.,dx);
dx=(0.5+cos(t*3.*0.32)*0.4)-x;
dy=(0.5-sin(t*3.*0.80)*0.4)-y;
dx=sqrt(dx*dx+dy*dy);
V.g=V.g+smoothstep(1.26,0.,dx);
dx=(0.5-cos(t*3.*0.49)*0.4)-x;
dy=(0.5+sin(t*3.*0.18)*0.4)-y;
dx=sqrt(dx*dx+dy*dy);
V.b=V.b+smoothstep(1.26,0.,dx);
dx=(0.5+cos(t*0.53)*0.4)-x;
dy=(0.5-sin(t*0.46)*0.4)-y;
dx=sqrt(dx*dx+dy*dy);
V.rg+=vec2(smoothstep(0.626,0.,dx));
dx=(0.5+cos(t*0.98)*0.4)-x;
dy=(0.5+sin(t*0.57)*0.4)-y;
dx=sqrt(dx*dx+dy*dy);
V.rb+=vec2(smoothstep(0.626,0.,dx));
dx=(0.5-cos(t*0.86)*0.4)-x;
dy=(0.5-sin(t*0.32)*0.4)-y;
dx=sqrt(dx*dx+dy*dy);
V.gb+=vec2(smoothstep(0.626,0.,dx));
dx=1.626*max(max(V.r,V.g),V.b);
return vec4(V/dx,1.);
}

View File

@@ -0,0 +1,5 @@
extern float X,Y,W,H;
vec4 effect(vec4 C,Image Tx,vec2 pos,vec2 scr_pos){
C[3]=min((scr_pos.x-X)/W*0.3+(scr_pos.y-Y)/H*0.1,0.3)+0.5;
return C;
}

View File

@@ -0,0 +1,10 @@
extern float t,w;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float x=scr_pos.x/w;
return vec4(
.8-x*.6,
.3+.2*sin(t),
.15+x*.7,
1.
);
}

View File

@@ -0,0 +1,10 @@
extern float t,h;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float y=scr_pos.y/h;
return vec4(
.8-y*.6,
.2+y*.4,
.3+.1*sin(t),
1.
);
}

View File

@@ -0,0 +1,29 @@
#define PI 3.14159
extern float xresolution;
//sample from 1D vis-depth map
float samp(vec2 coord,float r,Image u_texture){
return step(r,Texel(u_texture,coord).r);
}
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
//cartesian to polar, y of 1D sample is always 0
vec2 norm=texture_coords.st*2.-1.;
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
float r=length(norm);
//enlarge blur parameter by distance, light scattering simulation
float blur=(1./xresolution)*smoothstep(0.3,1.,r);
//Simple Gaussian blur
float sum=//brightness(0~1)
samp(vec2(tc.x-3.*blur,tc.y),r,texture)*0.1
+samp(vec2(tc.x-2.*blur,tc.y),r,texture)*0.13
+samp(vec2(tc.x-1.*blur,tc.y),r,texture)*0.17
+samp(tc,r,texture)*0.2//The center tex coord,which gives us hard shadows.
+samp(vec2(tc.x+1.*blur,tc.y),r,texture)*0.17
+samp(vec2(tc.x+2.*blur,tc.y),r,texture)*0.13
+samp(vec2(tc.x+3.*blur,tc.y),r,texture)*0.1;
//Multiply the distance to get a soft fading
return vec4(vec3(1.),sum*smoothstep(1.,0.,r));
}

View File

@@ -0,0 +1,11 @@
extern float t,w,h;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float x=scr_pos.x/w;
float y=scr_pos.y/h;
return vec4(
.8-y*.7+.2*sin(t/6.26),
.2+y*.5+.15*sin(t/4.),
.2+x*.6-.1*sin(t/2.83),
1.
);
}

View File

@@ -0,0 +1,11 @@
extern float t,w,h;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float x=scr_pos.x/w;
float y=scr_pos.y/h;
return vec4(
.4-y*.3-.1*sin(t/6.26),
.2+.1*sin(t),
abs(.7-x*1.2+y*.5*sin(t/16.)),
1.
);
}

View File

@@ -0,0 +1,21 @@
#define PI 3.14
extern float yresolution;
vec4 effect(vec4 color,Image texture,vec2 texture_coords,vec2 screen_coords){
//Iterate through the occluder map's y-axis.
for(float y=0.;y<yresolution;y++){
//cartesian to polar
// y/yresolution=distance to light source(0~1)
vec2 norm=vec2(texture_coords.s,y/yresolution)*2.-1.;
float theta=PI*1.5+norm.x*PI;
float r=(1.+norm.y)*0.5;
//sample from solid
if(
Texel(texture,(
vec2(-r*sin(theta),-r*cos(theta))*0.5+0.5//coord of solid sampling
))
.a>0.1
)return vec4(vec3(y/yresolution),1.);//collision check, alpha>0.1 means transparent
}
return vec4(1.,1.,1.,1.);//return max distance 1
}

View File

@@ -0,0 +1,8 @@
extern float w,h;
extern float level;
vec4 effect(vec4 color,Image text,vec2 pos,vec2 scr_pos){
float dx=abs(scr_pos.x/w-0.5);
float dy=abs(scr_pos.y/h-0.5);
float a=(max(dx*2.6,dy*1.8)-.626)*level;
return vec4(1.,0.,0.,a);
}

165
Zframework/sysFX.lua Normal file
View File

@@ -0,0 +1,165 @@
local gc=love.graphics
local setColor=gc.setColor
local setWidth=gc.setLineWidth
local ins,rem=table.insert,table.remove
local fx={}
local FXupdate={}
function FXupdate.badge(S,dt)
S.t=S.t+dt
if S.t<.2 then
S.x,S.y=S.x1-14,S.y1-14
elseif S.t<.8 then
local t=((S.t-.2)*1.6667)
t=(3-2*t)*t*t
S.x,S.y=S.x1*(1-t)+S.x2*t-14,S.y1*(1-t)+S.y2*t-14
else
S.x,S.y=S.x2-14,S.y2-14
end
return S.t>=1
end
function FXupdate.attack(S,dt)
S.t=S.t+dt
local L=S.drag
if S.t>.8 then
S.rad=S.rad*1.05+.1
S.x,S.y=S.x2,S.y2
elseif S.t>.2 then
local t=(S.t-.2)*1.6667
t=(3-2*t)*t*t
S.x,S.y=S.x1*(1-t)+S.x2*t,S.y1*(1-t)+S.y2*t
ins(L,S.x)ins(L,S.y)
end
if #L==4+4*setting.atkFX then
rem(L,1)rem(L,1)
end
return S.t>1
end
function FXupdate.ripple(S,dt)
S.t=S.t+dt*S.rate
return S.t>=1
end
function FXupdate.rectRipple(S,dt)
S.t=S.t+dt*S.rate
return S.t>=1
end
function FXupdate.shade(S,dt)
S.t=S.t+dt*S.rate
return S.t>=1
end
local FXdraw={}
function FXdraw.badge(S)
gc.setColor(1,1,1,S.t<.2 and S.t*.6 or S.t<.8 and 1 or(1-S.t)*.6)
gc.draw(IMG.badgeIcon,S.x,S.y)
end
function FXdraw.attack(S)
gc.setLineWidth(5)
gc.push("transform")
local t=S.t
local a=(t<.2 and t*5 or t<.8 and 1 or 5-t*5)*S.a
local L=S.drag
local len=#L
local r,g,b=S.r,S.g,S.b
local rad,crn=S.rad,S.corner
for i=1,len,2 do
gc.setColor(r,g,b,.4*a*i/len)
gc.translate(L[i],L[i+1])
gc.rotate(t*.1)
gc.circle("fill",0,0,rad,crn)
gc.rotate(-t*.1)
gc.translate(-L[i],-L[i+1])
end
gc.translate(S.x,S.y)
gc.rotate(t*6)
gc.setColor(r,g,b,a*.5)gc.circle("line",0,0,rad,crn)
gc.setColor(r,g,b,a)gc.circle("fill",0,0,rad,crn)
gc.pop()
end
function FXdraw.ripple(S)
local t=S.t
setWidth(2)
setColor(1,1,1,1-t)
gc.circle("line",S.x,S.y,t*(2-t)*S.r)
end
function FXdraw.rectRipple(S)
setWidth(6)
setColor(1,1,1,1-S.t)
local r=(10*S.t)^1.2
gc.rectangle("line",S.x-r,S.y-r,S.w+2*r,S.h+2*r)
end
function FXdraw.shade(S)
setColor(S.r,S.g,S.b,1-S.t)
gc.rectangle("fill",S.x,S.y,S.w,S.h,2)
end
local sysFX={}
function sysFX.update(dt)
for i=#fx,1,-1 do
if fx[i]:update(dt) then
rem(fx,i)
end
end
end
function sysFX.draw()
for i=1,#fx do
fx[i]:draw()
end
end
function sysFX.newBadge(x1,y1,x2,y2)
fx[#fx+1]={
update=FXupdate.badge,
draw=FXdraw.badge,
t=0,
x=x1,y=y1,
x1=x1,y1=y1,
x2=x2,y2=y2,
}
end
function sysFX.newAttack(x1,y1,x2,y2,rad,corner,type,r,g,b,a)
fx[#fx+1]={
update=FXupdate.attack,
draw=FXdraw.attack,
t=0,
x=x1,y=y1,
x1=x1,y1=y1,--Start pos
x2=x2,y2=y2,--End pos
rad=rad,
corner=corner,
type=type,
r=r,g=g,b=b,a=a,
drag={},--Afterimage coordinate list
}
end
function sysFX.newRipple(duration,x,y,r)
fx[#fx+1]={
update=FXupdate.ripple,
draw=FXdraw.ripple,
t=0,
rate=1/duration,
x=x,y=y,r=r,
}
end
function sysFX.newRectRipple(duration,x,y,w,h)
fx[#fx+1]={
update=FXupdate.rectRipple,
draw=FXdraw.rectRipple,
t=0,
rate=1/duration,
x=x,y=y,w=w,h=h,
}
end
function sysFX.newShade(duration,r,g,b,x,y,w,h)
fx[#fx+1]={
update=FXupdate.shade,
draw=FXdraw.shade,
t=0,
rate=1/duration,
r=r,g=g,b=b,
x=x,y=y,w=w,h=h,
}
end
return sysFX

58
Zframework/task.lua Normal file
View File

@@ -0,0 +1,58 @@
local rem=table.remove
local tasks={}
local TASK={}
function TASK.getCount()
return #tasks
end
function TASK.update()
for i=#tasks,1,-1 do
local T=tasks[i]
if T.code(T.data)then
rem(tasks,i)
end
end
end
function TASK.new(code,data)
tasks[#tasks+1]={
code=code,
data=data,
}
end
function TASK.changeCode(c1,c2)
for i=#tasks,1,-1 do
if tasks[i].code==c1 then
tasks[i].code=c2
end
end
end
function TASK.removeTask_code(code)
for i=#tasks,1,-1 do
if tasks[i].code==code then
rem(tasks,i)
end
end
end
function TASK.removeTask_data(data)
for i=#tasks,1,-1 do
if tasks[i].data==data then
rem(tasks,i)
end
end
end
function TASK.clear(opt)
if opt=="all"then
local i=#tasks
while i>0 do
tasks[i]=nil
i=i-1
end
else--Player table
for i=#tasks,1,-1 do
if tasks[i].P==opt then
rem(tasks,i)
end
end
end
end
return TASK

View File

@@ -3,10 +3,16 @@ local rnd=math.random
local mStr=mStr
local rem=table.remove
local texts={}
local textFX={}
function textFX.appear(t)
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.sudden(t)
gc.setColor(1,1,1,1-t.c)
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.fly(t)
mStr(t.text,t.x+(t.c-.5)^3*300,t.y-t.font*.7)
end
@@ -29,13 +35,15 @@ function textFX.spin(t)
gc.translate(t.x,t.y)
if t.c<.3 then
gc.rotate((.3-t.c)^2*4)
elseif t.c>.8 then
gc.rotate((t.c-.8)^2*-4)
end
mStr(t.text,0,-t.font*.7)
gc.pop()
end
function textFX.flicker(t)
local _,τ,T,Τ=gc.getColor()
gc.setColor(_,τ,T,Τ*(rnd()+.5))
local _,_,_,T=gc.getColor()
gc.setColor(1,1,1,T*(rnd()+.5))
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.zoomout(t)
@@ -56,7 +64,17 @@ function textFX.beat(t)
mStr(t.text,0,-t.font*.7)
gc.pop()
end
function getTEXT(text,x,y,font,style,spd,stop)
function textFX.mark(t)
local _,_,_,T=gc.getColor()
gc.setColor(1,1,1,T*.08)
mStr(t.text,t.x,t.y-t.font*.7)
end
local TEXT={}
function TEXT.clear()
texts={}
end
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT()
return{
c=0,
text=text,
@@ -65,22 +83,23 @@ function getTEXT(text,x,y,font,style,spd,stop)
font=font or 40,
spd=(spd or 1)/60,
stop=stop,
draw=textFX[style]or error("unavailable type:"..style),
}
end--another version of TEXT()
function TEXT(text,x,y,font,style,spd,stop)
texts[#texts+1]={
c=0, --timer
text=text, --string
x=x or 0, --x
y=y or 0, --y
font=font or 40, --font
spd=(spd or 1)/60, --timing speed(1=last 1 sec)
stop=stop, --stop time(sustained text)
draw=textFX[style]or error("unavailable type:"..style), --draw method
draw=textFX[style]or assert(false,"unavailable type:"..style),
}
end
function updateText(list)
function TEXT.show(text,x,y,font,style,spd,stop)
texts[#texts+1]={
c=0, --Timer
text=text, --String
x=x or 0, --X
y=y or 0, --Y
font=font or 40, --Font
spd=(spd or 1)/60, --Timing speed(1=last 1 sec)
stop=stop, --Stop time(sustained text)
draw=textFX[style]or assert(false,"unavailable type:"..style), --Draw method
}
end
function TEXT.update(list)
if not list then list=texts end
for i=#list,1,-1 do
local t=list[i]
t.c=t.c+t.spd
@@ -89,12 +108,13 @@ function updateText(list)
t.c=t.stop
end
end
if t.c>60 then
if t.c>1 then
rem(list,i)
end
end
end
function drawTexts(list)
function TEXT.draw(list)
if not list then list=texts end
for i=1,#list do
local t=list[i]
local p=t.c
@@ -102,4 +122,5 @@ function drawTexts(list)
setFont(t.font)
t:draw()
end
end
end
return TEXT

42
Zframework/toolfunc.lua Normal file
View File

@@ -0,0 +1,42 @@
local gc=love.graphics
local int=math.floor
local format=string.format
local fontData=love.filesystem.newFile("font.ttf")
local newFont=gc.setNewFont
local setNewFont=gc.setFont
local fontCache,currentFontSize={}
function setFont(s)
local f=fontCache[s]
if s~=currentFontSize then
if f then
setNewFont(f)
else
f=newFont(fontData,s)
fontCache[s]=f
setNewFont(f)
end
currentFontSize=s
end
return f
end
function toTime(s)
if s<60 then
return format("%.3fs",s)
elseif s<3600 then
return format("%d:%.2f",int(s/60),s%60)
else
local h=int(s/3600)
return format("%d:%d:%.2f",h,int(s/60%60),s%60)
end
end
function mStr(s,x,y)
gc.printf(s,x-450,y,900,"center")
end
function mText(s,x,y)
gc.draw(s,x-s:getWidth()*.5,y)
end
function mDraw(s,x,y,a,k)
gc.draw(s,x,y,a,k,nil,s:getWidth()*.5,s:getHeight()*.5)
end

8
Zframework/vib.lua Normal file
View File

@@ -0,0 +1,8 @@
local level={0,0,.015,.02,.03,.04,.05,.06,.07,.08}
local _=love.system.vibrate
return function(t)
local L=setting.vib
if L>0 then
_(level[L+t])
end
end

134
Zframework/voice.lua Normal file
View File

@@ -0,0 +1,134 @@
local rnd=math.random
local rem=table.remove
local voiceQueue={free=0}
local bank={}--{{SRC1s},{SRC2s},...}
local VOC={}
VOC.name={
"zspin","sspin","lspin","jspin","tspin","ospin","ispin",
"single","double","triple","techrash",
"mini","b2b","b3b","pc",
"win","lose",
"bye",
"nya",
"happy",
"doubt",
"sad",
"egg",
"welcome"
}
VOC.list={
zspin={"zspin_1","zspin_2","zspin_3"},
sspin={"sspin_1","sspin_2","sspin_3","sspin_4","sspin_5","sspin_6"},
lspin={"lspin_1","lspin_2"},
jspin={"jspin_1","jspin_2","jspin_3","jspin_4"},
tspin={"tspin_1","tspin_2","tspin_3","tspin_4","tspin_5","tspin_6"},
ospin={"ospin_1","ospin_2","ospin_3"},
ispin={"ispin_1","ispin_2","ispin_3"},
single={"single_1","single_2","single_3","single_4","single_5","single_6","single_7"},
double={"double_1","double_2","double_3","double_4","double_5"},
triple={"triple_1","triple_2","triple_3","triple_4","triple_5","triple_6","triple_7"},
techrash={"techrash_1","techrash_2","techrash_3","techrash_4"},
mini={"mini_1","mini_2","mini_3"},
b2b={"b2b_1","b2b_2","b2b_3"},
b3b={"b3b_1","b3b_2"},
pc={"clear_1","clear_2"},
win={"win_1","win_2","win_3","win_4","win_5","win_6","win_6","win_7"},
lose={"lose_1","lose_2","lose_3"},
bye={"bye_1","bye_2"},
nya={"nya_1","nya_2","nya_3","nya_4"},
happy={"nya_happy_1","nya_happy_2","nya_happy_3","nya_happy_4"},
doubt={"nya_doubt_1","nya_doubt_2"},
sad={"nya_sad_1"},
egg={"egg_1","egg_2"},
welcome={"welcome_voc"},
}
local function getVoice(str)
local L=bank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then
L[n]=L[1]:clone()
L[n]:seek(0)
break
end
end
return L[n]
--Load voice with string
end
function VOC.loadOne(_)
local N=VOC.name[_]
for i=1,#VOC.list[N]do
local V=VOC.list[N][i]
bank[V]={love.audio.newSource("VOICE/"..V..".ogg","static")}
end
end
function VOC.loadAll()
for i=1,#VOC.list do
VOC.loadOne(i)
end
end
function VOC.getFreeChannel()
local i=#voiceQueue
for i=1,i do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[i+1]={s=0}
return i+1
end
function VOC.getCount()
return #voiceQueue
end
function VOC.update()
for i=#voiceQueue,1,-1 do
local Q=voiceQueue[i]
if Q.s==0 then--Free channel, auto delete when >3
if i>3 then
rem(voiceQueue,i)
end
elseif Q.s==1 then--Waiting load source
Q[1]=getVoice(Q[1])
Q[1]:setVolume(setting.voc)
Q[1]:play()
Q.s=Q[2]and 2 or 4
elseif Q.s==2 then--Playing 1,ready 2
if Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=getVoice(Q[2])
Q[2]:setVolume(setting.voc)
Q[2]:play()
Q.s=3
end
elseif Q.s==3 then--Playing 12 same time
if not Q[1]:isPlaying()then
for i=1,#Q do
Q[i]=Q[i+1]
end
Q.s=Q[2]and 2 or 4
end
elseif Q.s==4 then--Playing last
if not Q[1].isPlaying(Q[1])then
Q[1]=nil
Q.s=0
end
end
end
end
function VOC.play(s,chn)
if setting.voc>0 then
if chn then
local L=voiceQueue[chn]
local _=VOC.list[s]
if not _ then return end
L[#L+1]=_[rnd(#_)]
L.s=1
--Add to queue[chn]
else
voiceQueue[VOC.getFreeChannel()]={s=1,VOC.list[s][rnd(#VOC.list[s])]}
--Create new channel & play
end
end
end
return VOC

599
Zframework/widget.lua Normal file
View File

@@ -0,0 +1,599 @@
local gc=love.graphics
local kb=love.keyboard
local int,abs=math.floor,math.abs
local format=string.format
local color=color
local setFont=setFont
local Timer=love.timer.getTime
local button={
type="button",
ATV=0,--Activating time(0~8)
}
function button:reset()
self.ATV=0
end
function button:isAbove(x,y)
local ATV=self.ATV
return
x>self.x-ATV and
y>self.y-ATV and
x<self.x+self.w+2*ATV and
y<self.y+self.h+2*ATV
end
function button:getCenter()
return self.x+self.w*.5,self.y+self.h*.5
end
function button:FX()
local ATV=self.ATV
sysFX.newRectRipple(
.16,
self.x-ATV,
self.y-ATV,
self.w+2*ATV,
self.h+2*ATV
,5
)
end
function button:update()
local ATV=self.ATV
if WIDGET.sel==self then
if ATV<8 then self.ATV=ATV+1 end
else
if ATV>0 then self.ATV=ATV-.5 end
end
end
function button:draw()
local x,y,w,h=self.x,self.y,self.w,self.h
local ATV=self.ATV
local r,g,b=unpack(self.color)
gc.setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
gc.rectangle("fill",x-ATV,y-ATV,w+2*ATV,h+2*ATV)
if ATV>0 then
gc.setLineWidth(4)
gc.setColor(1,1,1,ATV*.125)
gc.rectangle("line",x-ATV+2,y-ATV+2,w+2*ATV-4,h+2*ATV-4)
end
local t=self.text
if t then
if type(t)=="function"then t=t()end
setFont(self.font)
local y0=y+h*.5-self.font*.7-ATV*.5
gc.setColor(1,1,1,.2+ATV*.05)
gc.printf(t,x-2,y0-2,w,"center")
gc.printf(t,x-2,y0+2,w,"center")
gc.printf(t,x+2,y0-2,w,"center")
gc.printf(t,x+2,y0+2,w,"center")
gc.setColor(r*.5,g*.5,b*.5)
gc.printf(t,x,y0,w,"center")
end
end
function button:getInfo()
DBP(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font))
end
local key={
type="key",
ATV=0,--Activating time(0~4)
}
function key:reset()
self.ATV=0
end
function key:isAbove(x,y)
local ATV=self.ATV
return
x>self.x and
y>self.y and
x<self.x+self.w and
y<self.y+self.h
end
function key:getCenter()
return self.x+self.w*.5,self.y+self.h*.5
end
function key:update()
local ATV=self.ATV
if WIDGET.sel==self then
if ATV<4 then self.ATV=ATV+1 end
else
if ATV>0 then self.ATV=ATV-.5 end
end
end
function key:draw()
local x,y,w,h=self.x,self.y,self.w,self.h
local ATV=self.ATV
local r,g,b=unpack(self.color)
gc.setColor(1,1,1,ATV*.125)
gc.rectangle("fill",x,y,w,h)
gc.setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
gc.setLineWidth(4)
gc.rectangle("line",x,y,w,h)
local t=self.text
if t then
if type(t)=="function"then t=t()end
setFont(self.font)
gc.setColor(r,g,b,1.2)
gc.printf(t,x,y+h*.5-self.font*.7,w,"center")
end
end
function key:getInfo()
DBP(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font))
end
local switch={
type="switch",
ATV=0,--Activating time(0~8)
CHK=0,--Check alpha(0~6)
}
function switch:reset()
self.ATV=0
self.CHK=0
end
function switch:isAbove(x,y)
return x>self.x and x<self.x+50 and y>self.y-25 and y<self.y+25
end
function switch:getCenter()
return self.x,self.y
end
function switch:update()
local _=self.ATV
if WIDGET.sel==self then if _<8 then self.ATV=_+1 end
else if _>0 then self.ATV=_-.5 end
end
_=self.CHK
if self:disp()then if _<6 then self.CHK=_+1 end
else if _>0 then self.CHK=_-1 end
end
end
function switch:draw()
local x,y=self.x,self.y-25
local ATV=self.ATV
--Checked
if ATV>0 then
gc.setColor(1,1,1,ATV*.08)
gc.rectangle("fill",x,y,50,50)
end
if self.CHK>0 then
gc.setColor(.9,1,.9,self.CHK/6)
gc.setLineWidth(6)
gc.line(x+5,y+25,x+18,y+38,x+45,y+11)
end
--Frame
gc.setLineWidth(4)
gc.setColor(1,1,1,.6+ATV*.05)
gc.rectangle("line",x,y,50,50)
--Text
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,x-412-ATV,y+20-self.font*.7,400,"right")
end
end
function switch:getInfo()
DBP(format("x=%d,y=%d,font=%d",self.x,self.y,self.font))
end
local slider={
type="slider",
ATV=0,--Activating time(0~8)
pos=0,--Position shown
}
local sliderShowFunc={
int=function(S)
return S.disp()
end,
float=function(S)
return int(S.disp()*100)*.01
end,
percent=function(S)
return int(S.disp()*100).."%"
end,
frame_time=function(S)
S=S.disp()
return S.."F "..int(S*16.67).."ms"
end,
}
function slider:reset()
self.ATV=0
self.pos=0
end
function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end
function slider:getCenter()
return self.x+self.w*(self.pos/self.unit),self.y
end
function slider:update()
local _=self.ATV
if WIDGET.sel==self then
if _<6 then self.ATV=_+1 end
else
if _>0 then self.ATV=_-.5 end
end
if not(self.hide and self.hide())then
self.pos=self.pos*.7+self.disp()*.3
end
end
function slider:draw()
local x,y=self.x,self.y
local ATV=self.ATV
local x2=x+self.w
gc.setColor(1,1,1,.5+ATV*.06)
--Units
if not self.smooth then
gc.setLineWidth(2)
for p=0,self.unit do
local x=x+(x2-x)*p/self.unit
gc.line(x,y+7,x,y-7)
end
end
--Axis
gc.setLineWidth(4)
gc.line(x,y,x2,y)
--Block
local cx=x+(x2-x)*self.pos/self.unit
local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV
gc.setColor(.8,.8,.8)
gc.rectangle("fill",bx,by,bw,bh)
local t
if ATV>0 then
gc.setLineWidth(2)
gc.setColor(1,1,1,ATV*.16)
gc.rectangle("line",bx+1,by+1,bw-2,bh-2)
if self.show then
setFont(25)
mStr(self:show(),cx,by-30)
end
end
--Text
t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,x-312-ATV,y-self.font*.7,300,"right")
end
end
function slider:getInfo()
DBP(format("x=%d,y=%d,w=%d",self.x,self.y,self.w))
end
local WIDGET={}
WIDGET.active={}--Table, contains all active widgets
WIDGET.sel=nil--Selected widget
function WIDGET.set(L)
WIDGET.sel=nil
WIDGET.active=L or{}
--Reset all widgets
if L then
for _,W in next,L do
W:reset()
end
end
end
WIDGET.new={}
function WIDGET.newText(D)
local _={
name= D.name,
x= D.x,
y= D.y,
align= D.align,
color= color[D.color]or D.color,
font= D.font,
hide= D.hide,
}for k,v in next,button do _[k]=v end return _
end
function WIDGET.newImage(D)
local _={
name= D.name,
x= D.x-w*.5,
y= D.y-h*.5,
w= D.w,
h= D.h,
color= color[D.color]or D.color,
font= D.font,
code= D.code,
hide= D.hide,
}for k,v in next,button do _[k]=v end return _
end
function WIDGET.newButton(D)
if not D.h then D.h=D.w end
local _={
name= D.name,
x= D.x-D.w*.5,
y= D.y-D.h*.5,
w= D.w,
h= D.h,
resCtr={
D.x,D.y,
D.x-D.w*.35,D.y-D.h*.35,
D.x-D.w*.35,D.y+D.h*.35,
D.x+D.w*.35,D.y-D.h*.35,
D.x+D.w*.35,D.y+D.h*.35,
},
color= color[D.color]or D.color,
font= D.font,
code= D.code,
hide= D.hide,
}for k,v in next,button do _[k]=v end return _
end
function WIDGET.newKey(D)
if not D.h then D.h=D.w end
local _={
name= D.name,
x= D.x-D.w*.5,
y= D.y-D.h*.5,
w= D.w,
h= D.h,
resCtr={
D.x,D.y,
D.x-D.w*.35,D.y-D.h*.35,
D.x-D.w*.35,D.y+D.h*.35,
D.x+D.w*.35,D.y-D.h*.35,
D.x+D.w*.35,D.y+D.h*.35,
},
color= color[D.color]or D.color,
font= D.font,
code= D.code,
hide= D.hide,
}for k,v in next,key do _[k]=v end return _
end
function WIDGET.newSwitch(D)
local _={
name= D.name,
x= D.x,
y= D.y,
cx= D.x+25,
cy= D.y,
resCtr={
D.x+25,D.y,
},
font= D.font,
disp= D.disp,
code= D.code,
hide= D.hide,
}for k,v in next,switch do _[k]=v end return _
end
function WIDGET.newSlider(D)
local _={
name= D.name,
x= D.x,
y= D.y,
w= D.w,
cx= D.x+D.w*.5,
cy= D.y,
resCtr={
D.x,D.y,
D.x+D.w*.25,D.y,
D.x+D.w*.5,D.y,
D.x+D.w*.75,D.y,
D.x+D.w,D.y,
},
unit= D.unit or 1,
--smooth=nil,
font= D.font,
change= D.change,
disp= D.disp,
code= D.code,
hide= D.hide,
--show= nil,
lastTime=0,
}
if D.smooth~=nil then
_.smooth=D.smooth
else
_.smooth=_.unit<=1
end
if D.show then
if type(D.show)=="function"then
_.show=D.show
else
_.show=sliderShowFunc[D.show]
end
elseif _.unit<=1 then
_.show=sliderShowFunc.percent
else
_.show=sliderShowFunc.int
end
for k,v in next,slider do _[k]=v end return _
end
function WIDGET.moveCursor(x,y)
WIDGET.sel=nil
for _,W in next,WIDGET.active do
if not(W.hide and W.hide())and W:isAbove(x,y)then
WIDGET.sel=W
return
end
end
end
function WIDGET.press(x,y)
local W=WIDGET.sel
if not W then return end
if W.type=="button"then
W.code()
W:FX()
SFX.play("button")
elseif W.type=="key"then
W.code()
SFX.play("lock")
elseif W.type=="switch"then
W.code()
SFX.play("move",.6)
elseif W.type=="slider"then
WIDGET.drag(x,y)
end
if W.hide and W.hide()then WIDGET.sel=nil end
end
function WIDGET.drag(x,y,dx,dy)
local W=WIDGET.sel
if not W then return end
if W.type=="slider"then
if not x then return end
local p=W.disp()
local P=x<W.x and 0 or x>W.x+W.w and W.unit or(x-W.x)/W.w*W.unit
if not W.smooth then
P=int(P+.5)
end
if p~=P then
W.code(P)
end
if W.change and Timer()-W.lastTime>.18 then
W.lastTime=Timer()
W.change()
end
elseif not W:isAbove(x,y)then
WIDGET.sel=nil
end
end
function WIDGET.release(x,y)
local W=WIDGET.sel
if not W then return end
if W.type=="slider"then
W.lastTime=0
WIDGET.drag(x,y)
end
WIDGET.sel=nil
end
function WIDGET.keyPressed(i)
if i=="space"or i=="return"then
if WIDGET.sel then
WIDGET.press()
end
elseif kb.isDown("lshift","lalt","lctrl")then
--When hold [↑], control slider with left/right
if i=="left"or i=="right"then
local W=WIDGET.sel
if W then
if W.type=="slider"then
local p=W.disp()
local P=i=="left"and(p>0 and p-1)or p<W.unit and p+1
if p==P or not P then return end
W.code(P)
if W.change then W.change()end
end
end
end
elseif i=="up"or i=="down"or i=="left"or i=="right"then
if WIDGET.sel then
local W=WIDGET.sel
local WX,WY=W:getCenter()
local dir=(i=="right"or i=="down")and 1 or -1
local tar
local minDist=1e99
if i=="left"or i=="right"then
for i=1,#WIDGET.active do
local W1=WIDGET.active[i]
if W~=W1 and W1.resCtr then
local L=W1.resCtr
for j=1,#L,2 do
local x,y=L[j],L[j+1]
local dist=(x-WX)*dir
if dist>10 then
dist=dist+abs(y-WY)*6.26
if dist<minDist then
minDist=dist
tar=W1
end
end
end
end
end
else
for i=1,#WIDGET.active do
local W1=WIDGET.active[i]
if W~=W1 and W1.resCtr then
local L=W1.resCtr
for j=1,#L,2 do
local x,y=L[j],L[j+1]
local dist=(y-WY)*dir
if dist>10 then
dist=dist+abs(x-WX)*6.26
if dist<minDist then
minDist=dist
tar=W1
end
end
end
end
end
end
if tar then
WIDGET.sel=tar
end
else
WIDGET.sel=WIDGET.active[1]
end
end
end
local keyMirror={
dpup="up",
dpdown="down",
dpleft="left",
dpright="right",
start="return",
back="escape",
}
function WIDGET.gamepadPressed(i)
if i=="start"then
if WIDGET.sel then
WIDGET.press()
end
elseif i=="a"or i=="b"then
local W=WIDGET.sel
if W then
if W.type=="button"or W.type=="key"then
WIDGET.press()
elseif W.type=="slider"then
local p=W.disp()
local P=i=="left"and(p>0 and p-1)or p<W.unit and p+1
if p==P or not P then return end
W.code(P)
if W.change then W.change()end
end
end
elseif i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
WIDGET.keyPressed(keyMirror[i])
end
end
function WIDGET.update()
for _,W in next,WIDGET.active do
W:update()
end
end
function WIDGET.draw()
for _,W in next,WIDGET.active do
if not(W.hide and W.hide())then
W:draw()
end
end
end
return WIDGET

543
Zframework/widgetList.lua Normal file
View File

@@ -0,0 +1,543 @@
local rnd=math.random
local ins,rem=table.insert,table.remove
local mobileHide=(system=="Android"or system=="iOS")and function()return true end
local function BACK()SCN.back()end
local virtualkeySet={
{
{1, 80, 720-200, 80},--moveLeft
{2, 320, 720-200, 80},--moveRight
{3, 1280-80, 720-200, 80},--rotRight
{4, 1280-200, 720-80, 80},--rotLeft
{5, 1280-200, 720-320, 80},--rot180
{6, 200, 720-320, 80},--hardDrop
{7, 200, 720-80, 80},--softDrop
{8, 1280-320, 720-200, 80},--hold
{9, 1280-80, 280, 80},--func
{10,80, 280, 80},--restart
},--Farter's set,thanks
{
{1, 1280-320, 720-200, 80},--moveLeft
{2, 1280-80, 720-200, 80},--moveRight
{3, 200, 720-80, 80},--rotRight
{4, 80, 720-200, 80},--rotLeft
{5, 200, 720-320, 80},--rot180
{6, 1280-200, 720-320, 80},--hardDrop
{7, 1280-200, 720-80, 80},--softDrop
{8, 320, 720-200, 80},--hold
{9, 80, 280, 80},--func
{10,1280-80, 280, 80},--restart
},--Mirrored farter's set,sknaht
{
{1, 80, 720-80, 80},--moveLeft
{2, 240, 720-80, 80},--moveRight
{3, 1280-240, 720-80, 80},--rotRight
{4, 1280-400, 720-80, 80},--rotLeft
{5, 1280-240, 720-240, 80},--rot180
{6, 1280-80, 720-80, 80},--hardDrop
{7, 1280-80, 720-240, 80},--softDrop
{8, 1280-80, 720-400, 80},--hold
{9, 80, 360, 80},--func
{10,80, 80, 80},--restart
},--Author's set,not recommend
{
{1, 1280-400, 720-80, 80},--moveLeft
{2, 1280-80, 720-80, 80},--moveRight
{3, 240, 720-80, 80},--rotRight
{4, 80, 720-80, 80},--rotLeft
{5, 240, 720-240, 80},--rot180
{6, 1280-240, 720-240, 80},--hardDrop
{7, 1280-240, 720-80, 80},--softDrop
{8, 1280-80, 720-240, 80},--hold
{9, 80, 720-240, 80},--func
{10,80, 320, 80},--restart
},--Keyboard set
{
{10,70, 50,30},--restart
{9, 130, 50,30},--func
{4, 190, 50,30},--rotLeft
{3, 250, 50,30},--rotRight
{5, 310, 50,30},--rot180
{1, 370, 50,30},--moveLeft
{2, 430, 50,30},--moveRight
{8, 490, 50,30},--hold
{7, 550, 50,30},--softDrop1
{6, 610, 50,30},--hardDrop
{11,670, 50,30},--insLeft
{12,730, 50,30},--insRight
{13,790, 50,30},--insDown
{14,850, 50,30},--down1
{15,910, 50,30},--down4
{16,970, 50,30},--down10
{17,1030, 50,30},--dropLeft
{18,1090, 50,30},--dropRight
{19,1150, 50,30},--zangiLeft
{20,1210, 50,30},--zangiRight
},--PC key feedback(top&in a row)
}
--Lambda Funcs for widgets,delete at file end
local function SETval(k) return function()return setting[k] end end
local function SETsto(k) return function(i)setting[k]=i end end
local function SETrev(k) return function()setting[k]=not setting[k] end end
local function pressKey(k) return function()love.keypressed(k) end end
local function setPen(i) return function()sceneTemp.pen=i end end
local function prevSkin(n) return function()SKIN.prev(n) end end
local function nextSkin(n) return function()SKIN.next(n) end end
local function nextDir(n) return function()SKIN.rotate(n) end end
local function VKAdisp(n) return function()return VK_org[n].ava end end
local function VKAcode(n) return function()VK_org[n].ava=not VK_org[n].ava end end
local function setLang(n) return function()LANG.set(n)setting.lang=n end end
--NewXXX
newText=WIDGET.newText
newImage=WIDGET.newImage
newButton=WIDGET.newButton
newKey=WIDGET.newKey
newSwitch=WIDGET.newSwitch
newSlider=WIDGET.newSlider
--All widgets
local Widgets={
load={},intro={},quit={},
calculator={
newKey({name="_1", x=150,y=300,w=90, color="white", font=50,code=pressKey("1")}),
newKey({name="_2", x=250,y=300,w=90, color="white", font=50,code=pressKey("2")}),
newKey({name="_3", x=350,y=300,w=90, color="white", font=50,code=pressKey("3")}),
newKey({name="_4", x=150,y=400,w=90, color="white", font=50,code=pressKey("4")}),
newKey({name="_5", x=250,y=400,w=90, color="white", font=50,code=pressKey("5")}),
newKey({name="_6", x=350,y=400,w=90, color="white", font=50,code=pressKey("6")}),
newKey({name="_7", x=150,y=500,w=90, color="white", font=50,code=pressKey("7")}),
newKey({name="_8", x=250,y=500,w=90, color="white", font=50,code=pressKey("8")}),
newKey({name="_9", x=350,y=500,w=90, color="white", font=50,code=pressKey("9")}),
newKey({name="_0", x=150,y=600,w=90, color="white", font=50,code=pressKey("0")}),
newKey({name="<", x=250,y=600,w=90, color="lRed", font=50,code=pressKey("backspace")}),
newKey({name="=", x=350,y=600,w=90, color="lYellow",font=50,code=pressKey("return")}),
newKey({name="+", x=450,y=300,w=90, color="lBlue", font=50,code=pressKey("+")}),
newKey({name="-", x=450,y=400,w=90, color="lBlue", font=50,code=pressKey("-")}),
newKey({name="*", x=450,y=500,w=90, color="lBlue", font=50,code=pressKey("*")}),
newKey({name="/", x=450,y=600,w=90, color="lBlue", font=50,code=pressKey("/")}),
newButton({name="play", x=640,y=600,w=180,h=90, color="lGreen", font=40,code=pressKey("space"),hide=function()return not sceneTemp.pass end}),
},
p15={
newButton({name="reset", x=160,y=100,w=180,h=100,color="lGreen", font=40,code=pressKey("space")}),
newSwitch({name="color", x=200,y=240,w=60, font=40,disp=function()return sceneTemp.color end,code=pressKey("c"),hide=function()return sceneTemp.state>0 end}),
newSwitch({name="hide", x=200,y=340,w=60, font=40,disp=function()return sceneTemp.blind end,code=pressKey("h"),hide=function()return sceneTemp.state>0 end}),
newButton({name="back", x=1140,y=640,w=180,h=80,color="white", font=35,code=BACK}),
},
main={
newButton({name="play", x=150,y=280,w=200,h=160,color="lRed", font=55,code=function()SCN.go("mode")end}),
newButton({name="setting", x=370,y=280,w=200,h=160,color="lBlue", font=45,code=function()SCN.go("setting_game")end}),
newButton({name="music", x=590,y=280,w=200,h=160,color="lPurple",font=32,code=function()SCN.go("music")end}),
newButton({name="help", x=150,y=460,w=200,h=160,color="lYellow",font=50,code=function()SCN.go("help")end}),
newButton({name="stat", x=370,y=460,w=200,h=160,color="lCyan", font=43,code=function()SCN.go("stat")end}),
newButton({name="qplay", x=590,y=460,w=200,h=160,color="lOrange",font=43,code=function()SCN.push()loadGame(stat.lastPlay,true)end}),
newButton({name="lang", x=150,y=610,w=160,h=100,color="lGreen", font=45,code=function()SCN.go("setting_lang")end}),
newButton({name="quit", x=590,y=610,w=160,h=100,color="lGrey", font=45,code=function()VOC.play("bye")SCN.swapTo("quit","slowFade")end}),
},
mode={
newButton({name="setting", x=1100,y=540,w=240,h=90,color="lGreen", font=40,code=function()
SCN.go("custom")
end,
hide=function()
return mapCam.sel~="custom_clear" and mapCam.sel~="custom_puzzle"
end}),
newButton({name="start", x=1040,y=655,w=180,h=80,color="white", font=40,code=pressKey("return"),hide=function()return not mapCam.sel end}),
newButton({name="back", x=1200,y=655,w=120,h=80,color="white", font=40,code=BACK}),
},
music={
newSlider({name="bgm", x=760, y=80, w=400, font=35,disp=SETval("bgm"),code=function(v)setting.bgm=v;BGM.freshVolume()end}),
newButton({name="up", x=1100, y=200, w=120, color="white", font=55,code=pressKey("up")}),
newButton({name="play", x=1100, y=340, w=120, color="white", font=35,code=pressKey("space"),hide=function()return setting.bgm==0 end}),
newButton({name="down", x=1100, y=480, w=120, color="white", font=55,code=pressKey("down")}),
newButton({name="back", x=1140, y=640, w=180,h=80, color="white", font=35,code=BACK}),
},
custom={
newKey({name="up", x=1140, y=100, w=100, color="white", font=45,code=function()sceneTemp=(sceneTemp-2)%#customID+1 end}),
newKey({name="down", x=1140, y=340, w=100, color="white", font=45,code=function()sceneTemp=sceneTemp%#customID+1 end}),
newKey({name="left", x=1080, y=220, w=100, color="white", font=45,code=pressKey("left")}),
newKey({name="right", x=1200, y=220, w=100, color="white", font=45,code=pressKey("right")}),
newButton({name="set1", x=900, y=320, w=210,h=70, color="lYellow",font=32,code=pressKey("1")}),
newButton({name="set2", x=900, y=400, w=210,h=70, color="lYellow",font=32,code=pressKey("2")}),
newButton({name="set3", x=900, y=480, w=210,h=70, color="lYellow",font=32,code=pressKey("3")}),
newButton({name="set4", x=900, y=560, w=210,h=70, color="lYellow",font=32,code=pressKey("4")}),
newButton({name="set5", x=900, y=640, w=210,h=70, color="lYellow",font=32,code=pressKey("5")}),
newButton({name="seq", x=665, y=415, w=200,h=40, color="lGreen", font=30,code=pressKey("q")}),
newButton({name="draw", x=150, y=80, w=220,h=80, color="white", font=35,code=pressKey("e")}),
newButton({name="back", x=1140, y=640, w=180,h=80, color="white", font=35,code=BACK}),
},
sequence={
newKey({name="Z", x=100, y=440, w=90, color="white", font=50,code=pressKey(1)}),
newKey({name="S", x=200, y=440, w=90, color="white", font=50,code=pressKey(2)}),
newKey({name="J", x=300, y=440, w=90, color="white", font=50,code=pressKey(3)}),
newKey({name="L", x=400, y=440, w=90, color="white", font=50,code=pressKey(4)}),
newKey({name="T", x=500, y=440, w=90, color="white", font=50,code=pressKey(5)}),
newKey({name="O", x=600, y=440, w=90, color="white", font=50,code=pressKey(6)}),
newKey({name="I", x=700, y=440, w=90, color="white", font=50,code=pressKey(7)}),
newKey({name="Z5", x=100, y=540, w=90, color="grey", font=50,code=pressKey(8)}),
newKey({name="S5", x=200, y=540, w=90, color="grey", font=50,code=pressKey(9)}),
newKey({name="P", x=300, y=540, w=90, color="grey", font=50,code=pressKey(10)}),
newKey({name="Q", x=400, y=540, w=90, color="grey", font=50,code=pressKey(11)}),
newKey({name="F", x=500, y=540, w=90, color="grey", font=50,code=pressKey(12)}),
newKey({name="E", x=600, y=540, w=90, color="grey", font=50,code=pressKey(13)}),
newKey({name="T5", x=700, y=540, w=90, color="grey", font=50,code=pressKey(14)}),
newKey({name="U", x=800, y=540, w=90, color="grey", font=50,code=pressKey(15)}),
newKey({name="V", x=900, y=540, w=90, color="grey", font=50,code=pressKey(16)}),
newKey({name="W", x=100, y=640, w=90, color="grey", font=50,code=pressKey(17)}),
newKey({name="X", x=200, y=640, w=90, color="grey", font=50,code=pressKey(18)}),
newKey({name="J5", x=300, y=640, w=90, color="grey", font=50,code=pressKey(19)}),
newKey({name="L5", x=400, y=640, w=90, color="grey", font=50,code=pressKey(20)}),
newKey({name="R", x=500, y=640, w=90, color="grey", font=50,code=pressKey(21)}),
newKey({name="Y", x=600, y=640, w=90, color="grey", font=50,code=pressKey(22)}),
newKey({name="N", x=700, y=640, w=90, color="grey", font=50,code=pressKey(23)}),
newKey({name="H", x=800, y=640, w=90, color="grey", font=50,code=pressKey(24)}),
newKey({name="I5", x=900, y=640, w=90, color="grey", font=50,code=pressKey(25)}),
newKey({name="left", x=800, y=440, w=90, color="lGreen", font=55,code=pressKey("left")}),
newKey({name="right", x=900, y=440, w=90, color="lGreen", font=55,code=pressKey("right")}),
newKey({name="backsp", x=1000, y=440, w=90, color="lYellow",font=50,code=pressKey("backspace")}),
newKey({name="reset", x=1000, y=540, w=90, color="lYellow",font=50,code=pressKey("delete")}),
newButton({name="copy", x=1140, y=440, w=170,h=90, color="lRed", font=40,code=pressKey("cC"),hide=function()return #preBag==0 end}),
newButton({name="paste", x=1140, y=540, w=170,h=90, color="lBlue", font=40,code=pressKey("cV")}),
newButton({name="back", x=1140, y=640, w=180,h=80, color="white", font=35,code=BACK}),
},
draw={
newButton({name="b1", x=500+65*1, y=150, w=58, color="red", font=30,code=setPen(1)}),--B1
newButton({name="b2", x=500+65*2, y=150, w=58, color="orange", font=30,code=setPen(2)}),--B2
newButton({name="b3", x=500+65*3, y=150, w=58, color="yellow", font=30,code=setPen(3)}),--B3
newButton({name="b4", x=500+65*4, y=150, w=58, color="grass", font=30,code=setPen(4)}),--B4
newButton({name="b5", x=500+65*5, y=150, w=58, color="green", font=30,code=setPen(5)}),--B5
newButton({name="b6", x=500+65*6, y=150, w=58, color="water", font=30,code=setPen(6)}),--B6
newButton({name="b7", x=500+65*7, y=150, w=58, color="cyan", font=30,code=setPen(7)}),--B7
newButton({name="b8", x=500+65*8, y=150, w=58, color="blue", font=30,code=setPen(8)}),--B8
newButton({name="b9", x=500+65*9, y=150, w=58, color="purple", font=30,code=setPen(9)}),--B9
newButton({name="b10", x=500+65*10,y=150, w=58, color="magenta",font=30,code=setPen(10)}),--B10
newButton({name="b11", x=500+65*11,y=150, w=58, color="pink", font=30,code=setPen(11)}),--B11
newButton({name="b12", x=500+65*1, y=230, w=58, color="dGrey", font=30,code=setPen(12)}),--Bone
newButton({name="b13", x=500+65*2, y=230, w=58, color="grey", font=30,code=setPen(13)}),--GB1
newButton({name="b14", x=500+65*3, y=230, w=58, color="lGrey", font=30,code=setPen(14)}),--GB2
newButton({name="b15", x=500+65*4, y=230, w=58, color="dPurple",font=30,code=setPen(15)}),--GB3
newButton({name="b16", x=500+65*5, y=230, w=58, color="dRed", font=30,code=setPen(16)}),--GB4
newButton({name="b17", x=500+65*6, y=230, w=58, color="dGreen", font=30,code=setPen(17)}),--GB5
newButton({name="any", x=600, y=360, w=120, color="lGrey", font=40,code=setPen(0)}),
newButton({name="space", x=730, y=360, w=120, color="grey", font=65,code=setPen(-1)}),
newButton({name="clear", x=1200, y=500, w=120, color="white", font=40,code=pressKey("delete")}),
newSwitch({name="demo", x=755, y=640, font=30,disp=function()return sceneTemp.demo end,code=function()sceneTemp.demo=not sceneTemp.demo end}),
newButton({name="copy", x=920, y=640, w=120, color="lRed", font=35,code=pressKey("cC")}),
newButton({name="paste", x=1060, y=640, w=120, color="lBlue", font=35,code=pressKey("cV")}),
newButton({name="custom", x=110, y=80, w=140,h=80, color="white", font=35,code=pressKey("e")}),
newButton({name="back", x=1140, y=640, w=180,h=80, color="white", font=35,code=BACK}),
},
play={
newButton({name="pause", x=1235, y=45, w=80, color="white", font=25,code=function()pauseGame()end}),
},
pause={
newButton({name="setting", x=1120, y=70, w=240,h=90, color="lBlue", font=35,code=pressKey("s")}),
newButton({name="replay", x=640, y=250, w=240,h=100,color="lYellow",font=30,code=pressKey("p"),hide=function()return not(game.result or game.replaying)end}),
newButton({name="resume", x=640, y=367, w=240,h=100,color="lGreen", font=30,code=pressKey("escape")}),
newButton({name="restart", x=640, y=483, w=240,h=100,color="lRed", font=33,code=pressKey("r")}),
newButton({name="quit", x=640, y=600, w=240,h=100,color="white", font=35,code=BACK}),
},
setting_game={
newButton({name="graphic", x=200, y=80, w=240,h=80, color="lCyan", font=35,code=function()SCN.swapTo("setting_video","swipe")end}),
newButton({name="sound", x=1080, y=80, w=240,h=80, color="lCyan", font=35,code=function()SCN.swapTo("setting_sound","swipe")end}),
newButton({name="ctrl", x=290, y=220, w=320,h=80, color="lYellow",font=35,code=function()SCN.go("setting_control")end}),
newButton({name="key", x=640, y=220, w=320,h=80, color="lGreen", font=35,code=function()SCN.go("setting_key")end}),
newButton({name="touch", x=990, y=220, w=320,h=80, color="lBlue", font=35,code=function()SCN.go("setting_touch")end}),
newSlider({name="reTime", x=350, y=340, w=300,unit=10, font=30,disp=SETval("reTime"), code=SETsto("reTime"),show=function(S)return(.5+S.disp()*.25).."s"end}),
newSlider({name="maxNext", x=350, y=440, w=300,unit=6, font=30,disp=SETval("maxNext"), code=SETsto("maxNext")}),
newButton({name="layout", x=460, y=540, w=140,h=70,color="white", font=35,code=function()
SCN.go("setting_skin")
end}),
newSwitch({name="autoPause",x=1080, y=320, font=20,disp=SETval("autoPause"), code=SETrev("autoPause")}),
newSwitch({name="swap", x=1080, y=380, font=20,disp=SETval("swap"), code=SETrev("swap")}),
newSwitch({name="fine", x=1080, y=440, font=20,disp=SETval("fine"), code=SETrev("fine")}),
newSwitch({name="appLock", x=1080, y=500, font=20,disp=SETval("appLock"), code=SETrev("appLock")}),
newButton({name="back", x=1140, y=640, w=180,h=80,color="white", font=35,code=BACK}),
},
setting_video={
newButton({name="sound", x=200, y=80,w=240,h=80,color="lCyan",font=35,code=function()SCN.swapTo("setting_sound","swipe")end}),
newButton({name="game", x=1080, y=80,w=240,h=80,color="lCyan",font=35,code=function()SCN.swapTo("setting_game","swipe")end}),
newSlider({name="ghost", x=250, y=180,w=200,unit=.6,noUnit=true,font=35,disp=SETval("ghost"),show="percent",code=SETsto("ghost")}),
newSlider({name="center", x=600, y=180,w=200,unit=1, font=35,disp=SETval("center"), code=SETsto("center")}),
newSwitch({name="smooth", x=260, y=260, font=25,disp=SETval("smooth"), code=SETrev("smooth")}),
newSwitch({name="grid", x=480, y=260, font=35,disp=SETval("grid"), code=SETrev("grid")}),
newSwitch({name="bagLine", x=700, y=260, font=30,disp=SETval("bagLine"), code=SETrev("bagLine")}),
newSlider({name="lockFX", x=350, y=340,w=373,unit=5, font=32,disp=SETval("lockFX"), code=SETsto("lockFX")}),
newSlider({name="dropFX", x=350, y=390,w=373,unit=5, font=32,disp=SETval("dropFX"), code=SETsto("dropFX")}),
newSlider({name="moveFX", x=350, y=440,w=373,unit=5, font=32,disp=SETval("moveFX"), code=SETsto("moveFX")}),
newSlider({name="clearFX", x=350, y=490,w=373,unit=5, font=32,disp=SETval("clearFX"), code=SETsto("clearFX")}),
newSlider({name="shakeFX", x=350, y=540,w=373,unit=5, font=32,disp=SETval("shakeFX"), code=SETsto("shakeFX")}),
newSlider({name="atkFX", x=350, y=590,w=373,unit=5, font=32,disp=SETval("atkFX"), code=SETsto("atkFX")}),
newSlider({name="frame", x=350, y=640,w=373,unit=10,font=30,
disp=function()
return setting.frameMul>35 and setting.frameMul/10 or setting.frameMul/5-4
end,
code=function(i)
setting.frameMul=i<5 and 5*i+20 or 10*i
end}),
newSwitch({name="text", x=1050, y=180,font=35,disp=SETval("text"),code=SETrev("text")}),
newSwitch({name="warn", x=1050, y=260,font=35,disp=SETval("warn"),code=SETrev("warn")}),
newSwitch({name="fullscreen",x=1050,y=340,font=35,disp=SETval("fullscreen"),
code=function()
setting.fullscreen=not setting.fullscreen
love.window.setFullscreen(setting.fullscreen)
love.resize(love.graphics.getWidth(),love.graphics.getHeight())
end}),
newSwitch({name="bg", x=1050, y=420,font=35,disp=SETval("bg"),
code=function()
BG.set("none")
setting.bg=not setting.bg
BG.set("space")
end}),
newSwitch({name="power", x=1050, y=500,font=35,disp=SETval("powerInfo"),
code=function()
setting.powerInfo=not setting.powerInfo
end}),
newButton({name="back", x=1140, y=640,w=180,h=80,color="white", font=35,code=BACK}),
},
setting_sound={
newButton({name="game", x=200, y=80,w=240,h=80,color="lCyan", font=35,code=function()SCN.swapTo("setting_game","swipe")end}),
newButton({name="graphic", x=1080, y=80,w=240,h=80,color="lCyan", font=35,code=function()SCN.swapTo("setting_video","swipe")end}),
newSlider({name="sfx", x=180, y=200,w=400, font=35,change=function()SFX.play("blip_1")end, disp=SETval("sfx"), code=SETsto("sfx")}),
newSlider({name="stereo", x=180, y=500,w=400, font=35,change=function()SFX.play("move",1,-1)SFX.play("lock",1,1)end,disp=SETval("stereo"),code=SETsto("stereo"),hide=function()return setting.sfx==0 end}),
newSlider({name="spawn", x=180, y=300,w=400, font=30,change=function()SFX.fplay("spawn_"..rnd(7),setting.spawn)end,disp=SETval("spawn"), code=SETsto("spawn")}),
newSlider({name="bgm", x=180, y=400,w=400, font=35,change=function()BGM.freshVolume()end, disp=SETval("bgm"), code=SETsto("bgm")}),
newSlider({name="vib", x=750, y=200,w=400, unit=5, font=28,change=function()VIB(2)end, disp=SETval("vib"), code=SETsto("vib")}),
newSlider({name="voc", x=750, y=300,w=400, font=32,change=function()VOC.play("nya")end, disp=SETval("voc"), code=SETsto("voc")}),
newButton({name="back", x=1140, y=640,w=180,h=80,color="white", font=35,code=BACK}),
},
setting_control={
newSlider({name="das", x=250, y=200,w=910, unit=26, font=30,disp=SETval("das"), show="frame_time",code=SETsto("das")}),
newSlider({name="arr", x=250, y=290,w=525, unit=15, font=30,disp=SETval("arr"), show="frame_time",code=SETsto("arr")}),
newSlider({name="sddas", x=250, y=380,w=350, unit=10, font=30,disp=SETval("sddas"), show="frame_time",code=SETsto("sddas")}),
newSlider({name="sdarr", x=250, y=470,w=140, unit=4, font=30,disp=SETval("sdarr"), show="frame_time",code=SETsto("sdarr")}),
newSwitch({name="ihs", x=1100, y=290,font=30, disp=SETval("ihs"), code=SETrev("ihs")}),
newSwitch({name="irs", x=1100, y=380,font=30, disp=SETval("irs"), code=SETrev("irs")}),
newSwitch({name="ims", x=1100, y=470,font=30, disp=SETval("ims"), code=SETrev("ims")}),
newButton({name="reset", x=160, y=580,w=200,h=100,color="lRed",font=40,
code=function()
local _=setting
_.das,_.arr=10,2
_.sddas,_.sdarr=0,2
_.ihs,_.irs,_.ims=false,false,false
end}),
newButton({name="back", x=1140, y=640,w=180,h=80,color="white",font=35,code=BACK}),
},
setting_key={
newButton({name="back", x=1140,y=640,w=180,h=80,color="white",font=35,code=BACK}),
},
setting_skin={
newButton({name="prev", x=700,y=100,w=140,h=100,color="white",font=50,code=function()SKIN.prevSet()end}),
newButton({name="next", x=860,y=100,w=140,h=100,color="white",font=50,code=function()SKIN.nextSet()end}),
newButton({name="prev1", x=130,y=230,w=90,h=65,color="white",font=30,code=prevSkin(1)}),
newButton({name="prev2", x=270,y=230,w=90,h=65,color="white",font=30,code=prevSkin(2)}),
newButton({name="prev3", x=410,y=230,w=90,h=65,color="white",font=30,code=prevSkin(3)}),
newButton({name="prev4", x=550,y=230,w=90,h=65,color="white",font=30,code=prevSkin(4)}),
newButton({name="prev5", x=690,y=230,w=90,h=65,color="white",font=30,code=prevSkin(5)}),
newButton({name="prev6", x=830,y=230,w=90,h=65,color="white",font=30,code=prevSkin(6)}),
newButton({name="prev7", x=970,y=230,w=90,h=65,color="white",font=30,code=prevSkin(7)}),
newButton({name="next1", x=130,y=450,w=90,h=65,color="white",font=30,code=nextSkin(1)}),
newButton({name="next2", x=270,y=450,w=90,h=65,color="white",font=30,code=nextSkin(2)}),
newButton({name="next3", x=410,y=450,w=90,h=65,color="white",font=30,code=nextSkin(3)}),
newButton({name="next4", x=550,y=450,w=90,h=65,color="white",font=30,code=nextSkin(4)}),
newButton({name="next5", x=690,y=450,w=90,h=65,color="white",font=30,code=nextSkin(5)}),
newButton({name="next6", x=830,y=450,w=90,h=65,color="white",font=30,code=nextSkin(6)}),
newButton({name="next7", x=970,y=450,w=90,h=65,color="white",font=30,code=nextSkin(7)}),
newButton({name="spin1", x=130,y=540,w=90,h=65,color="white",font=30,code=nextDir(1)}),
newButton({name="spin2", x=270,y=540,w=90,h=65,color="white",font=30,code=nextDir(2)}),
newButton({name="spin3", x=410,y=540,w=90,h=65,color="white",font=30,code=nextDir(3)}),
newButton({name="spin4", x=550,y=540,w=90,h=65,color="white",font=30,code=nextDir(4)}),
newButton({name="spin5", x=690,y=540,w=90,h=65,color="white",font=30,code=nextDir(5)}),
--newButton({name="spin6",x=825,y=540,w=90,h=65,color="white",font=30,code=nextDir(6)}),--Cannot rotate O
newButton({name="spin7", x=970,y=540,w=90,h=65,color="white",font=30,code=nextDir(7)}),
newButton({name="skinR", x=200,y=640,w=220,h=80,color="lPurple",font=35,
code=function()
setting.skin={1,5,8,2,10,3,7,1,5,5,1,8,2,10,3,7,10,7,8,2,8,2,1,5,3}
SFX.play("rotate")
end}),
newButton({name="faceR", x=480,y=640,w=220,h=80,color="lRed",font=35,
code=function()
for i=1,25 do
setting.face[i]=0
end
SFX.play("hold")
end}),
newButton({name="back", x=1140,y=640,w=180,h=80,color="white",font=35,code=BACK}),
},
setting_touch={
newButton({name="default", x=520,y=80,w=200,h=80,color="white",font=35,
code=function()
local D=virtualkeySet[sceneTemp.default]
for i=1,#VK_org do
VK_org[i].ava=false
end
--Replace keys
for n=1,#D do
local T=D[n]
if T[1]then
local B=VK_org[n]
B.ava=true
B.x,B.y,B.r=T[2],T[3],T[4]
end
end
sceneTemp.default=sceneTemp.default%5+1
sceneTemp.sel=nil
end}),
newButton({name="snap", x=760,y=80,w=200,h=80,color="white",font=35,
code=function()
sceneTemp.snap=sceneTemp.snap%6+1
end}),
newButton({name="option", x=520,y=180,w=200,h=80,color="white",font=40,
code=function()
SCN.go("setting_touchSwitch")
end}),
newButton({name="back", x=760,y=180,w=200,h=80,color="white",font=35,code=BACK}),
newSlider({name="size", x=450,y=265,w=460,unit=14,font=40,show="vkSize",
disp=function()
return VK_org[sceneTemp.sel].r/10-1
end,
code=function(v)
if sceneTemp.sel then
VK_org[sceneTemp.sel].r=10+v*10
end
end,
hide=function()
return not sceneTemp.sel
end}),
},
setting_touchSwitch={
newSwitch({name="b1", x=280, y=80, font=35,disp=VKAdisp(1),code=VKAcode(1)}),
newSwitch({name="b2", x=280, y=140, font=35,disp=VKAdisp(2),code=VKAcode(2)}),
newSwitch({name="b3", x=280, y=200, font=35,disp=VKAdisp(3),code=VKAcode(3)}),
newSwitch({name="b4", x=280, y=260, font=35,disp=VKAdisp(4),code=VKAcode(4)}),
newSwitch({name="b5", x=280, y=320, font=35,disp=VKAdisp(5),code=VKAcode(5)}),
newSwitch({name="b6", x=280, y=380, font=35,disp=VKAdisp(6),code=VKAcode(6)}),
newSwitch({name="b7", x=280, y=440, font=35,disp=VKAdisp(7),code=VKAcode(7)}),
newSwitch({name="b8", x=280, y=500, font=35,disp=VKAdisp(8),code=VKAcode(8)}),
newSwitch({name="b9", x=280, y=560, font=35,disp=VKAdisp(9),code=VKAcode(9)}),
newSwitch({name="b10", x=280, y=620, font=35,disp=VKAdisp(10),code=VKAcode(10)}),
newSwitch({name="b11", x=620, y=80, font=35,disp=VKAdisp(11),code=VKAcode(11)}),
newSwitch({name="b12", x=620, y=140, font=35,disp=VKAdisp(12),code=VKAcode(12)}),
newSwitch({name="b13", x=620, y=200, font=35,disp=VKAdisp(13),code=VKAcode(13)}),
newSwitch({name="b14", x=620, y=260, font=35,disp=VKAdisp(14),code=VKAcode(14)}),
newSwitch({name="b15", x=620, y=320, font=35,disp=VKAdisp(15),code=VKAcode(15)}),
newSwitch({name="b16", x=620, y=380, font=35,disp=VKAdisp(16),code=VKAcode(16)}),
newSwitch({name="b17", x=620, y=440, font=35,disp=VKAdisp(17),code=VKAcode(17)}),
newSwitch({name="b18", x=620, y=500, font=35,disp=VKAdisp(18),code=VKAcode(18)}),
newSwitch({name="b19", x=620, y=560, font=35,disp=VKAdisp(19),code=VKAcode(19)}),
newSwitch({name="b20", x=620, y=620, font=35,disp=VKAdisp(20),code=VKAcode(20)}),
newButton({name="norm", x=840, y=100, w=240,h=80,color="white",font=35,code=function()for i=1,20 do VK_org[i].ava=i<11 end end}),
newButton({name="pro", x=1120, y=100, w=240,h=80,color="white",font=35,code=function()for i=1,20 do VK_org[i].ava=true end end}),
newSwitch({name="hide", x=1170, y=200, font=40,disp=SETval("VKSwitch"),code=SETrev("VKSwitch")}),
newSwitch({name="track", x=1170, y=300, font=35,disp=SETval("VKTrack"),code=SETrev("VKTrack")}),
newSlider({name="sfx", x=800, y=380, w=180, font=40,change=function()SFX.play("virtualKey",setting.VKSFX)end,disp=SETval("VKSFX"),code=SETsto("VKSFX")}),
newSlider({name="vib", x=800, y=460, w=180,unit=2, font=40,change=function()VIB(setting.VKVIB)end,disp=SETval("VKVIB"),code=SETsto("VKVIB")}),
newSwitch({name="icon", x=850, y=300, font=40,disp=SETval("VKIcon"),code=SETrev("VKIcon")}),
newButton({name="tkset", x=1120, y=420, w=240,h=80,color="white",font=32,
code=function()
SCN.go("setting_trackSetting")
end,
hide=function()
return not setting.VKTrack
end}),
newSlider({name="alpha", x=840, y=540, w=400,font=40,disp=SETval("VKAlpha"),code=SETsto("VKAlpha")}),
newButton({name="back", x=1140, y=640, w=180,h=80,color="white",font=35,code=BACK}),
},
setting_trackSetting={
newSwitch({name="VKDodge", x=400, y=200, font=35, disp=SETval("VKDodge"),code=SETrev("VKDodge")}),
newSlider({name="VKTchW", x=140, y=310, w=1000, unit=10,font=35,disp=SETval("VKTchW"),code=function(i)setting.VKTchW=i;setting.VKCurW=math.max(setting.VKCurW,i)end}),
newSlider({name="VKCurW", x=140, y=370, w=1000, unit=10,font=35,disp=SETval("VKCurW"),code=function(i)setting.VKCurW=i;setting.VKTchW=math.min(setting.VKTchW,i)end}),
newButton({name="back", x=1140, y=640, w=180,h=80,color="white",font=35,code=BACK}),
},
setting_lang={
newButton({name="chi", x=160, y=100,w=200,h=120,color="white",font=45,code=setLang(1)}),
newButton({name="chi2", x=380, y=100,w=200,h=120,color="white",font=45,code=setLang(2)}),
newButton({name="eng", x=600, y=100,w=200,h=120,color="white",font=45,code=setLang(3)}),
newButton({name="str", x=820, y=100,w=200,h=120,color="white",font=45,code=setLang(4)}),
newButton({name="yygq", x=1040, y=100,w=200,h=120,color="white",font=45,code=setLang(5)}),
newButton({name="back", x=640, y=600,w=200,h=80,color="white",font=35,code=BACK}),
},
help={
newButton({name="staff", x=980, y=500,w=150,h=80,color="white",font=32,code=function()SCN.go("staff")end}),
newButton({name="his", x=1160, y=500,w=150,h=80,color="white",font=32,code=function()SCN.go("history")end}),
newButton({name="qq", x=1070, y=600,w=200,h=80,color="white",font=32,code=function()love.system.openURL("tencent://message/?uin=1046101471&Site=&Menu=yes")end,hide=mobileHide}),
newButton({name="back", x=640, y=600,w=200,h=80,color="white",font=35,code=BACK}),
},
staff={
newButton({name="back", x=1140, y=640,w=180,h=80,color="white",font=35,code=BACK}),
},
history={
newKey({name="prev", x=1155, y=170,w=180, color="white",font=65,code=pressKey("up"),hide=function()return sceneTemp.pos==1 end}),
newKey({name="next", x=1155, y=400,w=180, color="white",font=65,code=pressKey("down"),hide=function()return sceneTemp.pos==#sceneTemp.text end}),
newButton({name="back", x=1140, y=640,w=180,h=80,color="white",font=35,code=BACK}),
},
stat={
newButton({name="path", x=980, y=620,w=250,h=80,color="white",font=25,code=function()love.system.openURL(love.filesystem.getSaveDirectory())end,hide=mobileHide}),
newButton({name="back", x=640, y=620,w=200,h=80,color="white",font=35,code=BACK}),
},
debug={
newButton({name="reset", x=640,y=200,w=260,h=100,color="yellow",font=40,
code=function()
sceneTemp.reset=true
end,
hide=function()
return sceneTemp.reset
end}),
newButton({name="reset1", x=340,y=400,w=260,h=100,color="red",font=40,
code=function()
love.filesystem.remove("unlock.dat")
SFX.play("finesseError_long")
TEXT.show("rank resetted",640,300,60,"stretch",.4)
TEXT.show("effected after restart game",640,360,60,"stretch",.4)
TEXT.show("play one game if you regret",640,390,40,"stretch",.4)
end,
hide=function()
return not sceneTemp.reset
end}),
newButton({name="reset2", x=640,y=400,w=260,h=100,color="red",font=40,
code=function()
love.filesystem.remove("data.dat")
SFX.play("finesseError_long")
TEXT.show("game data resetted",640,300,60,"stretch",.4)
TEXT.show("effected after restart game",640,360,60,"stretch",.4)
TEXT.show("play one game if you regret",640,390,40,"stretch",.4)
end,
hide=function()
return not sceneTemp.reset
end}),
newButton({name="reset3", x=940,y=400,w=260,h=100,color="red",font=40,
code=function()
local L=love.filesystem.getDirectoryItems("")
for i=1,#L do
local s=L[i]
if s:sub(-4)==".dat"then
love.filesystem.remove(s)
end
end
SFX.play("clear_4")SFX.play("finesseError_long")
TEXT.show("all file deleted",640,330,60,"stretch",.4)
TEXT.show("effected after restart game",640,390,60,"stretch",.4)
SCN.back()
end,
hide=function()
return not sceneTemp.reset
end}),
newButton({name="back", x=640,y=620,w=200,h=80,color="white",font=35,code=BACK}),
},
}
--Remove temp vars
mobileHide,SETval,SETsto,SETrev=nil
pressKey,setPen,prevSkin,nextSkin=nil
nextDir,VKAdisp,VKAcode,setLang=nil
newText,newImage,newButton,newSwitch,newSlider=nil
return Widgets

303
ai.lua
View File

@@ -1,303 +0,0 @@
--[[
HighestBlock
HorizontalTransitions
VerticalTransitions
BlockedCells
Wells
FilledLines
4deepShape
BlockedWells;
]]
local int,ceil,min,abs,rnd=math.floor,math.ceil,math.min,math.abs,math.random
local ins,rem=table.insert,table.remove
local Timer=love.timer.getTime
-- controlname:
-- 1~5:mL,mR,rR,rL,rF,
-- 6~10:hD,sD,H,A,R,
-- 11~13:LL,RR,DD
local blockPos={4,4,4,4,4,5,4}
local scs={{1,2},{1,2},{1,2},{1,2},{1,2},{1.5,1.5},{0.5,2.5}}
-------------------------------------------------Cold clear
local CCblockID={4,3,5,6,1,2,0}
if system~="Windows"then goto SKIP end
require("CCloader")
BOT={
getConf= cc.get_default_config ,--()options,weights
--setConf= cc.set_options ,--(options,hold,20g,bag7)
new= cc.launch_async ,--(options,weights)bot
addNext= cc.add_next_piece_async ,--(bot,piece)
update= cc.reset_async ,--(bot,field,b2b,combo)
think= cc.request_next_move ,--(bot)
getMove= cc.poll_next_move ,--(bot)success,hold,move
ifDead= cc.is_dead_async ,--(bot)dead
destroy= cc.destroy_async ,--(bot)
setHold= cc.set_hold ,--(opt,bool)
set20G= cc.set_20g ,--(opt,bool)
setBag= cc.set_bag7 ,--(opt,bool)
setNode= cc.set_max_nodes ,--(opt,bool)
free= cc.free ,--(opt/wei)
}
function CC_updateField(P)
local F,i={},1
for y=1,#P.field do
for x=1,10 do
F[i],i=P.field[y][x]>0,i+1
end
end
while i<400 do
F[i],i=false,i+1
end
BOT.update(P.AI_bot,F,P.b2b>=100,P.combo)
end
function CC_switch20G(P)
P.AIdata._20G=true
P.AI_keys={}
BOT.destroy(P.AI_bot)
local opt,wei=BOT.getConf()
BOT.setHold(opt,P.AIdata.hold)
BOT.set20G(opt,P.AIdata._20G)
BOT.setBag(opt,P.AIdata.bag7)
BOT.setNode(opt,P.AIdata.node)
P.AI_bot=BOT.new(opt,wei)
BOT.free(opt)BOT.free(wei)
for i=1,P.AIdata.next do
BOT.addNext(P.AI_bot,CCblockID[P.next[i].id])
end
CC_updateField(P)
P.hd={bk={{}},id=0,color=0,name=0}P.holded=false
P.cur=rem(P.next,1)
P.sc,P.dir=scs[P.cur.id],0
P.r,P.c=#P.cur.bk,#P.cur.bk[1]
P.curX,P.curY=blockPos[P.cur.id],21+ceil(P.fieldBeneath/30)-P.r+min(int(#P.field*.2),2)
P:freshNext()
BOT.addNext(P.AI_bot,CCblockID[P.next[P.AIdata.next].id])
collectgarbage()
end
::SKIP::
-------------------------------------------------⑨Stack setup
local dirCount={1,1,3,3,3,0,1}
local spinOffset={
{1,0,0},--S
{1,0,0},--Z
{1,0,0},--L
{1,0,0},--J
{1,0,0},--T
{0,0,0},--O
{2,0,1},--I
}for i=1,7 do spinOffset[i][0]=0 end
local FCL={
[1]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{11,4},{11,3},{11,2,3},{4},{3},{2,3},{2,2,3},{12,4},{12,3}},
},
[3]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12},},
{{3,11},{11,3},{11,2,3},{1,3},{3},{2,3},{2,2,3},{12,1,3},{12,3},},
{{11,5},{11,2,5},{1,5},{5},{2,5},{2,2,5},{12,1,5},{12,5},},
{{11,4},{11,2,4},{1,4},{4},{2,4},{2,2,4},{12,1,4},{12,4},{4,12},},
},
[6]={
{{11},{11,2},{1,1},{1},{},{2},{2,2},{12,1},{12},},
},
[7]={
{{11},{11,2},{1},{},{2},{12,1},{12},},
{{4,11},{11,4},{11,3},{1,4},{4},{3},{2,3},{12,4},{12,3},{3,12},},
},
}
FCL[2]=FCL[1]
FCL[4]=FCL[3]
FCL[5]=FCL[3]
local LclearScore={[0]=0,-200,-120,-80,200}
local HclearScore={[0]=0,100,140,200,500}
local function ifoverlapAI(f,bk,x,y)
if y<1 then return true end
if y>#f then return end
for i=1,#bk do for j=1,#bk[1]do
if f[y+i-1]and bk[i][j]and f[y+i-1][x+j-1]>0 then return true end
end end
end
local function resetField(f0,f,start)
while f[start]do
removeRow(f,start)
end
for i=start,#f0 do
f[i]=getNewRow(0)
for j=1,10 do
f[i][j]=f0[i][j]
end
end
end
local function getScore(field,cb,cy)
local score=0
local highest=0
local height=getNewRow(0)
local clear=0
local hole=0
for i=cy+#cb-1,cy,-1 do
for j=1,10 do
if field[i][j]==0 then goto L end
end
removeRow(field,i)
clear=clear+1
::L::
end
if #field==0 then return 1e99 end--PC
for x=1,10 do
local h=#field
while field[h][x]==0 and h>1 do
h=h-1
end
height[x]=h
if x>3 and x<8 and h>highest then highest=h end
if h>1 then
for h=h-1,1,-1 do
if field[h][x]==0 then
hole=hole+1
if hole==5 then break end
end
end
end
end
local sdh=0
local h1,mh1=0,0
for x=1,9 do
local dh=abs(height[x]-height[x+1])
if dh==1 then
h1=h1+1
if h1>mh1 then mh1=h1 end
else
h1=0
end
sdh=sdh+min(dh^1.6,20)
end
freeRow[#freeRow+1]=height
freeRow.L=freeRow.L+1
score=
-#field*30
-#cb*15
+(#field>10 and
HclearScore[clear]--Clearing
-hole*70--Hole
-cy*50--Height
-sdh--∫Δh
or
LclearScore[clear]
-hole*100
-cy*40
-sdh*3
)
if #field>6 then score=score-highest*5+20 end
if mh1>3 then score=score-20-mh1*30 end
return score
end
-------------------------------------------------
AI_think={
["9S"]={
function(P,ctrl)
local Tfield={}--test field
local field_org=P.field
for i=1,#field_org do
Tfield[i]=getNewRow(0)
for j=1,10 do
Tfield[i][j]=field_org[i][j]
end
end
local best={x=1,dir=0,hold=false,score=-1e99}
for ifhold=0,P.gameEnv.hold and 1 or 0 do
local bn=ifhold==0 and P.cur.id or P.hd.id>0 and P.hd.id or P.next[1].id
for dir=0,dirCount[bn] do--each dir
local cb=blocks[bn][dir]
for cx=1,11-#cb[1]do--each pos
local cy=#Tfield+1
while not ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1
end--move to bottom
for i=1,#cb do
local y=cy+i-1
if not Tfield[y]then Tfield[y]=getNewRow(0)end
for j=1,#cb[1]do
if cb[i][j]then
Tfield[y][cx+j-1]=1
end
end
end--simulate lock
local score=getScore(Tfield,cb,cy)
if score>best.score then
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score}
end
resetField(field_org,Tfield,cy)
end
end
end
::L::
if #Tfield>0 then
removeRow(Tfield,1)
goto L
end--Release cache
local p=#ctrl+1
if best.hold then
ctrl[p]=8
p=p+1
end
local l=FCL[best.bn][best.dir+1][best.x]
for i=1,#l do
ctrl[p]=l[i]
p=p+1
end
ctrl[p]=6
return 2
end,
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,
},
["CC"]={
function(P)
if P.AI_needFresh then
CC_updateField(P)
P.AI_needFresh=false
end
BOT.think(P.AI_bot)
return 2
end,--start thinking
function(P,ctrl)
if BOT.ifDead(P.AI_bot)then ins(ctrl,6)return 3 end
local success,hold,move=BOT.getMove(P.AI_bot)
if success then
if hold then ctrl[1]=8 end--Hold
while move[1]do
local m=rem(move,1)
if m<4 then
ins(ctrl,m+1)
elseif not P.AIdata._20G then
ins(ctrl,13)
end
end
ins(ctrl,6)
return 3
else
return 2--stay this stage
end
end,--poll keys
function(P)
P.AI_delay=P.AI_delay0
if Timer()-P.modeData.point>P.modeData.event then
P.modeData.point=Timer()
P.modeData.event=P.AI_delay0+rnd(2,10)
P:changeAtkMode(rnd()<.85 and 1 or #P.atker>3 and 4 or rnd()<.3 and 2 or 3)
end
return 1
end,--check if time to change target
},
}--AI think stage

165
class.lua
View File

@@ -1,165 +0,0 @@
local gc=love.graphics
local rem=table.remove
local format=string.format
Task={}
function newTask(code,P,data)
Task[#Task+1]={
code=code,
P=P,
data=data,
}
end
function clearTask(opt)
if opt=="all"then
local i=#Task
while i>0 do
Task[i]=nil
i=i-1
end
elseif opt=="play"then
for i=#Task,1,-1 do
if Task[i].P then
rem(Task,i)
end
end
else--Player table
for i=#Task,1,-1 do
if Task[i].P==opt then
rem(Task,i)
end
end
end
end
local button={type="button"}
function newButton(x,y,w,h,color,font,code,hide,N)
local _={
x=x-w*.5,y=y-h*.5,
w=w,h=h,
color=color,
font=font,
code=code,
hide=hide,
next=N,
}for k,v in next,button do _[k]=v end return _
end
function button:isAbove(x,y)
return x>self.x and x<self.x+self.w and y>self.y and y<self.y+self.h
end
function button:FX()
sysFX[#sysFX+1]={0,0,10,self.x,self.y,self.w,self.h}
--[0=ripple],timer,duration,x,y,w,h
end
function button:draw()
local C=self.color
gc.setColor(C)
gc.setLineWidth(3)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
gc.setColor(C[1],C[2],C[3],.4)
gc.setLineWidth(5)gc.rectangle("line",self.x,self.y,self.w,self.h,4)
if self==widget_sel then
gc.rectangle("fill",self.x,self.y,self.w,self.h,4)
end--Highlight when Selected
local t=self.text
if t then
if type(t)=="function"then t=t()end
setFont(self.font)
local y0=self.y+self.h*.5-self.font*.7
gc.printf(t,self.x-2,y0-1,self.w,"center")
gc.setColor(C)
gc.printf(t,self.x,y0,self.w,"center")
end
end
function button:getInfo()
print(format("x=%d,y=%d,w=%d,h=%d,font=%d",self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font))
end
local switch={type="switch"}
function newSwitch(x,y,font,disp,code,hide,N)
local _={
x=x,y=y,font=font,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,switch do _[k]=v end return _
end
function switch:isAbove(x,y)
return x>self.x and x<self.x+100 and y>self.y-20 and y<self.y+20
end
function switch:FX()
sysFX[#sysFX+1]=self.disp()and
{1,0,15,1,.4,.4,self.x,self.y-20,50,40,0}--Switched on
or{1,0,15,.4,1,.4,self.x+50,self.y-20,50,40,0}--Switched off
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function switch:draw()
local x,y=self.x,self.y-20
if self.disp()then
gc.setColor(.6,1,.6)
gc.rectangle("fill",x+50,y,50,40,3)
--ON
else
gc.setColor(1,.6,.6)
gc.rectangle("fill",x,y,50,40,3)
--OFF
end--switch
gc.setColor(1,1,1,self==widget_sel and 1 or .6)
gc.setLineWidth(3)gc.rectangle("line",x-3,y-3,106,46,5)
--frame
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,x-412,y+20-self.font*.7,400,"right")
end
end
function switch:getInfo()
print(format("x=%d,y=%d,font=%d",self.x,self.y,self.font))
end
local slider={type="slider"}
function newSlider(x,y,w,unit,font,change,disp,code,hide,N)
local _={
x=x,y=y,
w=w,unit=unit,
font=font,
change=change,
disp=disp,
code=code,
hide=hide,
next=N,
}for k,v in next,slider do _[k]=v end return _
end
function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-20 and y<self.y+20
end
function slider:FX(pos)
sysFX[#sysFX+1]={1,0,10,1,1,1,self.x+self.w*pos/self.unit-8,self.y-15,17,30}
--[1=square fade],timer,duration,r,g,b,x,y,w,h
end
function slider:draw()
local S=self==widget_sel
gc.setColor(1,1,1,S and 1 or .5)
gc.setLineWidth(2)
local x1,x2=self.x,self.x+self.w
for p=0,self.unit do
local x=x1+(x2-x1)*p/self.unit
gc.line(x,self.y+7,x,self.y-7)
end
--units
gc.setLineWidth(5)
gc.line(x1,self.y,x2,self.y)
--axis
gc.setColor(1,1,1)
gc.rectangle("fill",x1+(x2-x1)*self.disp()/self.unit-8,self.y-15,17,30)
--block
local t=self.text
if t then
gc.setColor(1,1,1)
setFont(self.font)
gc.printf(t,self.x-312,self.y-self.font*.7,300,"right")
end
end
function slider:getInfo()
print(format("x=%d,y=%d,w=%d",self.x,self.y,self.w))
end

View File

@@ -1,36 +1,34 @@
math.randomseed(os.time())
gameVersion="Alpha V0.8.1"
gameVersion="Alpha V0.10.7"
function love.conf(t)
t.identity="Techmino"--Save directory name
t.identity="Techmino"--Saving folder
t.version="11.1"
t.console=X
t.gammacorrect=X
t.appendidentity=X--If search files in source before save directory
t.accelerometerjoystick=X--If exposing accelerometer on iOS and Android as a Joystick
t.audio.mixwithsystem=true--Switch on to keep sysBGM
t.gammacorrect=false
t.appendidentity=true--Search files in source then in save directory
t.accelerometerjoystick=false--Accelerometer=joystick on ios/android
if t.audio then t.audio.mixwithsystem=true end
local W=t.window
W.title="Techmino "..gameVersion
W.icon="/image/icon.png"
W.width,W.height=1280,720
W.minwidth,W.minheight=640,360
W.borderless=X
W.resizable=1
W.borderless=false
W.resizable=true
W.fullscreentype="desktop"--"exclusive"
W.fullscreen=X
W.vsync=0--0→∞fps
W.msaa=X--The number of samples to use with multi-sampled antialiasing (number)
W.depth=X--Bits per sample in the depth buffer
W.stencil=1--The number of bits per sample in the stencil buffer
W.fullscreen=false
W.vsync=0--Do not limit FPS
W.msaa=false--Num of samples to use with multi-sampled antialiasing
W.depth=0--Bits/samp of depth buffer
W.stencil=1--Bits/samp of stencil buffer
W.display=1--Monitor ID
W.highdpi=X--Enable high-dpi mode for the window on a Retina display (boolean)
W.highdpi=true--High-dpi mode for the window on a Retina display
W.x,W.y=nil
local M=t.modules
M.window,M.system,M.event=1,1,1
M.audio,M.sound=1,1
M.math,M.data=1,1
M.timer,M.graphics,M.font,M.image=1,1,1,1
M.mouse,M.touch,M.keyboard,M.joystick=1,1,1,1
M.physics,M.thread,M.video=X
M.window,M.system,M.event=true,true,true
M.audio,M.sound=true,true
M.math,M.data=true,true
M.timer,M.graphics,M.font,M.image=true,true,true,true
M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true
M.physics,M.thread,M.video=false,false,false
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +0,0 @@
setting={
das=10,arr=2,
sddas=0,sdarr=2,
quickR=true,swap=true,
fine=false,
--game
ghost=true,center=true,
smo=true,grid=false,
dropFX=3,
shakeFX=2,
atkFX=3,
frameMul=100,
fullscreen=false,
bg=true,
bgblock=true,
lang=1,
skin=1,
--graphic
sfx=10,bgm=7,
vib=3,voc=0,
stereo=6,
--sound
keyMap={
{"left","right","x","z","c","up","down","space","tab","r"},
{},{},{},{},{},{},{},
--keyboard
{"dpleft","dpright","a","b","y","dpup","dpdown","rightshoulder","x","leftshoulder"},
{},{},{},{},{},{},{},
--joystick
},
VKSwitch=true,
VKTrack=true,--If tracked
VKDodge=false,--If repel
VKTchW=3,--Touch Weight
VKCurW=4,--CurPos Weight
VKIcon=true,
VKAlpha=3,
--control
}
local L=setting.keyMap
for i=1,#L do
for j=1,20 do
if not L[i][j]then
L[i][j]=""
end
end
end
stat={
run=0,game=0,time=0,
extraPiece=0,extraRate=0,
key=0,rotate=0,hold=0,piece=0,row=0,
atk=0,send=0,recv=0,pend=0,
clear_1=0,clear_2=0,clear_3=0,clear_4=0,
spin_0=0,spin_1=0,spin_2=0,spin_3=0,
b2b=0,b3b=0,pc=0,score=0,
}
--Things related to virtualkey
local O,_=true,false
VK_org={--Original set,for restore VK' position
{ava=O,x=80, y=720-200, r=80},--moveLeft
{ava=O,x=320, y=720-200, r=80},--moveRight
{ava=O,x=1280-80, y=720-200, r=80},--rotRight
{ava=O,x=1280-200, y=720-80, r=80},--rotLeft
{ava=O,x=1280-200, y=720-320, r=80},--rotFlip
{ava=O,x=200, y=720-320, r=80},--hardDrop
{ava=O,x=200, y=720-80, r=80},--softDrop
{ava=O,x=1280-320, y=720-200, r=80},--hold
{ava=O,x=1280-80, y=280, r=80},--func
{ava=O,x=80, y=280, r=80},--restart
{ava=_,x=100, y=50, r=80},--insLeft
{ava=_,x=200, y=50, r=80},--insRight
{ava=_,x=300, y=50, r=80},--insDown
{ava=_,x=400, y=50, r=80},--down1
{ava=_,x=500, y=50, r=80},--down4
{ava=_,x=600, y=50, r=80},--down10
{ava=_,x=700, y=50, r=80},--dropLeft
{ava=_,x=800, y=50, r=80},--dropRight
{ava=_,x=900, y=50, r=80},--addToLeft
{ava=_,x=1000, y=50, r=80},--addToRight
}
virtualkey={}
for i=1,#VK_org do
virtualkey[i]={}
end

View File

@@ -1,89 +1,113 @@
(ENG ver. below)
游戏方法:
控制系统提供的一个个方块,每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
完成当前游戏模式中的目标或者是活到最后即算胜利.
系统提供的一个个四联骨牌("方块",总共7种),玩家需要控制(左右移动和旋转90,180,270度),每填满场地的一行就会将其消除,根据消除方式会给对手攻击(如果有对手的话)
活到最后或者完成目标即胜利.
旋转系统:
使用Techmino专属旋转系统,细节不赘述
使用Techmino专属旋转系统,细节懒得写(
spin判定:
结合了不可移动判定和三角判定,是否为mini也与这二者有关,细节不赘述
结合了不可移动判定和三角判定,是否为mini也与判定过程数据有关,细节也懒得写(
攻击系统:
消1/2/3/4攻击0/1/2/4
spin1/2/3攻击2/4/6,若mini则减半
b2b:增加1~2(tetris)/1~3(spin)攻击
b3b:满b2b效果+1额外抵挡
PC:其它攻击与6~8(本局内递增)取高+2额外抵挡
连击:0,0,1,1,2,2,3,3,4,4,3……
普通消除:
1/2/3/4攻击0.5/1.5/2.5/4
特殊消除:
spin1/2/3攻击2/4/6,若mini则减至一半
B2B:加1(techrash/spin1/spin2)或2(spin3)攻击
B3B:在B2B效果之上消四再加1,spin再加0.5*消行数攻击,二者都+1额外抵挡
连击:给予上述攻击[连击数*20%]的加成,上限200%,连消3次之后额外加1攻击
特殊消除会增加B2B点数,让之后的特殊消除获得B2B(B3B)增益(详细说明见下文)
半全消("下方有剩余方块"的全消,如果是I消1行则必须不剩余玩家放置的方块):伤害+2,额外抵挡+2
全消:将上述伤害之和减半,再+6~12(本局内递增)+2额外抵挡(注:本局消行数>4时会将B2B点数拉满)
根据上述规则计算后,向下取整,攻击打出
back to back(B2B)点数说明:
B2B点数的范围在0~1200
在40及以上特殊消除时B2B,在1000以上特殊消除时B3B,1200封顶
消四+100
空spin加20,不超过1000
spin1~3+50/100/180 (mini*.5)
普通消除-250
1000以上空放一块-40(不减到低于1000)
分数系统:
操作越牛逼得分越高嗷(
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
b2b或者b3b增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
back to back(B2B)点数说明:
B2B点数的范围在0~1200,在点数>=40时进行特殊消除为B2B,>1000时特殊消除为B3B
普通消除-250
spin1/2/3:+50/100/180(mini变为原来25%)
消四:+100
空spin:+20,此法得到的点数不能超过1000
当点数在1000以上时空放一块-40(不减到低于1000)
模式说明:
竞速:
用你最快的速度消除40行(据难度而定)吧!
马拉松:
根据总消行数,速度会逐渐加快,消除两百行吧!(easy和hard就是normal开始和结束的速度,消除200行不加速)
大师:
马拉松进化版,如果觉得马拉松太简单了久玩这个吧,每一个难度都是一层境界,L难度和U难度攒到500点数通关,final难度为上级者专属游戏模式,不建议游玩.
经典:
使用低速控制设置在高速下落时尽可能消除更多的行,没有通关目标.(到90有"彩蛋")
:
闲得无聊,只是想单纯地打打块地时候可以玩此模式,无重力消除200行.
无尽:
无尽模式,边上会显示玩家的消行数和攻击效率,适合科研(术语).
单挑:
和一个电脑玩家单挑,带加号的和最后一个模式是超强机器人(仅限Windows平台),试试你能稳定打败多难的对手吧!
回合制:
玩法同单挑模式,只不过只有当一个人放下一个方块后另一个人才能放下一块.
仅TSD:
这个模式中,玩家必须用TSD(T spin double)的方式消除,否则直接判负,你能连续打出多少个TSD呢?
隐形:
根据不同难度,场地内(甚至当前方块)会隐形,看看你能活多久吧!(GM难度为类似TGM3的GM Roll,用于上级者练习)
挖掘:
每隔一定时间,系统会向场地的低端添加一行垃圾行,间隔会随着波数增加而越来越短,你能顶住几波呢?
生存:
每隔一定时间,系统会向玩家的垃圾缓冲槽中添加垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家可以将其抵消也可以让其释放,尽可能活更久的时间.
防守:
系统会向玩家的垃圾缓冲槽中添加难消除的垃圾行,释放速度和间隔会随着波数增加而越来越短,玩家要尽量抵消他们来让自己存活更久.
进攻:
当玩家的攻击缓冲槽空时,系统会向玩家的垃圾缓冲槽中添加大量的垃圾行(高难度下后期甚至会远超过20),释放速度和间隔都会随着波数增加而越来越短,垃圾上涨速度也会提升.赶紧在其释放之前将攻击抵消到不会一下致命的量!
科研:
玩家只被允许做特殊消除(spin/全消/消四),在带+的难度中不允许消四,U难度下玩家甚至只被允许每一个方块都使用最简操作控制,任何违反规则的行为都会判负.
C4W练习:(或者说是4w练习)
系统直接提供给玩家"留4列"的场地,玩家可以自由练习4w消除,该技巧在某些时候实战很有用.(需要学会spin,否则意义不是很大)
全清训练:
系统会连续给玩家提供"标准开局PC套路"的场地和四个方块(不允许使用hold),玩家需要一直完成PC,否则判负.
全清挑战:
在消除一百行的限制内,你能全清几次?
49人混战:
许多玩家同时进行一局游戏其它的是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家AOE,若无则伏击随机玩家
坚持到最后的玩家就是胜利者.
99人混战:
同49人混战,只是增加到了99名玩家,难度系数也有调整,对设备的要求也较高.
干旱:
系统提供的方块序列变得奇怪了!你能消除100行不死吗,或者,多快?
多人:
使用键盘或者多个手柄(也许?)
自定义:
玩家可以自由调整下落速度等等几乎大多数设置(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来玩方块拼图.在拼图模式下,按功能键切换是否显示提示模板.其中打"X"的格子不允许有方块,空的格子可以是任何状态,玩家能获得的七种普通方块必须完全符合,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.
混战模式说明:
许多玩家同时进行一局游戏对手都是AI,不是真人).随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家攻击AOE,若未被任何人锁定则攻击随机玩家(不锁定)
坚持到最后的玩家就是胜利者.
自定义模式说明:
玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),也可以画一个场地去消除或者是作为提示模板来进行拼图模式.
在拼图模式下,按功能键切换是否展示提示.其中打"X"的格子不允许有方块,空的格子可以是任何状态,普通的七种彩色方块必须颜色对应,垃圾行方块的为止只要有方块就可以,但是不能是空气,玩家拼出自己画的图后就会判定胜利.
Gameplay:
System will offer a series of tetrominoes ("Pieces". There are 7 types), and the player needs to control [them] (move left and right, rotate 90, 180 or 270 degrees), filling a row on the play field will clear it, attack will be sent depending on the type of the line clear (if there is an opponent)
Survive till the last or complete the level's goal to win.
Rotation system:
Uses Techmino's custom rotation system. Too lazy to write the details
Spin detection:
Combines immobile and 3-corner detection, and whether a spin is mini also depends on the data used for detection. Also too lazy to write the details
Attack system:
Regular line clears:
Single/Double/Triple/Techrash sends 0.5/1.5/2.5/4
Special line clears:
Spin Single/Double/Triple sends 2/4/6, half if Mini
B2B: +1 (Techrash/Spin Single/Spin Double) or +2 (Spin Triple)
B2B2B/B3B: In addition to B2B, +1 if Techrash, +(0.5 * lines cleared) if Spin, and in both cases +1 additional blocking
Combo: each combo gives 20% more attack (capped at 200%), extra 1 attack after 3 combo
Special line clears will increase B2B gauge, making later special line clears have B2B or B2B2B bonus (see below)
Half Perfect Clear (a Perfect Clear "with blocks left below". If it's an I clearing 1 line, then the remaining blocks must not be player-placed): Attack +2, Extra Blocking +2
Perfect Clear: half all damage above, then +6 to +12 attack (increases within a round) and +2 extra blocking. (note: if lines cleared in this round >4, then B2B gauge will be filled)
After calculating all above, the damage value will be rounded down then sent
Score system:
The more impressive you play, the more score you get
Attack delay:
Attack from Doubles/Triples take effect the faster, then Techrash, Spins send rather slow attack, and high combos will send the slowest
B2B or B2B2B, while they increase lines sent, they also increase the attack delay. Minis will greatly increase delay.
Countering:
When you send attack, if there is garbage in queue, extra blocking will be used first, then attack, countering the earliest attack at a 1:1 ratio.
Unused extra blocking will be discarded, then remaining attack will be sent to your opponent.
Back to Back (B2B) gauge:
The B2B gauge ranges from 0 to 1,200. Special line clears are B2B if the gauge is >=40, B2B2B if >1,000.
A regular line clear -250
Spin Single/Double/Triple +50/100/180 (x25% if Mini)
Techrash +100
Spin without clearing lines +20, but gauge cannot exceed 1,000 with this method
When gauge is above 1,000, a drop without clearing lines -40 (cannot drop below 1,000 with this method)
Battle Royale modes:
Many players play within one game (all opponents are bots, not real players). As players get eliminated, blocks fall faster, and garbage take effect faster, as well as rise faster. KO-ing another player grants you one badge plus all badge that player has, increasing your attack power.
Players can select one of 4 attack modes:
1. Random: Every time you attack, 10% chance to lock onto a random player.
2. Badges: After you attack or when your target dies, lock onto the player with the most badges.
3. KOs: After you attack or when your target dies, lock onto the player with the highest field. (This refreshes every second)
4. Counter: attack all players locking onto yourself. Your attack will be sent to all of them. If you are not targetted, you attack a random player (not locking).
The last survivor wins.
Custom mode:
You can freely adjust most parameters (not including special effects of other game modes), and you can also draw a field to clear or make a template to build.
In build (puzzle) mode, you can toggle template display with Function key. Cells with a X cannot have blocks; empty cells can be in any state; regular colored cells have to be made of the corresponding block; garbage-colored cells can be any block but not air. Once you make the shape, you will win.
附录Appendix:
ZXC's cool O-spin map:XY0BCgAwCAIR7v9vHtUSt8AS0xKqgpnNGyXkrmFNePf6qi3BbQPrHT2Owxe6D66NeKi86dwB

BIN
font.ttf

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
image/mess/electric.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

BIN
image/mess/hbm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
image/mess/pay1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
image/mess/pay2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

BIN
image/mess/speedLimit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
image/mess/title_new.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
image/miya/ch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
image/miya/f1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
image/miya/f2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
image/miya/f3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
image/miya/f4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
image/skin/WTF.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

BIN
image/skin/ball(shaw).png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
image/skin/classic(_).png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
image/skin/glow(mrz).png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Some files were not shown because too many files have changed in this diff Show More