FreeBlues 发表于 2012-7-2 15:07:33

TI-BASIC 计算器游戏开发之文字、图形、音频教程:前言+I 中文文字显示

本帖最后由 FreeBlues 于 2012-7-3 11:35 编辑

TI-BASIC 计算器游戏开发之文字、图形、音频教程:前言

【前言】
开发环境:TI-89T的TI-BASIC,主要是因为TI在计算器上实现的BASIC在各种型号的计算器上差别不大,其次是因为我现在手头只有一台TI-89T,选择这个方便调试。

首先说明一下,本教程主要讲解跟游戏开发相关的内容,对于TI-BASIC太过于基础的内容不会说得太详细,要求读者对于TI-BASIC的基本语法有一定程度的了解,比如你至少应该知道如何建立一个PRGM程序,如何在这个PRGM程序中使用TI自带的函数。
电子游戏,主要就是利用静态图形、动态图形、文字、音乐、音效等手段来讲一个故事,而且这个故事需要你的参与,在你的各种选择中故事逐步发展,你的游戏角色会经历完整的冒险历程,会遇到朋友、敌人等各种人物,会体验快乐、悲伤等各种情绪,会探索未知的世界,会发现秘密、揭穿阴谋,会帮助好人,惩治坏人,还可能会拯救一个国家、一个大陆、整个宇宙甚至连异次元宇宙也一起拯救,一直到游戏的结束。

完整的电脑游戏有各种不同的类型,而且因为网络的发展很多游戏具备了网络功能,可以跟更多的玩家交互,这些就不多说了。我们目前准备开发游戏的运行平台是TI计算器,确切地说是TI-89T,因为TI-89T之间的互联要么需要连接线,要么需要增加额外的硬件,其实最主要的是我还没有学相关的知识,所以互联暂不考虑,也就是说因为受到软硬件平台的限制,我们目前开发的游戏只会用到文字、静态图形、动态图形、音乐、音效这几方面,事实上,这些方面已经基本覆盖了一个单机游戏所能用到的软件开发技术。
为什么选择TI-BASIC,一方面是因为我们要在TI计算器上搞开发,TI-BASIC有先天优势,它超级简单,调试方便,而且功能不弱,比较适合用来做一种讲解游戏开发思路的工具,实际上不论是C语言还是BASIC,就编写程序而言,其本质思想是相同的,就是把你的想法用计算机能够识别、理解的方式说给它听,然后它会照你说的去执行。用TI-BASIC来做出一个小游戏的原型框架,然后如果有时间、有兴趣可以很迅速地把它移植到其他平台上。

对于我来说,用TI-BASIC编程就意味着不必一直坐在电脑前,可以用一个舒服的姿势躺在床上调试程序,也可以在外出时不必携带笨重的笔记本,只要带一个小小的计算器,就能随时验证头脑中出现的想法。最让人开心的是TI-89T的能耗很低,即使像我这么高频率地使用,很可能半年才需要换一次电池。
言归正传,上面说到我们会用到TI-BASIC的文字、静态图形、动态图形、音乐、音效这五方面的功能,我们将按这个顺序进行讲解,首先是文字,然后是图形,最后是声音。关于文字要多说两句:如果仅仅使用英文文字,那么文字方面基本没什么需要多说的,直接用TI计算器系统提供的build-in函数就可以了,但是我们希望能够在这些小游戏中用到中文显示,另外游戏完成了一搬要显示作者团队的名字,你肯定不愿意只能显示几个英文拼音吧?因此中文的支持是必须的。而对于中文的软件实现因为比较有趣,所以我们先从文字显示开始。
【注意】在这里我们要明确一个思想,一种工程软件开发的思想--“够用就好”,什么叫“够用就好”?就是说你的软件需要实现一种特定的功能,比如这里对中文文字支持的功能,这个功能不需要做得十分强大,更不需要做成一种通用技术(所谓的通用技术指的是这种技术能够适用于各种不同的应用场景),只需要满足你这个软件的特定的需求就可以了。为什么说这是一种工程软件开发的思想?因为工程软件的开发,首先考虑的是成本问题,通用技术的好处是一旦开发成功,后续的各种场景都可以使用,但是首次开发的成本太高,不适合个人开发者的。当然,我这个建议是针对大多数跟我一样智力普通的家伙而言的,因为对我们这些智力普通的人来说,开发一个特定用途的功能和开发一种通用场景的功能所花费的时间差异是巨大的,但是对于一些天才而言,他们的超人智力可以轻易地缩短两者的时间差距,所以,天才们对此条建议免疫。

TI-BASIC 计算器游戏开发之文字、图形、音频教程:I:中文文字显示
【第一部分】
TI-BSAIC 中文文字显示教程
现在正式讨论TI-BASIC如何处理汉字的问题,计算机历来有两种汉字处理技术,一种是矢量化汉字,一种是点阵化汉字:汉字矢量化算法很精致,需要对汉字的组成结构有相当深入的了解,当然现在它已经成为一种通用技术。虽然汉字矢量化技术很成熟,但是要把它移植到TI-89T上工作量太大,暂不考虑。
汉字点阵化也是一种通用技术,不过处理思路比较简单粗暴,这种算法根本不去考虑汉字内在结构所蕴藏的逻辑性和每个组成部分的含义,只是把汉字当做一个像素图形来处理,下图是一个从网上找到的非常适合用来说明的汉字点阵像素图:

英文点阵字符图:


(来自:http://blog.cechina.cn/zhiy66/205022/message.aspx)
左边是“中文字模”,中间是用0和1表示的笔画,右边是把中间的二进制数字16进制化的 byte 值,这是一个16*16的点阵。

汉字点阵处理法首先把每个汉字当做一个宽度和高度固定的图形放在屏幕上,比如高16个像素点,宽16个像素点,相当于一个16*16的正方形,横着看有16行,竖着看有16列,有笔画的像素位置设置为1,没有笔画的像素位置设置为0,这样每个像素点只需要两个值就可以保存,也就是说每个像素点用一个 bit 位(1个bit位正好有0或1两个值)就可以了,每一行有16个像素点等价于每一行有16个 bit 位,我们知道8个 bit 位是一个字节 1 byte,16个 bit 位正好2个字节,也就是说每一行的数据可以保存到2个byte里,16行的数据需要16个双字节,这个汉字图形可以用32个字节来表示,这样算下来,100个汉字就是 100*32 byte,1000个汉字就是 1000*32 byte,10000个汉字就是10000*32 byte, 当然如果你用的汉字图形可以更小一些,比如高度是8像素,宽度是8像素,也就是8*8的点阵,那么一个汉字用8 byte 就可以保存下来了。

一般来说采用点阵化汉字方会搞一个几百K字节到若干M字节的汉字字库(fxesms论坛前几天有人发了一个汉字点阵程序,可以参考一下)。程序使用时会调用这个字库文件,根据汉字的索引(好像是区位码)获得某个汉字的点阵数据,这个数据就是几个16进制数,这个数据就是汉字的字模,然后在程序中用两个嵌套循环画像素点,一个按行数循环,一个按列数循环,遇到有笔画的1就在对应行数坐标和列数坐标的位置上画一个像素点,遇到没有笔画的0就不画,这样就把这个汉字显示到屏幕上了。

上面说的是C语言调用汉字点阵字库画汉字的方法,在TI-BASIC中也有对应的画屏幕像素点的函数,而且有好几个,我们先拿其中的 PxlOn 来举例,先大致说一下 PxlOn 的用法:
【小提示】建议养成经常查看TI手册的习惯,虽然是英语,不过很简单,尤其是函数说明部分。
PxlOn顾名思义就是把像素点打开,也就是在空白的屏幕上画一点,那么在哪里画呢?当然要指定行列坐标值,这里用raw,col 分别表示行和列,完整的用法就是 PxlOn raw,col ,比如你想在第10行,第15列画一个点,就执行:
1PxlOn 10,15
那么我们是否直接把C语言的处理方法搬过来用呢?确实可以这么用,不过TI-BASIC本身有一个局限,就是嵌套循环时速度会比较慢,而且在最里层的循环里还要做一次判断,判断是1还是0,因此这么做效率不高,如果只显示一个汉字还凑合,但是我们肯定不会满足于只显示一个汉字,怎么办?
【小提示】TI-BASIC的多重循环效率不高,使用时不要嵌套过深。
粗暴办法:前面我们评价过汉字点阵化处理是一种简单粗暴的算法,那么我们这里要用到一种更加简单更加粗暴的算法,它更适用于我们目前的场景:用TI-BASIC在TI-89T上显示汉字,我们的处理方法是预先把每个汉字点阵中的行列坐标值算出来,分别保存到两个列表中,行坐标保存到rawlist,对应的列坐标保存到collist,然后直接把这两个列表当做参数传给 PxlOn ,这里再补充一下,PxlOn 还有一种用法,就是使用坐标列表,形式如下:

1PxlOn {rawlist},{collist}
具体的例子如下:

1PxlOn {raw1,raw2,raw3...raw1000...rawn},{col1,col2,col3...col1000...coln}
这种方法避免了在多重循环中计算判断,经实际测试后确认效率是可以接受的。
这里的关键就是如何通过一个汉字点阵图来获取一个汉字的坐标列表,你当然可以用WINDOWS的画笔程序创建一个16*16 大小的图形,然后写一个汉字上去,然后把这个图形放大,一个像素点一个像素点去数,遇到有黑点的就记录下它的行坐标和列坐标,然后把所有的点都数一遍,记下所有有黑点的像素的行列坐标,再把它们分别保存到两个列表 rawlist 和 collist 中就可以了。

用计算机程序表达就是:
1、先看第0行,第0列的点是不是黑色点,如果是则记录 rawlist 为{0},collist为{0},如果不是就不做记录,这里假设(0,0)是黑色点;
2、再看第0行,第1列的点是不是黑色点,如果是则记录 rawlist 为{0,0},collist为{0,1},如果不是就不做记录,这里假设(0,1)也是黑色点;
3、再看第0行第2列的点是不是黑色点,如果是则记录 rawlist 为{0,0,0},collist为{0,1,2},如果不是就不做记录,这里假设(0,1)也是黑色点;
4、一直循环做此过程,......;
5、再看第0行,第7列的点;
6、此时第0行的8个像素点已经全部检查完毕,得到的结果是两个列表 rawlist 和 collist
7、这时开始换下一行,从第1行,第0列开始检查,具体过程跟上面的一样;
8、一直循环做此过程......
9、再看第1行,第7列的点,
10、此时第1行的8个像素点已经全部检查完毕
11、换下一行,从第2行,第0列开始,...... 到第2行,第7列结束
12、重复此过程,每次列数数到7就换行...
13、一直到最后一个点,第7行,第7列,这时你就会发现,我们的检查路径是从左上角的(0,0)开始,从左到右平行检查,每次检查到第7列就换下一行继续从左到右检查,一直到右下角的(7,7);


Python 程序如下:


按照上面的算法我们完成了对一个8*8的汉字点阵图的扫描,最终得到了两个坐标列表:rawlist和collist。
这种扫描算法可以在TI上用TI-BASIC实现,但是有这么几个现实问题,一是需要TI上有汉字点阵图形,不过一旦有了点阵图就不需要再分析了,直接调用图形就可以了,当然也可以手工来绘制,这就相当的繁琐了,或者要把字库文件传到TI上,不过TI-89T貌似不能接受非TI格式的外部文件(这一点我没深入研究,可能有变通的办法,知道的朋友可以分享一下)。

所以综合考虑,我们把这部分工作放到PC机上来做,我用PYTHON写了一个简单程序(上面给出逇那个程序),从各种不同分辨率的BMP点阵图中生成 rawlist 和 collist ,保存到一个文本文件中,然后再用一个名为 fromtxt.exe 的转换程序将其转换为 TI-89T能够接受的 .89t 文件,把该文件上传到 TI-89T 中,用 TextEdit 打开,拷贝其内容,再打开 PrgmEdit ,粘贴刚才拷贝的数据,就初步得到了汉字点阵图的坐标列表数据,再在程序中执行:

1PxlOn {rawlist},{collist}
就可以把汉字画到TI-89T的屏幕上了。

很好,学完上述的教程我们就明白如何把汉字显示到屏幕上去了,实际上这种汉字显示技术也是基于图形处理来做的,因此我们下一节会讲授更多、更专门的图形处理方面的内容。

【失败经验】上面这些操作看起来是不是很麻烦,话说我开始时也是打算直接用PYTHON生成一个PRGM文件,上传到TI-89T以后直接运行就行了,可是在查看了.89p 的文件格式描述后才发现几个文档不太一致,这个倒也罢了,最麻烦的是大家都没说清楚 .89p 的文件校验和算法是计算那些数据得出的,就是从文件末尾倒数的2个字节不知道该怎么填,结果生成的山寨版 .89p 文件上传时直接被拒绝,提醒我校验和不对,然后用TI-89T生成了一些 89p 的文件,用vim查它们的二进制,比对了半天也没找出啥规律来,一想,这不是在搞解密嘛,不能弄这么复杂,上网搜了一下,发现没一个程序能在我的WIN7下生成正确的 .89p 文件,有几个程序连安装都存在不少问题,而且看他们也大多是用了一个ocx控件,貌似没人知道明确的校验和算法,因此在一番尝试之后明智地选择了放弃,改用上述的办法来实现。

【建议】在软件开发过程中,可能会遇到各种问题,有些问题你可以迅速解决,有些问题需要稍微多花一些时间解决,有些问题很难在短时间内解决,那么此时就要做出取舍,看看这个问题能否通过其他处理方法回避掉,如果采用其他处理方法是否会对开发带来太多效率方面的影响?具体到我们这个例子,很显然,在面对 .89p 格式文件的校验和算法不明确的情况下,换一种方式可以尽快让开发继续下去,只是稍微操作麻烦一些,所以果断放弃对校验和算法的研究,改用简单的处理方法。在这里我想说明的是开发中遇到的任何问题,都存在不止一条的解决之道,如何选择,要根据你实际的情况来决定。

......当然我还是希望有高人能把那个校验和算法推导出来......

月与映之皮丘 发表于 2012-7-2 15:15:07

ns上的ti basic就是个悲剧。。。

FreeBlues 发表于 2012-7-2 15:58:23

ns上的ti basic就是个悲剧。。。
皮丘With冰之伊 发表于 2012-7-2 15:15 http://www.cncalc.org/images/common/back.gif

嘿嘿,一起用TI-89T来开发吧!

zyf0826 发表于 2012-7-2 16:00:57

手持TI NS路过支持

imath 发表于 2012-7-2 16:45:57

ns上的ti basic就是个悲剧。。。
皮丘With冰之伊 发表于 2012-7-2 15:15 http://www.cncalc.org/images/common/back.gif
Nspire上的TI-Basic恰恰是所有计算器中最强大的。

FreeBlues 发表于 2012-7-2 18:12:12


Nspire上的TI-Basic恰恰是所有计算器中最强大的。
imath 发表于 2012-7-2 16:45 http://www.cncalc.org/images/common/back.gif

就是不知道和TI-89T的BASIC差异有多大...

wtof1996 发表于 2012-7-2 18:57:55

6# FreeBlues
可用自然书写显示来写程序

wtof1996 发表于 2012-7-2 18:58:33

另外,lz是否介意我转载至其他地方?我会注明出处及作者(整个教程)

月与映之皮丘 发表于 2012-7-2 19:30:16

6# FreeBlues


不带图像。。。不过cas和自然书写是可以的

FreeBlues 发表于 2012-7-2 19:54:00

6# FreeBlues
可用自然书写显示来写程序
wtof1996 发表于 2012-7-2 18:57 http://www.cncalc.org/images/common/back.gif

是有计划后面写一个好用一些的编辑器,比如可以选择字体大小,不过如果使用自然书写的话会不会把屏幕占得差不多了?还有救是我没怎么研究过自然书写。

FreeBlues 发表于 2012-7-2 20:02:03

另外,lz是否介意我转载至其他地方?我会注明出处及作者(整个教程)
wtof1996 发表于 2012-7-2 18:58 http://www.cncalc.org/images/common/back.gif

欢迎转载,教程嘛就是希望更多人能看到。

不过这次发的还只能说是一个草稿,还有不少内容不完整,比如一些示范代码什么的,原来是打算学习论坛的其他写教程的朋友的认真态度,在教程里附上调试无误的代码和相关的截图,同时搞成PDF格式的便于其他人下载,还有就是最后会以一个相对来说比较简单的计算器图形游戏开发的过程作为结束。(如果没有这种实际案例示范,教程读起来就比较无趣)

但是最近败了一块EZ430 Chronos 无线开发套件,最近主要投入研究这块超低功耗的单片机手表了,怕这个TI-BASIC教程拖来拖去完不成,就先把这个还不完整的教程发到论坛上了,也起个自我监督的作用,避免写得半途而废。

wtof1996 发表于 2012-7-2 22:49:55

11# FreeBlues
我主要是打算转载到贴吧,我个人的(目前来说是吧,主图形机,没几个人)
那么我还是等。完整版本的好了,也希望你加油哦

wtof1996 发表于 2012-7-2 22:51:19

10# FreeBlues
我指的是ns
ns的分辨率是320*240,所以基本上没问题

刘剑武 发表于 2013-4-22 22:08:05

有点意思

zjyssd 发表于 2014-4-17 21:40:37

{:014:}好玩,学习到了

ssaalkjhgf 发表于 2015-11-7 10:55:34

不过用PXLON画出来的东西实在graph界面上面啊
页: [1]
查看完整版本: TI-BASIC 计算器游戏开发之文字、图形、音频教程:前言+I 中文文字显示