安卓galgame自己移植galgame的教程

谁教我怎么移植galgame到安卓_galgame吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:307,411贴子:
谁教我怎么移植galgame到安卓
谁教我怎么移植galgame到安卓
1 下载游戏镜像2 解压所有文件扔进模拟器3 开始游戏
求大神,我QQ
唉... ...~ 扶额~
内&&容:使用签名档&&
保存至快速回贴
为兴趣而生,贴吧更懂你。&或您现在的位置: >
onscripter安卓ONS游戏模拟器下载及使用教程
ONS游戏模拟器介绍:
  ONS游戏模拟器全名为onscripter,这是一款可以玩移植ONS游戏的软件,也就是常说的GALGAME。ONS模拟器最早登陆在LINUX平台,而大家都知道安卓系统是基于LINUX框架开发出来的操作系统,所以ONS模拟器理所当然地登陆到了安卓平台上,当然塞班系统上也有ONS模拟器,这里只介绍安卓ONS,因为它的兼容性最为强大,移植起来也相对比较简单。
  那么安卓ONS模拟器的兼容性如何呢?无论你的安卓手机是1.6的操作系统还是4.1的操作系统,安卓ONS游戏模拟器都能玩,可放心使用。
  不过这里小编必须提醒一点,ONS游戏模拟器运行的GALGAME包含不良导向的内容,请不要让孩子玩它,下载的时候请作为试用学习为主。
ONS游戏模拟器使用方法:
  准备工作:您需要用到ONS模拟器及ONS游戏移植工具。
  第一步:下载ONS游戏模拟器,新版旧版都可以,你可以都试用一下,自行决定哪个更适合自己,然后安装ONS游戏模拟器.APK
  第二步:下载已经做好的适用于ONS的游戏移植包,在SD卡上新建一个名为ONS的文件夹,将游戏包解压放到ONS文件夹下。当然,你也可以自己制作ONS游戏移植包,下面会对如何做ONS游戏移植包进行教程讲解。
  第三步:在安卓手机上运行ONS模拟器,你会看到刚才放入到ONS文件夹中的游戏。选择即可开始。
ONS游戏移植工具的使用方法:
  使用ONS的时候,ONScripter-GBK.apk代表中文模拟器,运行中文游戏必须用这个,并将default GBK.ttf修改成default.ttf来使用。
  ONScripter-JP.apk代表日语模拟器,运行日语游戏必须用这个,并将default JP.TTF修改成default.ttf来使用。
  要运行移植ONS游戏,必须包含三个部分。
  arc.nsa:BGM,图片语音等素材文件
  default.ttf:字体文件,上面有说明。
  nscript.dat:脚本文件,控制各种命令。
  特别说明一点,nscmake.exe打包TXT文件的时候名称必须为01.txt,02.txt这样的序号。
移植开始:
  第一步:用DT载入需要移植的游戏镜像文件。
  第二步:如果在虚拟光驱中我们看到了arc.nsa和nscript.dat这两份文件,就说明这个游戏是可以移植到ONS上的,于是将这两个文件复制下来。
  第三步:确定一下这游戏有没有汉化,假如是汉化的游戏,选择default GBK.ttf文件,修改成default.ttf。
  第四步:将这三个文件放到一个文件夹里,然后放到SD卡的ons目录下,安装中文模拟器即可开始游戏。
  第四步(附):假如这个游戏很大,很占用空间可以通过解包封包的方式来压缩空间,在文件中有说明文档可以参考。
相关文章:ONS游戏模拟器下载 ONS游戏模拟器 ONS游戏模拟器教程 onscripter
图解新闻:
最新攻略:
24小时更新:
热门排行本周本月
推荐文章本周本月安卓自己移植galgame的教程_百度知道
安卓自己移植galgame的教程
有高手知道吗?尽量详细一点。
我有更好的答案
请去acgfuture贴吧看,如果游戏是ns引擎的,直接丢手机里,加个字体文件即可,至于别的,建议lz加入其研究小组,另,订尝斥妒俪德筹泉船沪请期待10.15acgf上线发布的clannad 和air......———————————————————请了解下,高手不会来这里的,网上只有ns移植的教程,只有去请教,没有送上门的道理
其他类似问题
为您推荐:
安卓的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁查看: 89714|回复: 746
交易诚信度0 最后登录注册时间阅读权限60UID2148585帖子狩魂0 在线时间489 小时
猥人师表 Lv.6, 积分 2109, 距离下一级还需 2891 积分
UID2148585积分2109帖子精华0浮云1013 猥币837 汽油1
本帖最后由 欧夏 于
10:45 编辑
安卓上的GALGAME移植模拟器 Onscripter
【整理】Android用户的福音-GALGAME运行软件Onscripter for Android
1L模拟器使用教程
2L Android移植游戏下载
ONScripter
  原身为NScripter,经过linux的改进出现了ONScripter。
  ONScripter是一个通用GalGame引擎,被很多同人乃至商业AVG游戏所采用,包括《月姫》《ひぐらしのなく顷に》(寒蝉鸣泣之时)《ToHeart》《月は东に日は西に》《银色》《朱-Aka-》等。其中使用NS(NScripter)的著名Gal《水仙》是很棒的代表作。
  同时,在PSP、DS甚至android、PPC和Symbian s60V3/V5平台上也出现了各种ONS(ONScripter)版本,其中的资源和脚本文件互通,是一款不错的用来运行galgame软件。例如荼荼丸用ONS移植的PSP版本《夜明前的琉璃色》,经过一定的修改之后也甚至可以在WM和android手机上运行,当然也有国产精品魅族M8的ONS版本。
第一步 下载游戏
下载Android专用的移植游戏。(请到2L)
标志是arc.nsa和nscript.dat这两个文件。
安装模拟器到Android设备上
游客,如果您要查看本帖隐藏内容请玩日文游戏请安装ONScripter-JP.apk
玩中文游戏请安装ONScripter-GBK.apk
这两个游戏的签名是一样的 所以暂时不能同时安装在系统中
关于字体:
default GBK.ttf 简体中文字体文件,使用的时候请改名为:default.ttf
default JP.TTF 日语字体文件,使用的时候请改名为:default.ttf
ONScripter-GBK.apk 简体中文ONS模拟器,运行中文游戏时请安装这个,并配合default GBK.ttf使用
ONScripter-JP.apk 日语ONS模拟器,运行日语游戏时请安装这个,并配合default JP.TTF使用
在新建一个文件夹ONS在TF卡中 解压游戏 把解压后的文件夹置于ONS这个文件夹中
在设备中找到ONS模拟器并且打开游戏~OK
送你葱!送你葱!!送你葱!!! ...
祝天下考生考出好成绩
总评分:&浮云 + 17&
We can still be free.
交易诚信度0 最后登录注册时间阅读权限200UID5453153帖子狩魂0 在线时间4941 小时
UID5453153积分37034帖子精华0浮云24731 猥币16056 汽油0
各种流弊。。。。。。。。。
安卓给力啊
欧夏厉害啊 感谢分享了
交易诚信度0 最后登录注册时间阅读权限80UID9672518帖子狩魂0 在线时间1747 小时
Happy Tree Friends
猥风八面 Lv.8, 积分 14636, 距离下一级还需 15364 积分
UID9672518积分14636帖子精华0浮云10779 猥币6824 汽油0
落在世界上空的是神的颜色
交易诚信度1 最后登录注册时间阅读权限150UID5156869帖子狩魂0 在线时间4923 小时
即使永夜,我也要前进,因为星光即使微弱也会为我照亮前进的道路
UID5156869积分53004帖子精华0浮云16496 猥币159600 汽油70
这帖子总结的真心好~
可以在地址上加上回复可见。。
ios用户泪目{:4_560:}
交易诚信度0 最后登录注册时间阅读权限5UID4991162帖子狩魂0 在线时间4 小时
猥不足道 Lv.2, 积分 110, 距离下一级还需 90 积分
UID4991162积分110帖子精华0浮云6 猥币501 汽油0
不错,支持
交易诚信度0 最后登录注册时间阅读权限5UID2443403帖子狩魂0 在线时间27 小时
猥不足道 Lv.2, 积分 91, 距离下一级还需 109 积分
UID2443403积分91帖子精华0浮云0 猥币315 汽油0
novo8大爱啊。。。。。
交易诚信度0 最后登录注册时间阅读权限80UID9472528帖子狩魂0 在线时间436 小时
猥风八面 Lv.8, 积分 13493, 距离下一级还需 16507 积分
UID9472528积分13493帖子精华0浮云414 猥币63131 汽油1
有点想入手android了,原先还想买iphone的说~
APP里有很多官方移植的AVG
总评分:&浮云 + 1&
A secret makes a woman woman.
交易诚信度0 最后登录注册时间阅读权限30UID5915733帖子狩魂0 在线时间167 小时
猥乎其微 Lv.3, 积分 259, 距离下一级还需 241 积分
UID5915733积分259帖子精华0浮云1 猥币707 汽油0
这么强大!
交易诚信度0 最后登录注册时间阅读权限1UID998868帖子狩魂0 在线时间46 小时
猥时尚早 Lv.1, 积分 47, 距离下一级还需 3 积分
UID998868积分47帖子精华0浮云1 猥币1573 汽油0
NB 给力啊~~~~~~~~~
交易诚信度0 最后登录注册时间阅读权限5UID4988974帖子狩魂0 在线时间12 小时
猥不足道 Lv.2, 积分 149, 距离下一级还需 51 积分
UID4988974积分149帖子精华0浮云22 猥币577 汽油1
感谢分享啊!
交易诚信度0 最后登录注册时间阅读权限80UID40467帖子狩魂0 在线时间773 小时
猥风八面 Lv.8, 积分 16442, 距离下一级还需 13558 积分
UID40467积分16442帖子精华0浮云416 猥币77159 汽油0
htc的都是Android的吧,最近買了部,能玩就爽了
总评分:&浮云 + 1&
这个世界并不存在什么奇迹,有的只是必然与偶然,还有自己要做什么,仅此而已
交易诚信度0 最后登录注册时间阅读权限140UID918帖子狩魂0 在线时间8622 小时
二塌糊涂の人生
UID918积分37147帖子精华0浮云22456 猥币27581 汽油40
教程美。。
移植模拟器。。好高深
木有手机的情何以堪。。。{:4_717:}
交易诚信度0 最后登录注册时间阅读权限1UID帖子狩魂0 在线时间0 小时
UID积分7帖子精华0浮云0 猥币35 汽油0
BIXU HUIFU
请认真回帖 尊重作者
总评分:&猥币 -20&
交易诚信度0 最后登录注册时间阅读权限5UID帖子狩魂0 在线时间120 小时
猥不足道 Lv.2, 积分 171, 距离下一级还需 29 积分
UID积分171帖子精华0浮云3 猥币476 汽油0
虽然手机很少用来玩游戏,不过还是支持了~
交易诚信度0 最后登录注册时间阅读权限100UID6225505帖子狩魂0 在线时间11997 小时
UID6225505积分149018帖子精华0浮云65500 猥币107357 汽油1
{:4_717:}不是Android用户的撸过...我想换手机了...
FC:95& &港服PSN:DN-ZERO
管理团队【光辉事迹】
猥皮大本营管理团队特有的红色令牌。象征权力与责任的契约之证。(担任过论坛各级版主)
菁英组长【稀有成就】
特殊用户组组长所持有的黑色令牌。象征着团队协作的光辉之证。(担任过特殊用户组组长/负责人)
常客【普通成就】
《我的业余生活》从前有一个论坛叫TGBUS…(在线时间超过1000小时)
水元素【普通成就】
水、H2O、みず、water,额...总之怎么叫都行了
(累计发帖1000即可解锁)
水精灵【稀有成就】
我很喜欢水,因为这就是我存在的意义...(累计发帖10000即可解锁)
浮云爱好者【普通成就】
一朵,两朵,三朵,呵呵呵… (累计获得1000朵浮云)
浮云收藏家【稀有成就】
已经收藏到这么多浮云了吗,不错嘛!(累计获得5000朵浮云)
浮云鉴定砖家【光辉事迹】
浮云对你来说,已经没有秘密了!(累计获得10000朵浮云)
银质奖杯【稀有成就】
差点就是第一名了! --不甘心的菲尼如是说(曾在论坛任意板块内组织的活动中获得第二名)
S·P·Y【稀有成就】
呵呵想揭下我的面具看看我的真实身份吗?知道的人都死光了哦……(同时列名于3个以上用户组)
我的朋友很多【普通成就】
朋友不只是踏脚石,偶尔也可以当坐垫的哦(好友数超过100名)
帖!帖!帖!【稀有成就】
一呼百应,号令群雄,说的就是我了(发布过一个主题帖并有超过1000个回复。资源、回复可见贴不可)
成就猎人Rank.D【普通成就】
你已经踏上了成就收集的不归路,5个成就怎么可能满足你的需求,继续努力吧! (获得累计超过5个成就--不包括负面成就)
成就猎人Rank.C【稀有成就】
随便玩玩就拿到这么多了,SO EASY,妈妈再也不用担心我的成就 (获得累计超过10个成就--不包括负面成就)
2014大力神杯【稀有成就】
恭喜你取得了本届大力神杯(2014巴西世界杯)
优秀版主【光辉事迹】
辛勤的版主,总是在大家已经休息的时候一个人默默地…删广告??! (在季度优秀版主评比中获得殊荣)
大负翁【普通成就】
老爷太太,赏点碎银子买碗粥吧。。。我的碗都破成这样了(负面成就,不计入成就猎人数量。猥币≤-1,为此而版主协助违规扣分或将面临严惩)
大少爷的修养【稀有成就】
土豪什么的才不符合我的身份,我是品行端庄努力上进的绅士。嗨,baby……人生是需要relax的~~(在猥皮大本营的加油站一次性充了100汽油)
小千金的癖好【普通成就】
作为大型玩具公司董事长女儿的我,只有在给小樱做漂亮衣服的时候,才能让我体会到作为一个有钱人的好处 (在猥皮大本营的加油站充过5汽油)
论坛贵宾【光辉事迹】
曾为论坛做出过杰出贡献的版主、会员所持有的徽章。象征丰硕成果的华美之证。(获得“论坛贵宾”头衔)
略疼【稀有成就】
(续《我的业余生活》2)我在那里…消磨了大量的… (在线时间超过5000小时)
与猥皮共成长【史诗成就】
日…值得纪念 (注册时间显示于日)
我哭给你看【普通成就】
又没中奖!!再不给我抽中我就哭给你看!我要水漫猥皮大本营!(连续7次参与论坛正版游戏抽奖仍未成功抽中)
日常【光辉事迹】
(续《我的业余生活》3)人参啊……(在线时间超过10000小时)
水魔神【光辉事迹】
哦…哦…力量,我感觉到了力量,这种静谧的意志所转化而成的肃正之力,究竟是……(累计发帖100000即可解锁)
无双的水神【唯一成就】
您…您就是海神波塞冬吧?!--吟游诗人Garsiazero如是说(全论坛第一个发帖量达到200000者)
浮云创造者【史诗成就】
我越来越强烈的意识到,浮云就是你创造的!(累计获得30000朵浮云)
Floating Clouds【唯一成就】
你已经参透了浮云的真谛,发现自己也是一朵浮云…(全论坛第一个获得50000朵浮云者)
Lucky☆Star【稀有成就】
什么!你在发完申请贴截图的时候没被人撒云?实在是太幸运了,让我抱抱你的大腿吧!(规则改为:总积分正好=或777777)
海贼王的宝藏【光辉事迹】
想要我的财宝吗?想要的话就给你吧,去找吧,伟大航路,我把世界的一切都放在那里,ONE PIECE! (在猥皮大本营的加油站一次性充了500汽油)
邪恶贵族的继承【史诗成就】
有爵位,领土,和美丽的未婚妻,那又如何?我的一生只为复仇! (在猥皮大本营的加油站一次性充了200汽油)
铜质奖杯【普通成就】
好歹有个名次,哈哈哈哈哈(曾在论坛任意板块内组织的活动中获得第三名)
金质奖杯【光辉事迹】
比赛第一,友谊第二!(曾在论坛任意板块内组织的活动中获得第一名)
正版党【光辉事迹】
不是咱要晒正版,实在是游戏太好玩(自曝拥有任意平台10款以上的正版游戏)
全主机制霸之环【光辉事迹】
首先我要感谢我的把拔马嘛,还要感谢各种TV,感谢@#%&*…让我拥有现世代所有的游戏机。(PSP、PSV、NDS、3DS、PS3、XBOX360、WII、WII U、PS4、XBOX ONE)
成就猎人Rank.B【光辉事迹】
达人?=,=是在侮辱我吗?!我是神,我是,我…… --从此无人知其下落 (获得累计超过20个成就--不包括负面成就)
Powered by谈谈AVG游戏的Android移植(NScripter与吉里吉里) - cping - 博客园
大家好,很久不见,小弟最近闭关修炼iPhone中,所以很长时间没更新博文(顺便在写某物的C++版,另外某物0.3.2版与WP7版已构建完成,不久就会发布)。这次回来,先换个与某物无关的话题,以目前用户量最大的NScripter(简称NS,以下同)与Krkr2(吉里吉里2)为代表,来简单谈谈 AVG游戏的Android环境移植吧。______________关于NScripter的Android版移植:ONS和SDL:大家都知道,日本人高桥直树是NScripter项目的发起者。然而,事实上高桥直树开发的原始版NS程式早在09年就已经停止了更新,现今已很难再看见利用原版NS开发的程式。那么,NS为何还能有现在这么庞大的用户支持率呢?答案很简单,一切都要归功于ONS的存在。应当说,目前应用最广,也是真正让NS脚本发扬光大的,还要数第三方制作的ONScripter,这一完整支持NS脚本的跨平台AVG引擎不可(简称ONS,以下同)。单独从编程角度上讲,ONS不等同于NS,由于高桥氏开发的NS程式并没有开放源码,因此ONS是通过黑盒方式参考NS效果自行模拟出的ONS功能(这个过程有点像制作游戏机模拟器),所以它并不是一个代码移植品,而应视同一个独立于NS原版的新型NS脚本解释与执行器。除了能解读同样的游戏脚本外,它与 NS就没有任何程式上的继承关系。ONS相比较NS的最大优势在于,ONS和完全依赖DirectX渲染仅支持Windows系统的NS不同,它采用了一代神人Slouken制作的SDL框架进行脚本与计算机设备交互,天生具备SDL框架“骇人听闻”的跨平台移植能力。无论是windows、linux、mac抑或PSP、PS3、PS2gs乃至wince、iphone、ipod、android平台都能看到它活跃的身影(当然,这需要相关的本地运行库配合,比如从渲染角度上讲,在Windows绘制画面既可以使用SDL提供的DirectX封装又可以使用OpenGL 封装,而到了Linux环境就只能使用OpenGL库,到了智能机或者掌机环境就要转到OpenGLES库,这些都必须有人提供相关的本地化封装,然后才能通过统一的API进行调用。即便所写代码在API层面高度一致,但在不同环境中的具体实现依旧是有差异的。也就是说,如果某个平台并没有必要的运行库支持,那么SDL也无法在该平台编译与运行。而SDL的强悍就体现在,它所提供的本地运行库相当完整,几乎涵盖了所有主流系统,兼容性却又相当优异)。凭借这种优势,目前大家所见的,绝大多数使用NS脚本开发的AVG游戏(或者狭义的指galgame),大多是以ONS而非原版NS作为运行环境——在掌机和智能机上尤其如此。可以说,没有SDL的成功,就没有今天的NS(ONS)的辉煌。这里吐个槽,前一阵小弟在某书店读到某Android教程,其中以NDK5编译了某版本的《雷神之锤》,而后就反复强调NDK移植C/C++游戏是多么方便,多么简单之类的。小弟以为,这种说法实在有些忽悠了。众所周知,网上能找到的开源版《雷神之锤》(),使用的就是SDL这个目前世界上兼容性最强的跨平台引擎(而SDL子项目,早已提供了SDL与Android设备的完整交互支持)。因此,即便NDK5能正常编译SDL开发的游戏,也只能证明NDK5的基本功能正常(Android好歹也是Linux核心,如果SDL在上面都跑不起来,让Google情何以堪啊),却无法理解成NDK开发有多么便捷,更不能代表所有 C/C++游戏都能轻松移植到Android环境当中(此前小弟曾和某友谈及怎么常有人能把DOS游戏移植到Android环境中运行的问题,小弟在此粗谈两点:一、世上有个开源项目叫DosBox,能够跨平台模拟标准DOS运行环境。二、DosBox是以SDL为核心开发的),就别提完全取代Java开发模式了。我们登录,就可以获得关于标准版ONS的详细介绍与各版本下载路径。至于ONS-Android,则是由ONS作者提供的,完全实现了ONS功能的,专门用于跑在Android平台的ONS版本。如果您要在Android上进行NS游戏移植,首先就离不开ONS-Android的下载与编译。ONS-Android的编译:ONS-Android的编译,仅需要如下步骤就可以做到。1 下载SDL的Android版扩展库由于标准版SDL源码包中尚未包括Android本地化支持,所以我们需要单独下载Android版SDL源码包,才能在Android环境中正常编译与运行SDL程序。事实上,所有想使用SDL以C/C++方式开发Android游戏的用户,也会需要这个SDL运行库的支持。下载地址:(PS: ONScripter-Android内置已是这个运行库,不必真正下载,此处仅说明来源)。2 下载Android版ONScripter下载地址:由于ONS-Android采用JNI方式,进行C/C++部分与Java部分的交互,因此下载后的源代码也就同时包含了java(功能集中在游戏载入,界面初始化与JNI调用)与纯C(sdl-android支持库)两大部分的源码。不过,真正解释执行NS脚本的ONScripter本体(C++实现)这时却并没有包含在内(估计是作者考虑到ONScripter核心代码是所有平台共通的,才没有直接放入ONS-Android当中)。现在,我们还需要下载ONScripter的核心源码部分,才能真正进行ONS-Android编译。3 下载标准版ONScripter下载地址(也可选其它版本):好了,编译ONS-Android的要素全部齐备了。现在,将最后下载的ONS核心源码解压,并放入onscripter_android的jni\application文件夹下(建议解压时不要改名,因为 ONS的Android.mk配置里默认就是编译onscripter*下文件,改名很可能导致找不到目标文件(除非您重写了Android.mk配置))。这时,我们只要通过NDK编译onscripter_android项目,就能立刻得到相关的so文件了(累计将编译出九个文件,其中只有libapplication.so为ONS运行库,其余为SDL支持库),相当之简单吧?下图为通过Cygwin在Windows中编译ONS的画面。&可以说,只要系统环境设定正常,原始ONS-Android配置已可保证编译成功。假如在编译时提示找不到某某文件,则说明环境变量中缺少必要的系统支持库路径,并非onscripter_android源码不全,请自行在Android.mk添加相关路径或者修改Cygwin环境配置,具体请参考NDK开发文档或Cygwin使用文档(当然,直接Ubuntu编译最简单)。编译成功后,获得的so文件列表:&有了so支持库与Java代码,任何稍有Android(或Java)开发经验者,都能轻易将NS游戏运行于Android系统之上。ONS-Android的汉化问题:出于众所周知的原因,ONS-Android默认并不支持中文编码(它是日本人做的)。这样的设计,在使用原版ONS-Android运行日文游戏时并不会有太大问题(只要该游戏没有调用第三方插件,没有使用额外API)。但是,一旦我们想要让它跑一些经过汉化的中文编码游戏呢?显而易见,肯定会造成乱码的出现。所以,如果我们想要ONS-Android能够正常地进行中文游戏显示,在进行ONS-Android编译时,便需修改其部分代码。更准确地说——是修改位于ONS核心包下的sjis2utf16.cpp文件来解决这一问题。总体来讲,ONS的字符解码过程并不复杂,sjis2utf16.cpp中仅有initSJIS2UTF16(初始化解码表到sjis_2_utf16这一数组中)、convSJIS2UTF16(转化日文编码SJIS为UTF-16编码)、convUTF16ToUTF8(转化UTF-16为UTF-8编码)这三个函数在起作用。而ONS的所有字符解码部分也会经由调用convSJIS2UTF16和convUTF16ToUTF8这两个函数产生作用(注意,initSJIS2UTF16是sjis_2_utf16变量初始化赋值时使用的函数,仅会在ONS启动时调用一次)。知道了这些,解决汉化问题就变得非常简单,只要根据现有的ONS解码规则,将其sjis_2_utf16_org数组中的SJIS日文编码表转化为我们需要的中文编码表(GBK也好,Big5也好,原理都一样,一个指定编码对应一个相对的UTF-16编码,然后以二维数组形式保存),就能够非常轻松的实现 ONS中文解码,甚至不需改写任何逻辑代码(如果有某些字符需要特殊过滤,也可以修改convSJIS2UTF16和convUTF16ToUTF8这两个函数进行拦截)。编码表较大,下文有相关下载地址。当然,如果我们想保留原版sjis2utf16.cpp内容也没问题,大可以新建一个gbk2utf16.cpp之类的文件,让两套解码器并行存在,按需求进行切换(比如想根据手机环境自适配字符解码器)。怎么做呢?粗读ONS源码我们可以发现,它实际调用到字符解码器的部分,仅集中于DirectReader.cpp和 ONScripterLabel.cpp、ONScripterLabel_text.cpp这三个源文件当中。具体的说,在于DirectReader 中的convertFromSJISToUTF8函数(其中同时调用了解码器的convSJIS2UTF16与convUTF16ToUTF8函数。 PS:该文件中还有convertFromSJISToEUC函数,是给资源文件名解码的,如果文件名中没有稀奇古怪字符的话原则上可以忽视不管,如果有的话也需要进行适当修改),以及ONScripterLabel_text.cpp中的drawGlyph函数(调用convSJIS2UTF16)和 ONScripterLabel中的initSDL函数(调用initSJIS2UTF16)。如果想自适配解码器,只需创建出相关的解码用函数(放在 gbk2utf16.cpp、big52utf16.cpp随便什么中原理都一样,改个编码表而已),继而通过最简单的if……else……判定即可(如果想根据编译环境判定,直接#if defined也行)。总之,ONS中文解码并不是什么复杂的问题,汉字编码表可以去查询,或者参考Emacs项目提供的map文件(下载一个Emacs,解压后它的etc/charsets文件夹下全是后缀为.map的编码表)。还有,很久以前有人用google code发布过ONS的gbk解码版本(),有需要的朋友可以从svn下载过来参考。ONS-Android的运行机制:单从Java编程角度来说,ONS-Android的结构可谓非常简单,开放给用户的仅有Audio.java、DataDownloader.java、 GLSurfaceView_SDL.java、ONScripter.java、Video.java这五个Java文件而已(因为具体实现是 C/C++的)。其中Video.java最为重要,它包含有DemoRenderer和DemoGLSurfaceView两个子类,这不单是ONS- Android的渲染核心,而且包含了nativeInit, nativeInitJavaCallbacks, nativeDone,nativeResize,nativeMouse,nativeKey等六个jni接口。其中最主要的接口是 nativeInitJavaCallbacks以及nativeInit,只有执行了这两个jni函数,才能真正启动ONS(本质上是先启动SDL框架,附带唤醒ONS)。而执行nativeInit函数时需要注入的地址字符串,默认来源于 ONScripter类下的gCurrentDirectoryPath这个静态变量。不管我们往gCurrentDirectoryPath中放入什么字符串,默认情况下ONS都会按照这个字符串去读取/保存游戏资源(如果不能找到该路径,则ONS会立即崩掉)。至于其它,nativeDone是关闭SDL(由于ONS依赖于SDL,所以这些操作实际上都会先执行SDL部分,然后才转到ONS部分,以下同),nativeResize是改变SDL画面大小,nativeMouse触发SDL屏幕操作,nativeKey触发SDL键盘操作,皆属基础操作,并没太多好讲解的。PS:上述部分jni源码位于onscripter_android\jni\sdl\src\video\android文件夹下,如果要修改Java类名或接口名,请注意同时修改相关C代码。而 ONS-Android的启动用Activity是ONScripter类,其中真正调用ONS运行的只有runSDLApp这个私有函数,至于 runLauncher及runDownloader函数一者为要求游戏用户选择ONS资源所在路径,一者为通过网络下载ONS游戏资源,都只会在 runSDLApp执行前调用,也不会实际触发jni接口(只有runSDLApp触发jni操作)。所以,如果您不想让游戏用户使用您的APK启动其它人提供的游戏资源(也就是不想被人当模拟器用),则可以删除runLauncher函数,或者固定gCurrentDirectoryPath变量中路径字符串即可。再者,游戏初始化后默认显示于画面右侧的仅仅是Java编码的ONS操作按钮(如ESC、Skip 这些),它们仅会通过JNI方式调用相应的SDL API,而不会真正影响C/C++实现部分。因此,如果您需要改变它们的显示位置,或者进行删除、修改这些按钮的操作,乃至用其它方式彻底替代它们(比如将相关JNI调用放入Menu中,按下菜单键时才起作用),都只需修改相关Java代码即可,无需改变任何C/C++部分。另外,通过解读源码我们可以获悉,在ONS-Android初始化运行时,有三种文件必不可少。一是脚本文件,它可以命名为0.txt、00.txt、nscr_sec.dat、nscript.___、nscript.dat这五种名称中的任意一种(后三种都属于NS的dat文件包,需要通过工具打包,网络有下载),但除此之外的名称一概不认,没有则无法运行游戏。二是游戏资源文件,也就是NS中使用的arc.nsa,游戏中使用的音频与图像文件强制要求打成此包(NS提供有打包工具),并且保持此名称不变,否则ONS还是不认。三是default.ttf,也就是字库文件,由于ONS-Android默认情况下不能使用Android字库,所以此文件必须存在,并且正常可读(必须能够被SDL识别),否则游戏会强制退出(没错,如果字库不存在或者读取异常,ONS直接就崩了~连错误都不报~)。有了上述三种文件,ONS才能在 Android中正常运行。最后,虽然AVG游戏通常需要较大的音频与图像文件支持,Android版ONS默认要求将游戏资源文件保存于SD卡中。但经实测发现,如果将gCurrentDirectoryPath设定为其它可读写目录,只要上述三文件正常无误,ONS-Android一样能正常运行(比如APK的Cache文件夹)。所以,如果我们想对游戏资源作一些手脚(在内存而非SD卡中进行游戏什么的),完全可以根据此特性入手。ONS-Android的运行效果:真机运行效果:模拟器运行效果:(虽然ONS-Android默认使用GLES,可惜Android模拟器默认只支持PixelFlinger,因此建议真机测试,否则速度相当悲剧)关于Krkr2(吉里吉里2)的Android版移植谈完了ONS的移植,下面再来谈谈Krkr2这个著名的AVG引擎(其实,主要是做galgame~)的Android移植问题。 那么,开章明义,大家请首先注意好这一句话:在Android中“直接运行”Krkr2游戏是不可能的虽然仅就Windows系统而言,Krkr2游戏量远远超过NS游戏在这一领域的数量。并且Krkr2系统无论在操作方式、画面效果、脚本功能都较古老的 NS系统更为先进。然而,以下三点因素却决定了在Android系统中,向ONS那样直接运行Krkr2游戏资源将非常难以实现(其实任何系统都一样)。一、首先,ONS源码不算SDL支持库,其大小仅有1MB左右,可谓短小精悍。而Krkr2呢? 仅core包下核心源码就有将近10MB,代码量比ONS多了将近10倍(还不算plugins包下的一些必要插件),仅此一项就让移植Krkr2比移植 ONS所面对的工作量大了许多(代码越多,出Bug的机会也就越高)。二、其次,ONS直接使用SDL框架开发,令它先天具备相当强大的跨平台特性(前文已述,SDL纯C打造,正宗的“一次编写,随处编译,随处运行”)。反观吉里吉里,W.Dee独立开发的 Krkr2核心显然没能达到SDL的高度,他在开发之初甚至就没考虑过跨平台的问题,因此要将它跨平台移植时所面临的问题也就可想而知。比如Krkr2默认使用DirectX而非OpenGL,又不像SDL那样为每个平台都制作了必要的自适配图形接口,导致它的渲染功能被绑死在 Windows平台上,如果要移植只能重写渲染部分不算;最要命的是,它还大量使用win32 API,先天与Windows系统难以分离,否则很多效果都要从头摸索如何实现;并且,Krkr2还非常随性的提供第三方接口,毫无原则的允许大量第三方插件跑在Krkr2之上,直接导致很多游戏根本不是仅仅解决Krkr2运行环境就能够移植的。事实上,如果想让Krkr2正常运行在非Windows平台,没有相当大规模的代码重构(注意,是重构,而不是简简单单的修改),根本不可能实现(总不能在Android上跑个Windows模拟器吧|||)。事实上,Krkr作者为解决跨平台问题,自2005年起已着手制作Krkr3,至今依旧努力中……三、最后,Krkr2基本结构是由一套C++核心(含基于DirectX的图像渲染部分及tjs脚本解释器与kag脚本解释器以及其它功能的复合),一套tjs 脚本库(依赖C++编译出的解释器运行,Krkr2特有的脚本语言,语法类Java),以及一套构建于tjs脚本及C++代码之上的kag脚本库(与 NScripter类似的命令行脚本,通过TJS脚本解释器与KAG解释器混合执行)这三大部分组成。简单点说,Krkr2在核心程序上运行着两个有嵌套关系,但关系又不那么紧密的解释器,以一种不完全的,近似于模拟器上跑模拟器的形式存在着。虽然这种方式在 Windows环境中运行AVG游戏,甚至更复杂一点的游戏(比如RPG)都不会存在太大问题(现代CPU的速度优势)。然而,一旦迁移到手机或智能机环境中,这种方式所带来的后患将相当严重,庞大的资源损耗,将直接影响程序的运行效果(没见过模拟器跑模拟器多恐怖的朋友,可在Windows系统下运行 android 3.0模拟器体验类似的“速度感”PS:题外话,Android模拟器截至到3.0为止,在PC机上的运行速度一直逆增长,版本越高速度越慢,用 android1.5反而会比3.0快很多)。综上所述,大家应该可以发现,如果想完整移植Krkr2游戏的运行环境到Android系统当中,将会是一件多么费力,而且很可能未必讨好的事情,就算有高人能完整的重构整个Krkr2项目到Android系统,最终也未必会在Android系统(或其它什么智能机平台)跑出“人类能够接受”的游戏速度来。更简单的讲,完整移植Krkr2的难度相当之大,没能力者肯定做不到跨平台完整移植Krkr2。而某些有能力者呢?大约也没人会穷数月乃至数载之功,一丝不苟得做完Krkr2的完美移植,却平白开源出来给不相识的人免费使用(特别是原作者都没做到跨平台的时候……)。所以,想和ONS一样近乎不改变任何游戏资源,直接在Android上运行现有NS游戏的美梦——是绝对不可能实现的。在Android中实现Krkr2游戏移植是可行的事实上,如果大家曾注意Android Market的AVG游戏动向,就会发现除了ONS的移植作品之外,还会有一些其它形式的AVG移植作品存在。但是,如果我们解压其APK,却很难发现诸如nscript.dat、arc.nsa这样明显的,和原版游戏同样的资源包存在。那么,他们是怎么做到的呢?很简单,他们所采用的手段是真正意义上的游戏移植,而非ONS那样近似于游戏模拟器的重构了整个NS运行环境。以Krkr2游戏移植为例,目前Android市场上可见的吉里吉里移植作品,大多仅仅模拟出了最容易实现的KAG3脚本部分,而无视TJS2脚本的存在,至于相应功能,则使用LUA脚本替代或者直接Java编码补全。这样做虽然远没ONS移植省力,但在Krkr2运行环境几乎不可能在智能机完整再现的如今,也总比自己强行重构Krkr2,再来用它运行游戏要高效得多了。——至少目前已知的,所有Krkr2游戏的Android移植项目,都是这样开发出来的。而下文介绍的KAS项目,就是一个非常典型的Krkr2-Android版移植实现。项目地址:源码下载:KAS参考Krkr2脚本实现,可以部分支持KAG3脚本(标准KAG脚本命令大约有150个左右,截止到6月23日的KAS中实现了不足1/3,而且完全不支持TJS脚本),脚本命名方式同样是.ks为后缀。PS:突然发现一篇博文不可能写全,所以紧急收笔,有时间小弟将单独介绍KAS。下面是小弟贴出的一个KAS中TagHandlers类(翻译后的),其中包含了KAS目前所支持的全部标准KAG指令,另外下文有部分翻译后的KAS项目工程下载地址。*****************package net.studiomikan.
import java.util.HashM
import java.util.TreeM
// 标签对象集合(KAS的脚本解析方式是将所有同指令的命令都放在一个集合中,所以有此接口)
interface TagObject
public void run(HashMap&String, String& elm);
// 标签集合处理器
public class TagHandlers
private TreeMap&String, TagObject& tagHandlersMap =
private MainSurfaceV
public TagHandlers(MainSurfaceView owner)
tagHandlersMap = new TreeMap&String, TagObject&();
getTagHandlers(owner);
// 返回指定标签名下属的所有脚本集合
public TagObject getTagObject(String tagName)
return tagHandlersMap.get(tagName);
// 当传递的MainSurfaceView不为null时,则根据MainSurfaceView中的脚本数据构建出完整的标签树
public void getTagHandlers(MainSurfaceView owner)
if(owner == null)
this.owner =
getTagHandlers();
//PS:KAS并没有完整的实现KAG脚本,下面给出的脚本指令不足标准KAG的1/3
public void getTagHandlers()
// 停止执行脚本
tagHandlersMap.put(&s&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_s(); }});
tagHandlersMap.put(&wait&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wait(elm); }});
tagHandlersMap.put(&r&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_r(); }});
// 消去消息层的文字
tagHandlersMap.put(&er&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_er(); }});
// 重构消息层MessageLayer
tagHandlersMap.put(&ct&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_ct(); }});
// 清空全部消息层中的文字
tagHandlersMap.put(&cm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_cm(); }});
// 显示完一页的消息后必须点击屏幕才允许换页
tagHandlersMap.put(&p&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_p(); }});
// 文字显示到行末时必须点击屏幕才允许换行
tagHandlersMap.put(&l&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_l(); }});
// 瞬间显示出全部文字
tagHandlersMap.put(&nowait&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_nowait(); }});
// endnowait
// 结束瞬间显示全部文字模式
tagHandlersMap.put(&endnowait&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_endnowait(); }});
// position
// 消息层的属性设置
(1)对象层位置:layer = message/message0/message1
(2)页面类型:page = fore/back
(3)层是否可见:visible = true/false
(4)层的颜色:color = 整型色彩值
(5)不透明度:opacity = 0(完全透明)~255(完全不透明)
(6)层左端位置:left = 0 以上整数
(7)层上端位置:top = 0 以上整数
(8)宽:width = 0 以上整数
(9)高:height = 0 以上整数
(10)Layer图像:frame = &Layer名&
(11)Layer图像的透明色:framekey = adapt/整型色彩值
(12)左方边距:marginl = 0 以上整数
(13)上方边距:margint = 0 以上整数
(14)右方边距:marginr = 0 以上整数
(15)下方边距:marginb = 0 以上整数
(16)纵向书写模式:vertical = false(默认)/true
(17)是否允许用鼠标拖动:draggable = false(默认)/true
tagHandlersMap.put(&position&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_position(elm); }});
// 标准层的属性设定
(1)对象层位置:layer = message/message0/message1/0/1/2……
(2)页面类型:page = fore/back
(3)层是否可见:visible = true/false
(4)层左端位置:left = 0以上整数
(5)层上端位置:top = 0以上整数
(6)不透明度:opacity = 0(完全透明)~255(完全不透明)
(7)消息层是否需要隐藏:autohide = true/false
(8)重叠顺序:index = 0以上整数
tagHandlersMap.put(&layopt&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_layopt(elm); }});
// 读取图像
tagHandlersMap.put(&image&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_image(elm); }});
// 跳转到指定脚本脚本
(1)要跳转到的脚本文件:storage=&文件名.ks&
(2)要跳转到的标签名:target=&*标签名&
(3)是否将这个跳转之后的部分看作“已读”:countpage=false(默认)/true
tagHandlersMap.put(&jump&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_jump(elm); }});
// 跳转到指定脚本文件里并执行相应标签
(1)要跳转到的脚本文件:storage=&文件名.ks&
(2)要跳转到的标签名:target=&*标签名&
(3)是否将这个跳转之后的部分看作“已读”:countpage=false(默认)/true
tagHandlersMap.put(&call&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_call(elm); }});
// 返回指定的脚本位置
(1)要跳转到的脚本文件:storage=&文件名.ks&
(2)要跳转到的标签名:target=&*标签名&
(3)是否将这个跳转之后的部分看作“已读”:countpage=false(默认)/true
tagHandlersMap.put(&return&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_return(); }});
// current
// 指定当前操作的消息层
(1)层名:layer = message/message0/message1
(2)页面:page = fore(默认)/back
(3)是否需要同时写入背景页面(BackPage)中:withback = false/true
tagHandlersMap.put(&current&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_current(elm); }});
// 命令游戏层进行渐变转换(这个渐变效果是根据分解渐变图像素而生成的,所以在Android模拟器中很慢……)
(1)渐变转换的时间:time = 0 以上整数(毫秒)
(2)渐变转换的类型:method = universal(自定义,默认)/ crossfade(淡入淡出)
(3)对象层:layer = message/message0/message1/base/0/1/2
(4)是否包含子层:children = true(默认)/false
(5)转换规则图像(仅当method = universal时有效):rule = &图像文件名&
(6)模糊程度值(仅当method = universal时有效):vague = 0 以上整数
(7)卷动方向(仅当method = scroll时有效):from = left/top/right/bottom
tagHandlersMap.put(&trans&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_trans(elm); }});
// backlay
// 将层的前景页面信息复制到背景页面中
tagHandlersMap.put(&backlay&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_backlay(elm); }});
// playbgm
// 播放背景音乐
(1)音效文件:storage=&音效文件名&
(2)是否循环播放:loop=false(默认)/true
(3)音效缓冲编号:0(默认)/1/2
tagHandlersMap.put(&playbgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_playbgm(elm); }});
// 设定背景音乐的属性
(1)音量的百分数:volume = 0~100
(2)最大音量百分数:gvolume = 0~100
tagHandlersMap.put(&bgmopt&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_bgmopt(elm); }});
// stopbgm
// 停止播放背景音乐
tagHandlersMap.put(&stopbgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_stopbgm(elm); }});
// 播放音效
(1)音效文件:storage = &音效文件名&
(2)是否循环播放:loop = false(默认)/true
(3)音效缓冲编号:0(默认)/1/2
tagHandlersMap.put(&playse&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_playse(elm); }});
// 音效设定
(1)音效缓冲编号:buf = 0(默认)/1/2
(2)音量:volume = 0~100(%)
tagHandlersMap.put(&seopt&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_seopt(elm); }});
// 停止播放音效
(1)音效缓冲编号:buf = 0(默认)/1/2
tagHandlersMap.put(&stopse&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_stopse(elm); }});
// 画面震动
(1)震动的时间:time = 0 以上整数(毫秒)
(2)time属性的单位:timemode = ms/delay
(3)横向的最大振幅:hmax = 0以上整数
(4)纵向的最大振幅:vmax = 0以上整数
tagHandlersMap.put(&quake&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_quake(elm); }});
// stopquake
// 停止画面震动
tagHandlersMap.put(&stopquake&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_stopquake(); }});
// 等待画面震动停止
tagHandlersMap.put(&wq&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wq(elm); }});
// hidemessage
// 隐藏消息层
tagHandlersMap.put(&hidemessage&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_hidemessage(); }});
// gotostart
// 回到startanchor标签指定的地点
(1)是否需要确认:ask=false(默认)/true
tagHandlersMap.put(&gotostart&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_gotostart(elm); }});
// 外部链接
(1)要跳转到的脚本文件:storage = &文件名.ks&
(2)要跳转到的标签名:target = &*标签名&
(3)链接色:color = 颜色值
(4)鼠标进入时的音效:enterse = &音效文件名&
(5)鼠标进入时的音效的缓冲编号:entersebuf = 0/1/2
(6)鼠标点击时的音效:clickse = &音效文件名&
(7)鼠标点击时的音效的缓冲编号:clicksebuf = 0/1/2
(8)鼠标退出时的音效:leavese = &音效文件名&
(9)鼠标退出时的音效的缓冲编号:leavesebuf = 0/1/2
(10)是否将这个跳转之后的部分看作“已读”:countpage = true(默认)/false
tagHandlersMap.put(&link&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_link(elm); }});
// endlink
// 结束链接
tagHandlersMap.put(&endlink&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_endlink(); }});
// locklink
// 锁定链接
tagHandlersMap.put(&locklink&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_locklink(); }});
// unlocklink
// 解锁链接
tagHandlersMap.put(&unlocklink&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_unlocklink(); }});
// deffont
// 设定默认的文字属性
(1)字体名:face = &字体名&
(2)文字大小:size = 0以上整数
(3)文字颜色:color = 颜色值
(4)是否粗体:bold = false(默认)/true
(5)是否描边:edge = false(默认)/true
(6)描边颜色:edgecolor = 颜色值
(7)是否显示阴影:shadow = true(默认)/false
(8)阴影颜色:shadowcolor = 颜色值
tagHandlersMap.put(&deffont&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_deffont(elm); }});
// defstyle
// 设定默认的文字风格
(1)字间距:pitch = 0 以上整数
(2)行间距:linespacing = 0 以上整数
(3)列间距:linesize = 0 以上整数
tagHandlersMap.put(&defstyle&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_defstyle(elm); }});
// laycount
// 更改层的数量
(1)普通层的数量:layers = 0 以上整数
(2)消息层的数量:messages = 1 以上整数
tagHandlersMap.put(&laycount&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_laycount(elm); }});
// fadeoutbgm
// 淡出背景音乐
tagHandlersMap.put(&fadeoutbgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadeoutbgm(elm); }});
// fadeoutse
// 淡出音效
tagHandlersMap.put(&fadeoutse&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadeoutse(elm); }});
// fadeinbgm
// 淡入背景音乐
tagHandlersMap.put(&fadeinbgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadeinbgm(elm); }});
// fadeinse
// 淡入音效
tagHandlersMap.put(&fadeinse&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadeinse(elm); }});
(1)对象层:layer = message/message0/message1/0/1/2……
(2)移动的位置:path = &(x1,y1,opacity1)(x2,y2,opacity2)……&
(3)到达一个点 (x,y,opacity) 所用的时间:time = 0以上整数(毫秒)
(4)页面:page = fore/back
(5)加速度:accel = 0(默认)/正数/负数
(6)动作开始前的延迟时间:delay = 0以上整数(毫秒)
tagHandlersMap.put(&move&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_move(elm); }});
// 载入存档
(1)保存的位置编号:place = 0 以上整数(0为默认)
(2)是否需要确认:ask = false(默认)/true
tagHandlersMap.put(&load&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_load(elm); }});
// 保存存档
(1)保存的位置编号:place = 0 以上整数(0为默认)
(2)是否需要确认:ask = false(默认)/true
tagHandlersMap.put(&save&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_save(elm); }});
//------------------------------------------------------------------------------------------
// 系统操作指令
// 自动等待
(1)自动等待输入的文字:ch = &文字对象&
(2)自动等待是否有效:enabled = true/false
(3)等待时间:time = 0 以上整数
tagHandlersMap.put(&autowc&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_autowc(elm); }});
// clearsysvar
// 消除所有系统变量
tagHandlersMap.put(&clearsysvar&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_clearsysvar(); }});
// clickskip
// 在点击画面时允许跳过当前脚本进度
tagHandlersMap.put(&clickskip&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_clickskip(elm); }});
// 脚本结束
tagHandlersMap.put(&close&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_close(elm); }});
// 指定标题
tagHandlersMap.put(&title&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_title(elm); }});
// waitclick
// 在点击画面后才能继续进行脚本解析
tagHandlersMap.put(&waitclick&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_waitclick(); }});
// 设定文字显示间隔时间
tagHandlersMap.put(&wc&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wc(elm); }});
//------------------------------------------------------------------------------------------
// erasemacro
tagHandlersMap.put(&erasemacro&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_erasemacro(elm); }});
//------------------------------------------------------------------------------------------
// 自动阅读模式
// cancelautomode
// 解除“自动阅读”模式
tagHandlersMap.put(&cancelautomode&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_cancelautomode(); }});
// cancelskip
// 解除跳过模式
tagHandlersMap.put(&cancelskip&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_cancelskip(); }});
// 显示文字
tagHandlersMap.put(&ch&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_ch(elm); }});
// 设定文字缩进
tagHandlersMap.put(&indent&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_indent(); }});
// endindent
// 解除文字缩进
tagHandlersMap.put(&endindent&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_endindent(); }});
// 指定文字的显示位置
(1)横方向位置:x = 0 以上整数
(2)纵方向位置:y = 0 以上整数
tagHandlersMap.put(&locate&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_locate(elm); }});
// 文字显示速度
tagHandlersMap.put(&delay&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_delay(elm); }});
//------------------------------------------------------------------------------------------
// 历史数据
// clearhistory : KAS专有,非标准KAG脚本语句
// 清空历史数据
tagHandlersMap.put(&clearhistory&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_clearhistory(); }});
// history
// 历史设定
(1)历史是否可显示:enabled=true/false
(2)是否输出文字信息至历史:output=true/false
tagHandlersMap.put(&history&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_history(elm); }});
// 历史的换行/换页
(1)换行是否需要换页:repage=false(默认)/true
tagHandlersMap.put(&hr&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_hr(elm); }});
// showhistory
// 显示历史数据
tagHandlersMap.put(&showhistory&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_showhistory(); }});
//------------------------------------------------------------------------------------------
// 跳转指令
// 图形按钮(PS:几乎没有实现标准KAG脚本button标签应有的功能……)
tagHandlersMap.put(&button&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_button(elm); }});
//------------------------------------------------------------------------------------------
// copylay
(1)复制源层:srclayer = message/message0/message1/base/0/1/2……
(2)复制目标层:destlayer = message/message0/message1/base/0/1/2……
(3)复制源页面:srcpage = fore/back
(4)复制目标页面:destpage = fore/back
tagHandlersMap.put(&copylay&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_copylay(elm); }});
// freeimage
// 释放图像层资源
tagHandlersMap.put(&freeimage&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_freeimage(elm); }});
// stopmove
// 停止层的移动
tagHandlersMap.put(&stopmove&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_stopmove(); }});
// stoptrans
// 停止层的渐变转换
tagHandlersMap.put(&stoptrans&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_stoptrans(); }});
// 等待层自动移动结束
tagHandlersMap.put(&wm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wm(elm); }});
//------------------------------------------------------------------------------------------
// 音效指令
// fadebgm
// 淡入背景音乐
tagHandlersMap.put(&fadebgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadebgm(elm); }});
// 淡入音效音乐
tagHandlersMap.put(&fadese&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fadese(elm); }});
// pausebgm
// 暂停背景音乐
tagHandlersMap.put(&pausebgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_pausebgm(); }});
// resumebgm
// 继续播放背景音乐
tagHandlersMap.put(&resumebgm&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_resumebgm(); }});
// 等待背景音乐淡出
tagHandlersMap.put(&wb&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wb(elm); }});
// 等待音效淡出
tagHandlersMap.put(&wf&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wf(elm); }});
// 等待背景音乐播放结束
tagHandlersMap.put(&wl&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_wl(elm); }});
// 等待音效播放结束
tagHandlersMap.put(&ws&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_ws(elm); }});
//------------------------------------------------------------------------------------------
// 变量指令(PS:由于没有TJS解释器,所以TJS相关部分不具备)
// clearvar
// 清理所有游戏变量
tagHandlersMap.put(&clearvar&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_clearvar(); }});
// 显示TJS脚本的执行结果(在KAS中仅仅支持四则运算罢了)
tagHandlersMap.put(&emb&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_emb(elm); }});
//------------------------------------------------------------------------------------------
// 存档指令
// copybookmark
// 复制存档
tagHandlersMap.put(&copybookmark&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_copybookmark(elm); }});
// disablestore
// 禁止存档
tagHandlersMap.put(&disablestore&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_disablestore(elm); }});
// erasebookmark
// 删除存档
tagHandlersMap.put(&erasebookmark&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_erasebookmark(elm); }});
// startanchor
// 即时存档,同时也是gotostart指令的返回点
tagHandlersMap.put(&startanchor&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_startanchor(elm); }});
// 开启存档功能
tagHandlersMap.put(&store&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_store(elm); }});
// tempload
// 读取内存上的临时存档
tagHandlersMap.put(&tempload&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_tempload(elm); }});
// tempsave
// 保存临时存档到游戏内存
tagHandlersMap.put(&tempsave&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_tempsave(elm); }});
//------------------------------------------------------------------------------------------
// 变量指令
// assign : KAS专有指令,非标准KAG脚本
// 将指定数值插入游戏变量中
tagHandlersMap.put(&assign&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_assign(elm); }});
// fillcolorbase : KAS专有指令,非标准KAG脚本
// 填充北京为指定颜色
tagHandlersMap.put(&fillcolorbase&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_fillcolorbase(elm); }});
// setversion : KAS专有指令,非标准KAG脚本
// 设定游戏版本
tagHandlersMap.put(&setversion&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_setversion(elm); }});
// callload : KAS专有指令,非标准KAG脚本
// 呼出游戏读档界面
tagHandlersMap.put(&callload&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_callload(); }});
// callsave : KAS专有指令,非标准KAG脚本
// 呼出游戏存档界面
tagHandlersMap.put(&callsave&,
new TagObject(){ public void run(HashMap&String, String& elm){ owner.tag_callsave(); }});
// printlayerstate : 打印出游戏状态(后台执行)
tagHandlersMap.put(&printlayerstate&,
new TagObject(){ public void run(HashMap&String, String& elm){
owner.tag_debug_printlayerstate(elm);
*****************此外,KAS默认的屏幕大小为800x450。作者给出的效果图:模拟器效果:(KAS采用Canvas渲染,在模拟器与不支持硬件加速的手机中速度会比ONS更快,缺点是Canvas在图像缩放时画质损失较大)改变KAS的Util类中布尔值debug可以设定是否开启调试模式(原版默认为false,小弟修正包中默认true)对了,在iPhone下有同类项目Artemis Engine,两者功能上基本一致(都是仅支持最基本的KAG脚本,与标准Krkr2最典型的差异是不能识别TJS文件以及不支持@iscript标记,也就是都没有提供支持TJS脚本解释器),有兴趣的朋友可以看看。如果原版ONS或KAS运行时出现问题的话(比如无法直接显示游戏画面),也可下载小弟提供的修正版本(加入NS资源打包工具,给ONS加上了编译好的so 文件,修正成可读取assets文件夹下游戏资源(注意读取assets目录下压缩文件的大小限制)。给KAS加入部分中文注释,修正了原版的 Canvas设定,真机上大约比原版快12FPS左右,在画面缩放时稍微比原版清晰些)。下载地址:

我要回帖

更多关于 安卓galgame 的文章

 

随机推荐