本文向大家描述一下J2ME Snake脚本引擎,主要包括高级代码编写,低级代码编写和脚本虚拟机(SVM)等内容,相信本文介绍一定会让你有所收获。
J2ME Snake脚本引擎简介
一、J2ME Snake脚本引擎高级代码编写:
1,语法类似于C。
2,支持函数定义,函数调用,数组,表达式,循环,分支。
3,弱类型(lua也是),内建类型有string,int,float,boolean
如定义变量varx;可以给x赋的值有x="你好Snake";x=32;x=32.23;x=true;
4,内建35个运算符,适用于所有的表达式,如位运算>>逻辑运算&&赋值运算|=等等,运算符优先级简化为4级,由高到低为单目运算>算数运算>关系运算>逻辑运算,如果你写代码是不确定运算符的优先级保险起见加上括号就不会有错。
5,支持转义字符输入。
6,支持注释,如行注释符//及块注释符/**/
二、J2ME Snake脚本引擎低级代码编写:
1,语法类似于8086汇编,但要比它简单的多,有33种虚拟指令可供选择,并且可以定义方法演示一个完整的加法函数及函数调用(分号是行注释符):
- myAdd()
- {
- paramy;函数参数y
- paramx;函数参数x
- Addx,y;将y的值与x相加并赋给x
- Mov_RetVal,x;将x值赋给寄存器(只有一个寄存器即_RetVal)
- Ret;方法返回符(可以省略)
- }
- _Main()
- {
- varx;定义局部变量x
- vary;定义局部变量y
- varz;定义局部变量
- Movx,2;将2赋给x
- Movy,3;将3赋给y
- Pushx;将x压栈,调用方法需要将参数压栈
- Pushy;将y压栈
- CallmyAdd;调用方法
- Movz,_RetVal;将寄存器的值赋给z
- }
判断和分支的低级代码我就不给出了,想了解的话可以先写高代码,再用编译器编译成低级代码(在编译器中输入参数-A)再参照低级代码来研究
话说回来,为什么要设计低级代码呢,干脆直接写高级代码多方便,之所以这样设计是由于编译器编译跳转分支那部分都非常的精简,运行速度非常的快,但是编译表达式就比较繁琐,虽然在3个星期前我压根不知道什么叫编译原理,但是通过写脚本的词法分析,语法分析,汇编等程序我才发现它的难度和复杂度超出想象好几倍,当前***的编译器如C++编译器是用状态机进行语法分析,在表达式的编译上做足了优化,可是我才是个初学者,为了加快研发速度我使用了半状态机半递归下降的方式进行编译,所以在效率上没有做太多优化,所以如果您想写复杂表达式求值并需要快速运行的代码,还是建议用低级代码编写,***可以和高级代码进行合并,用汇编器汇编成二进制。#p#
三、J2ME Snake脚本引擎之脚本虚拟机(SVM)
1,虚拟机的执行是基于字节码的,只有一个寄存器_RetVal用来存放返回值,运行时堆栈是用来进行函数调用的大小默认是512K,可以自己更改比如在低级代码上头部加入关键字SetStackSize1024虚拟机会根据设置来修改堆栈大小
2,和主游戏引擎通信是基于方法调用,需要自己写方法库类,这个类需要继承Lib.class,在自己的方法库中实现方法,考虑到效率,没有通信是没有用到对象,并且也不是基于RTTI机制,所以使用时务必要注意2点,这两点写在测试包里,可以去看一下。
3,错误处理也是考虑到效率没有基于java的异常,而是只打印错印并且虚拟机会正常运行,可是一旦打印出错误,需要做的就是停下运行的程序检查脚本有没有,或者是虚拟机的核心执行单元有没有BUG如果不这样做,那么后面的脚本数据已经成脏数据,会对游戏逻辑造成潜在的危险。
4,多线程:J2ME Snake脚本引擎能加载多个脚本并发执行,并且每个线程有个优先级,优先级高的脚本能分到更多的时间片,SVM来管理这些线程的运行,并且主游戏引擎能方便的操作脚本虚拟机加载,暂停,停止,恢复这些脚本线程。(0.8版提供多线程功能)
5,运行方式:主游戏引擎在while循环中,每次调用虚拟机的runScript(inttime)方法,通过传入时间片来决定虚拟机在这个循环周期运行多长时间,所以脚本里就可以写这样的循环while(true)也就是脚本有自己的逻辑死循环,但是它不会干扰主引擎的逻辑死循环,因为在传入的时间片运行完时,脚本引擎会自动跳出来让主引擎继续运行下一个循环,而这些对编程人员都是透明的。
【编辑推荐】
- 术语汇编 J2ME 3D技术简介
- 深入了解J2ME Polish+Eclipse配置过程
- 探究J2ME中cookie库的管理
- 深入了解J2ME网络程序设计
- 解析Linux下如何用eclipse搭建J2ME开发环境