4.8 游戏基本原理
在游戏开发行业,经常可以听到“游戏引擎”这个词。这是一个非常恰当的比方,本游戏的工作就像一个引擎一样,除非下达了停止命令,否则它将永远运行下去。
在程序里实现永不停止再简单不过,使用一个没有出口的循环结构就行。我们要做的,就是在这个循环体内告诉游戏该怎么做,这就是游戏的基本工作原理。
while(true)
{
doSomething();
}
4.8.1 状态机
现在我们有永不停止的引擎了,只要在doSomething()里告诉机器应该干什么就行。doSomething()可以是一个任务,也可以是多个任务的组合。这些任务可能会很复杂,有的时候我希望它画方,有的时候我希望它画圆。这就需要有一套管理任务的机制,我们可以通过状态变量来实现对引擎发送指令,让机器来进行我想让它做的任务,这就是状态机。举个例子:
int state = 1;
while(true)
{
if (state == 1)
{
画方;
}
else if(state == 2)
{
画圆;
}
}
在上面这段程序中先定义了一个state作为状态变量,在循环中会不停的检测它,当发现它为1时就画方,发现它为2时就画圆。我们可以在循环之外人为改变state的值,也可以将state交给循环来控制。至于state等于何值时具体做什么,这完全由开发者事先约定,状态机只会可靠的执行状态变量通知它要执行的任务。
4.8.2 线程
现在已经确定引擎的工作需要一个死循环,但这段循环代码放置的位置必须有一定的讲究。随意加入的死循环将会造成游戏的假死,因为系统没有机会对I/O进行处理。这个循环应该加入一个独立的线程中,与系统主线程并列执行,这样才不会互相干扰。
线程是一种特殊的多任务方式。当一个程序支持多线程时,可以运行两个或更多的由同一个程序启动的任务。Java的特点是内在支持多线程,即使精简到极致的J2ME版本也仍然保留了这一特性。
实现线程有两种方法:继承Thread类或者实现Runnable接口。因为本游戏的Game类已经是GameCanvas类的子类,所以只能使用后一种方法,事实上大多数的游戏都是这样做的。实现了Runnable接口的类必须实现Run方法,这是线程的运行主体,本游戏的“引擎“就在Game类的run()方法中。
在Game对象的构造函数中调用了一个Game.start()方法,它实现了状态机线程的创建和启动。
/**
* 开始游戏线程
*/
public void start()
{
isPause = false;
if (thread == null)
{
thread = new Thread(this);
thread.start();
}
}
线程一但被启动,就会自动执行run()方法内的代码,这时游戏才真正的开始。
4.8.3 FPS控制
如同真正的引擎一般,状态机也是有自己的“转速”的,汽车的引擎转速可快可慢,而状态机的“转速”则是越稳越好。
这像一个乐团中所有的演奏者都跟随指挥棒的舞动来演奏自己的乐器,平稳的节奏会产生平稳的音乐,忽快忽慢的节奏会让听众感到不适,假如节奏太快的话也许小担琴手能跟得上,而号手跟不上,演奏就会发生错误。在游戏里,飘忽的节奏会让游戏者感到游戏的下一步无法预料,不好控制,节奏太快的话,也许运算跟得上拍,而I/0却跟不上,这些都是开发者所不想看到的。
因为一般状态机每一次动作都会带来屏幕的刷新,通常用FPS(每秒帧数)来形容状态机的频率。游戏中一般使用Thread.sleep(long time)方法让线程定时休眠来控制FPS。
int spf = 50; //每帧50毫秒
while (true)
{
doSomething();
try
{
Thread.sleep(spf); //线程休眠指定时间
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
以上的代码试图让程序执行完doSomething()方法后休眠50毫秒,以使得产生1000 / 50 = 20FPS的运行频率。但这样是不可靠的,因为doSomething()方法本身会消耗一定的时间,这样每一次节拍的总时间总是会大于50毫秒,而且该方法因为任务内容、系统状态等的不一样消耗的时间将不等,这会让FPS变得忽快忽慢。
我们无法控制doSomething()方法执行的时间,但可以控制线程的休眠时间。只要获知了已执行完的doSomething()方法的耗时,就能通过减少相应休眠时间来让每一次节拍都正好等于预期时间,以此来稳定FPS。经过改进后的FPS控制算法如下:
int spf = 50; //每帧50毫秒
while (true)
{
// 任务开始时间
long startTime = System.currentTimeMillis();
doSomething();
// 任务消耗时间
long takenTime = System.currentTimeMillis() - startTime;
if (takenTime < spf)// 当执行时间大于spf时放弃休眠
{
try
{
Thread.sleep(spf - takenTime);// 调整休眠时间让总时间等于spf
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
FPS越高,游戏地动画效果将越流畅,但手机的性能是有限的,只有手机性能可满足的FPS才是有效的FPS。考虑到各种手机性能的差异,FPS最好设置为可以满足本机性能最低需求的数字,在本游戏中FPS被设置成20,已经可以流畅的表现动画了。
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
so cool~
好详尽的注释
我上次做项目的时候,开始没写注释
结果后来交的时候要求30%的注释量
从头注释那一堆代码的时候
那个晕啊!
确实很酷!
这样一来我都觉得自己做的设计根本没有任何意义。
很不错,谢谢你的分享了!!
谢谢啊
老大,没有下载版吗?
我也是在做毕业设计,感觉j2me同j2ee实在差别太大了。快崩溃了。
还有,你的画面很漂亮呀。
下载版?
不是有源程序嘛,deployed目录下的PopTang.jar和PopTang.jad就可以直接传到手机里用了。
呵呵,记得我当时实习手机开发上美工课画像素画....
手那是发麻啊~~~
不错啊,非常感谢!!!
赞一个
你的作品和论文写得很好,觉得你做东西真的很认真,佩服
记得我一年多前做毕业设计,很多都是应付式的,现在觉得真是有点后悔。
最近想学学j2me,主要是搞个超级玛丽,谢谢你的作品了,有很好的参考价值。
很好呀!要象你多学点。
真是太伟大了
你怎么不搞个大屏的啊
?
因为我自己用的N6070就这么大,方便测试
非常感谢
正打算做手机游戏的毕业设计,没有头绪一定好好参考.
就不客气的收下了
感激不尽!(一百遍) 楼主太好了! 我都不知道用语言了! 总之一句感激不尽! 279636240是我的QQ希望高手们多多指点!
楼主很不错啊,向你学习钻研和贡献精神
lz强人!张某佩服。小弟现在国外工作,实不如意,打算明年年底回国工作,打算从事J2ME手机游戏的开发工作。因为我喜欢玩游戏,一直都想自己做个游戏,可惜,雷声大,雨点小。
我的毕业设计是JPG和BMP图片的相互转换,用TurboC2谢谢,最后实现了,可是,程序写得很烂,跟Lz比简直是相差十万八千里啊,一句话,还是佩服!
昨晚配置J2ME的环境,搞到凌晨3点,没有成功,装好EclipseME后,首选项中的J2me选项出来了,但是Platform Components这个选项始终没有。不知Lz能否指导小弟一下?小弟感激不尽!
我大半年没写过程序了,刚打开Eclipse看了下,也没找到你说的Platform Components.
不知道你要做何用?
哦,这个问题已经解决了,Eclipe版本不同,3.2好像没有这个选项,不过系统已经配置好了,helloworld已经运行成功,不过还是谢谢你,呵呵~~
我今年大四了,我跟导师说明年毕业设计换你的这个题目,因为我可能明年会进一家手机游戏公司,打算也做个泡泡堂,不知道你介不介意让我使用你的部分代码和论文,可能还需要你稍微指点一下,谢谢了
QQ:376773982
可以,有疑问请联系我QQ,只是代码方面我已经忘得差不多了。。。
哥们 你真伟大啊 收藏了
老大,你什么时候上QQ啊,给你留言也没用,有没有开题报告之类的资料可以给我参考一下啊?论文有没有DOC版的,我还有几个代码的问题想请教你一下,谢谢了
QQ:376773982
不好意思,平时工作非常忙,加我QQ的时请注明身份,否则一般是不通过的。
9931817到底是不是你QQ啊,我用google搜到的
根本就没有身份验证啊。
不好意思, 我的QQ是7405440...我也忘了我有没有在Blog上公布过QQ了.
我想玩这款游戏,能告诉我在哪下载吗,我在你的blos里找不到,有源码我也不会用
马上要毕业了,课题就是基于J2EE的手机游戏的编程,因为我是学通信的对软件的开发不是很了解,准备毕业论文就这么混过去,看到LZ和各位师哥师姐的留言我决定认真的做玩,要让以后没有遗憾。
我也是万老师的学生,他是一个很好的老师,不过我不是一个跟你一样的好学生,呵呵,是他推荐我来的,他说你做的毕业设计是代表了大学生本科的最高水平,佩服。。。师哥~~~
做的不错哦..如果是大屏幕的,在模拟器上玩的会更爽的,一个字,强!还有个问题,看了下高手的论文,地图是三维的,那么,这也算一款三维游戏了吧..
你好!冒昧打扰了。我现在在做j2me的手机游戏。我是个新手。看了你的程序。我有点搞不懂。关于那个“保存关卡配置”具体是怎么做的啊。是怎么生成的十六进制配置文件的?如果你有空的话,麻烦回答下。谢谢哈!
用你目录做参考写另一个游戏的论文,谢谢了
你好,我现在是个大四的毕业生,由于Java根基浅薄,看了你的毕业设计关于那个关卡类的设计是怎么完成的?还望指教阿!QQ:61508486
bbbbbb
你好,我也是软件学院的学生,万老师上课的时候提过你,在这看到你的东西,很荣幸,呵呵!你的程序做的真的很好,向你学习,也请教下,你的泡泡堂在Jbuilder X里面应该如何运行,我其他的配置应该都没问题,就是运行不了,
java.io.IOException: CreateProcess: C:\Nokia\Devices\S40_SDK_3rd_Edition_Feature_Pack_2\bin\javaw -classpath D:\ppt\classes;C:\Nokia\Devices\S40_SDK_3rd_Edition_Feature_Pack_2\lib\classes.zip ppt.PopTang error=2
还望指教,谢谢!
我读书那会老师用JBuilder教学, 但我还是坚持用自己的Eclipse, 不熟悉JBuilder的配置, 帮不上你了.
我也向你推荐Eclipse或NetBean.开发工具的选择上大可不必跟着老师走, 想当年我们学C语言时还用Turbo C, 打击了多少人...还不如用Ultra Edit + cl呢!
确实不错,比我那时做的强多了!!记得我做手游毕设的时候好像还从没人做过手游毕设~~呵呵
万老师确实是好老师,如果没有他的指导的话就无法完成游戏了!
伟大啊
很强大,谢谢分享,希望能向你请教!谢谢
very good
谢谢分享,希望以后能向你请教!
大虾,请较一下,请问你知道J2ME游戏的脚本是怎么写的吗?地图工具用的是什么呢?有没有相关的教程啊?网上关于脚本的东西很少,地图工具也没有教程,自己摸索蛮耗时间的说~~
借鉴了下你的这个项目,论文还有部分代码(主要是整体的框架),不知道可行否?谢谢先~
@jerry_zihuai
无所谓~
我喜欢玩这个游戏,嘿嘿 !
Find Canon IR2830 Sharp AR-208s
Buy Sharp MX-M200D
Canon Image Runner
Image Runner 2018
Buy Canon IR-2020
Review Canon IR-1025IF
High-Performance Laser All-in-One for your Business or Small Workgroup
Buy Panasonic
Panafax UF-7200
Sharp FO-DC535 REFURB
Find Brother8480DN
Canon Canon IR-1025IF
Sharp FO-2080