j2me游戏教程(2)什么是状态机,怎样在上次的代码中建立状态机,什么是FPS?
|
|
Author: 一滴蔚蓝色 | Date: 2007-02-22 |
View: 2401 |
开发技术 - 程序设计 | Digg:
0
|
|
在讲述如何构建一个无限循环,来反复不停的往屏幕上绘图的程序之前, 先说一下什么是状态机。 (都是按我自己的理解来的,和实际可能有出入!) 首先需要一台不断提供能量的机器。 一个while循环就可以做到这一点。 while (true) { 做事。 } 那么不管这事是什么,都可以一直做下去。 机器就有了。 那么状态是咋回事? 就是你把好多事放到这个机器里,一会叫做这个,一会叫做那个。 如果增添一套比较成熟的管理方式,那么就是一个非常完整的状态机了. 举个例子: while (true) { 第一, 画一个三角。 第二,画一个方块。 } 程序先画三角,再画方块,每一次循环中,两件事同时做。 加个控制变量把他们分开。 state = 第一 while (true) { if (state == 第一) { 画三角。 } else if (state == 第二) { 画方块。 } } (Java里,用=号来赋值,用==来做比较) 现在程序总是在画三角,因为每一次循环总是在画三角。 如果在画了三角有5分钟左右,就想让画方块,代码这样写: state = 第一 while (true) { if (state == 第一) { 画三角。 if (画了五分钟) { state = 第二 } } else if (state == 第二) { 画方块。 } } 这样,程序会先画5分钟三角,再一直画方块. 大概清楚了么? 一个while循环,然后使用"状态"来控制做不同事,就构成了状态机。 整个游戏都是一个状态机。 比如,游戏一开始画logo 按了5键,转到画菜单。 再按5,转到画场景。 还有所谓的AI,也是一个状态机的方式,以后再说了。 -------------------------------------- 现在先看一下再JBuilder的那个项目中,如果构造这样一个状态机,要这么这么这么: 加个方法, public void run() { while (true) { System.out.println("xx");//这句话的意思是在控制台打印xx //以后可以自在这里面可以写自己的事情. } } 然后在类名处,写成这样一个: 以前是这样 public class Game extends Canvas implements CommandListener { 现在变成这样: public class Game extends Canvas implements Runnable, CommandListener { 多加了一个Runnable接口. 然后在 GameMidlet这一句 Display.getDisplay(this).setCurrent(displayable); 后面添上 new Thread(displayable).start(); 就行了. 现在运行一下,然后按模拟器上的Select按钮。 如果看到控制台不断有xx打印出来,就是成功了。 ------------------------------------- 刚才这几个步骤的意思是, 通过implements Runnable 把Game这个Canvas变成一个线程。 然后通过 new Thread(displayable).start(); 使这个线程运行。 这个线程运行之后,就会自动调用run方法。 而我们在run里面搞了一个无限的循环,这就构成了一个状态机了。 等于说,我们的状态机,是运行在另一个线程之中。 而不会干扰系统的方法调用。 如果你用一个普通的方法构建状态机,然后调用,类似这样: 在class Game不实现Runnable接口 只在里面加一个gogogo()方法: public void gogogo() { while (true) { } } 然后在GameMidlet这一句 Display.getDisplay(this).setCurrent(displayable); 后面添上 displayable.gogogo(); 这就完蛋了.因为gogogo里面有个无限循环,系统永远退不出 startApp()这个方法了。 如果使用线程,就不会产生这种情况。无限循环是在另一个线程独立运行的。 (java怎么实现的,估计还要看点儿线程之类的书了,可以不用搞那么深入。) 这样系统该掉其他方法,还会掉其他方法。 先动手做一下,再往下看。 ------------------------------------------------ 现在可以说说桢的概念了。英文叫做Frame. 可以这样理解: while (true) { 开始 如果 (***) 干这干那 否则如果 (yyy) 干那干这 结束 } 这从 开始,到 结束 的一个过程,也就是一次循环,叫做一桢。 每一桢用的时间,叫做SPF (Second per frame) 倒过来,每秒运行的桢数,叫FPS (Frame per second) 打CS的时候,有的版本可以看到屏幕上画着 FPS: 后面一个数字,不停的变。 这个东西越高越好,表示游戏速度越快。 怎么计算FPS: 在开始的时候记录一下系统时间,在结束的时候又记录一下系统时间, 两个时间一减,就知道这一桢用的时间了(SPF)。 1/SPF 就是FPS. 限桢的概念: 有时候一个循环奇快,有时候一个循环奇慢. 打游戏的时候, 你看着画面时快时慢, 肯定不中. 就要限制一下. 先规定好一个FPS,假如是每秒20桢,那么一桢用的时间就是50毫秒。 在 结束 的地方,判断,如果这一桢用的时间小于50毫秒,记录下还差多少时间到50毫秒, 然后就让程序睡觉,睡够这个差值,使这一桢整体使用的时间达到50毫秒。 这样平均下来游戏的FPS就是20,很稳定。 如果一桢的时间超出了50毫秒,那就没办法了。这就是游戏运行慢的原因,这时要想办法看看是做了什么事,导致程序运行缓慢。 魔兽肯定采用了比较高级的控制FPS的方法,如果卡,他就使用很低的FPS,不卡了之后,他就用很快的FPS补上。 这样看起来游戏 在网络速度不好的情况下,很迟钝的样子,然后再网络速度好了以后,刷刷刷运行的飞快。 神奇的是,他们能计算出桢的速度变化。 都是我的猜测而已了。 大概明白了没有?没有就说。 作业来了,试着写一下计算FPS的代码,把FPS打印到控制台。 有啥问题问哦。 下次,讲一下绘图的系统方法是怎么个调用流程。如何绘制图形到屏幕上。怎么察看相关的API文档。 加个方法, public void run() { while (true) { System.out.println("xx");//这句话的意思是在控制台打印xx //以后可以自在这里面可以写自己的事情. } } 的意思是在Game.java里加。 更多阅读: |
|
| 最近更新 ( 2008-09-10 ) |
尚无评论发表