- 浏览: 137135 次
- 性别:
- 来自: 郑州
文章分类
最新评论
-
Ken艹小哲:
太赞了 哥们 加扣
猜数字问题的最少步数算法. -
chenyuan122912:
...
解决AS3 Socket编程中最令人头疼的问题 -
hyx0914:
有源代码打包下载的吗?
Flex地图分块加载的实现 -
tianhai110:
非常有价值的 测试总结
时间效率,Timer和EnterFrame在FP 10.1之后测试和建议 -
763675117:
你好,fengxiangpiao,看了你的文档,我的需求和你差 ...
解决MovieClip打印问题 转
这几天一直在看 <<Killer Game Programming in Java>>,非常经典的好书,现在对游戏有了一个基本的认识,过几天就写个贪吃蛇出来.
因为看得有点快,真正准备写代码的时候又发现自己对一些基本知识点还是比较模糊,又返回去看前面.边看边做笔记,感觉确实理解得要更加清楚了.
*FPS 和 按时间准确的Sleeping*
============================
FPS
--------
一个测量animation速度的常用指标就是桢速(每秒显示桢的数量:frames per second),简称FPS.在下面的
代码中,做一次gameUpdate和gameRender的循环就对应一个桢.
比如100FPS表示run()中的每次迭代应该用1000/100 == 10ms.这个迭代时间存在period变量中.
//code example:
public void run() {
long beforeTime, timeDiff, sleepTime;
beforeTime = System.currentTimeMillis();
running = true;
while(running) {
gameUpdate();//计算game中的model
gameRender();//画一个image, "double buffer"
paintScreen();//在screen上显示image
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = period - timeDiff;//计算需要sleep的时间
if (sleepTime <= 0)
sleepTime = 5;
try {
Thread.sleep(sleepTime);
}catch(InterruptedException e);
beforeTime = System.currentTimeMillis();
}
}
--------
Timer Resolution
连续调用两次timer中间必需的最小时间.这样才能保证每次调用返回不同的时间.
比如:
long t1 = System.currentTimeMillis( );
long t2 = System.currentTimeMillis( );
long diff = t2 - t1; // 实际输出是0,单位是ms
在win95和win98上,resolution值是55ms,说明只有在每隔55ms后调用timer才会返回不同的值.
在animation loop中,resolution的会导致animation比期望的要慢而且减小了FPS.因为如果gameUpdate
和gameRender的时间小于55ms,那么timeDiff变量就会设为0,那么sleepTime就会比实际需要的时间要大.
为了防止这个问题,每个循环周期时间必须大于55ms,表示最高限制是大约18FPS.这个frame rate被广泛接
受,因为屏幕刷新过慢会表现得象闪屏(excessive flicker)一样.
在Windows2000, NT和XP上, currentTimeMillis()的resolution是10到15ms,这样就可以获得67-100FPS.
这个值对游戏来说是可以接受的.在Mac OS X和Linux上的resolution是1ms,相当好了.
--------
改进过的J2SE Timers
J2SE 1.4.2有一个没有被写入到文档的精确到微秒的timer class: sum.misc.Perf.
Pref计算diff的方法:
Pref perf = Perf.getPerf();
long countFrep = perf.highResFrequency();
long count1 = perf.highResCounter();
long count2 = perf.highResCounter();
long diff = (count2 - count1) * 1000000000L / countFreq;
//转换成纳秒nanoseconds
nanoseconds:十忆分之1秒
J2SE 5.0中解决了这个timer的问题,System.nanoTime(),可以象Pref timer一样来计算时间.
long count1 = System.nanoTime();
long count2 = System.nanoTime();
long diff = (count1 - count2);//单位是纳秒
--------
Non-J2SE Timers
Java 3D timer的计算方法:
long t1 = J3DTimer.getValue();
long t2 = j3DTimer.getValue();
long diff = t2 - t1;//单位是纳秒
*更好的Sleeping*
================
animation循环依赖一个好的timer和精确的sleep方法调用.现在在前面的基础上改进代码,以保证需要
的桢速.
//code example:
private static final int NO_DELAYS_PER_YIELD = 16;
public void run() {
long beforeTime, afterTime, timeDiff, sleepTime;
long overSleepTime = 0L;
int noDelays = 0;
beforeTime = J3DTimer.getValue();
running = true;
while(running) {
gameUpdate();
gameRender();
paintScreen();
afterTime = J3DTimer.getValue();
timeDiff = afterTime - beforeTime;
sleepTime = (period - timeDiff) - overSleepTime;
if (sleepTime > 0) {
try{
Thread.sleep(sleepTime/1000000L); //nano -> ms
}catch(InterrruptedException ex){}
overSleepTime = (J3DTimer.getValue() - afterTime) - sleepTime;
}else { //sleepTime <= 0; 桢的时间大于期望的period,
//不sleep直到sleepTime > 0 或 连续运行了NO_DELAYS_PER_YIELD次
overSleepTime = 0L;
if (++noDelays >= NO_DELAYS_PER_YIELD) {
Thread.yield();
noDelays = 0;
}
}
beforeTime = J3DTimer.getValue();
}
}
如果sleep()设置成sleep 10 ms,但是确用了12 ms,那么overSleepTime会被设置成2 ms,下次就会少
sleep 2ms.
如果桢的时间大于期望的period,那么就不浪费时间sleep,而是一直循环,一定次数后调用Thread.yield(),
这样来节省时间而又保证其它线程有机会运行.
*FPS和UPS*
==========
除了FPS,还有一个有用的测量animation速度的指标:UPS. 在现在的animation循环中每次迭代拥有一次
update和render.但是这个对应不是必需的.在循环中,可以每一次render前做两次updates.
//code example:
public void run() {
...
running = true;
while(running) {
gameUpdate();//update 游戏状态
gameUpdate();//再一次update 游戏状态
gameRender();
paintScreen();
//sleep
}
System.exit(0);
}
在上面的代码中,如果游戏提供了50FPS,那么就每秒就会做100次updates.
从Rendering中分离Updates
--------
对于高FPS速率的一个限制是update和render所需要的时间.假设period = 5ms(1000/5 == 200FPS),如果
update和render需要的时间大于5ms,那么200FPS就不可能达到.而它们所需要的时间中大部分是被render所消耗的.
在这种情况下,增加游戏速度的方法是增加UPS的速率.在编程中,也就是在每次迭代中增加gameUpdate的次数.
但是注意,如果增加gameUpdate的次数过多的话会造成游戏不连续,因为有许多游戏状态没有显示出来.
新的代码:
//code example:
private static int MAX_FRAME_SKIPS = 5;
public void run() {
long beforeTime, afterTime, timeDiff, sleepTime;
long overSleepTime = 0L;
int noDelays = 0;
long excess = 0L;
beforeTime = J3DTimer.getValue();
running = true;
while(running) {
gameUpdate();
gameRender();
paintScreen();
afterTime = J3DTimer.getValue();
timeDiff = afterTime - beforeTime;
sleepTime = (period - timeDiff) - overSleepTime;
if (sleepTime > 0) {
try{
Thread.sleep(sleepTime/1000000L); //nano -> ms
}catch(InterrruptedException ex){}
overSleepTime = (J3DTimer.getValue() - afterTime) - sleepTime;
}else {
excess -= sleepTime;
overSleepTime = 0L;
if (++noDelays >= NO_DELAYS_PER_YIELD) {
Thread.yield();
noDelays = 0;
}
}
beforeTime = J3DTimer.getValue();
int skips = 0;
while((excess > period) && (skips < MAX_FRAME_SKIPS)) {
excess -= period;
gameUpdate();
skips++;
}
}
}
如果update/render实际需要12ms,但是需要的period是10ms,那么sleepTime会是-2ms(由于引入overSleepTime,
所以可能会更小一点).额外的执行时间被加到excess变量中.
当excess达到period大小时,那么相当于丢失了一个桢,在while循环中,为每次丢失执行gameUpdate.但是限制在
MAX_FRAME_SKIPS里.
这样做的优点是,如果一个游戏的update/render速度不能满足期望的FPS时,那么就会另外执行gameUpdate.
这样改变了游戏的状态但是没有马上显示出来,最后用户会看见游戏移动更"快"了,虽然每秒钟显示的桢数并没有
改变.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/starshus/archive/2006/11/03/1364979.aspx
发表评论
-
在Eclipse中用JDBC连接Sql Server 2005总结
2010-12-13 11:01 779* 最近因为开发活动需要,用上了Eclipse,并要求使用精简 ... -
Java文件操作详解
2010-12-11 15:10 636输入输出流 在Java中, ... -
如何衔接不同文件中的swing组件转
2010-11-11 21:47 784软件编程牛人网 2005年2月2日3:43:23 问题是: ... -
一个简单的IP地址管理系统源代码
2010-11-11 21:46 748软件编程牛人网 import java.io.Buffere ... -
利用继承高效率写程序转
2010-11-11 21:45 670软件编程牛人网 2005年2月3日3:41:41 问题:如 ... -
FTP 协议(rfc939) 简单的实验(in Java)
2010-11-11 21:41 675Java代码:FTPClient.javapackage or ... -
70个JAVA问答
2010-11-09 15:20 915软件编程牛人网 1. ... -
提升JSP应用程序的七大绝招转
2010-11-09 15:17 627软件编程牛人网 你时常被客户抱怨JSP页面响应 ... -
java读取操作系统环境变量
2010-11-04 16:06 683在家上网赚钱更容易 /** 文件名:SysP ... -
JAVA中浅复制与深复制
2010-11-04 15:52 575在家上网赚钱更容易 1.浅复制与深复制概念⑴浅复制(浅克 ... -
Java网络编程从入门到精通(29):服务端Socket的选项
2010-11-03 12:11 669在家上网赚钱更容易 ServerSocket类有以下三个选项 ... -
Java网络编程从入门到精通(30):定制accept方法
2010-11-03 12:10 637在家上网赚钱更容易 ... -
Java网络编程从入门到精通(31):非阻塞I/O简介
2010-11-03 12:08 709在家上网赚钱更容易 在网络应用中,一般可以采用同步I ... -
Java网络编程从入门到精通(32):一个非阻塞I/O的例子
2010-11-03 12:07 697在家上网赚钱更容易 为了使读者更好地理解非阻塞I/O ... -
Java网络编程从入门到精通(33):非阻塞I/O的缓冲区(Buffer)
2010-11-03 12:05 575在家上网赚钱更容易 如果将同步I/O方式下的数据传输 ... -
Java网络编程从入门到精通(34):读写缓冲区中的数据---使用get和put方法按顺序读写单个数据
2010-11-03 12:03 597在家上网赚钱更容易 ... -
jsp 图形验证码 IllegalStateException 异常
2010-11-02 18:27 672在家上网赚钱更容易 最近用了jsp做了一个简单的图形验证码, ...
相关推荐
Java做游戏学习.zipJava做游戏学习.zipJava做游戏学习.zip Java做游戏学习.zipJava做游戏学习.zipJava做游戏学习.zip Java做游戏学习.zipJava做游戏学习.zipJava做游戏学习.zip Java做游戏学习.zipJava做游戏学习....
JAVA游戏的开发通常涉及到图形用户界面(GUI)的设计、音频处理、动画效果以及游戏逻辑等多个方面。在这款游戏中,开发者需要考虑如何创建一个流畅的用户交互体验,包括方块的下落速度、旋转操作的响应以及得分计算...
2. AI算法:简单的如敌人的随机行为,复杂如路径规划、行为树,甚至机器学习技术都可以在Java游戏中应用。 五、用户界面和音效 1. 用户界面:使用JavaFX或Swing等库创建游戏菜单、选项设置等界面元素,确保用户友好...
这个压缩包包含了几十个用Java编写的源代码,是学习Java游戏编程的理想资源。这些小游戏不仅展示了基础的编程概念,还涵盖了Java语言的核心特性以及游戏开发的常用技术。 首先,让我们来看看Java语言在游戏开发中的...
java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java...
Java游戏源码是一种学习和研究Java编程语言的好资源,它能帮助开发者理解游戏开发的底层逻辑,提升编程技能。在本资源包中,包含了16个不同的Java游戏源码,这意味着我们可以深入研究多种游戏类型的实现,例如可能...
同时,加入Java学习群***可能会提供一些学习资料和实时的老师指导,便于对Java游戏高级编程进行更深入的研究。由于提供的内容中强调了学习群的重要性,可以推断在学习的过程中,交流与实操同样重要。
Java游戏编程是一个不断发展和更新的领域,开发者需要不断学习新的库、框架和技术。参与开源项目,利用GitHub、Stack Overflow等社区资源,能加速学习进程。 总的来说,Java游戏编程涵盖了广泛的编程知识,从基础到...
这些"几个很不错的Java游戏源代码"提供了一次深入理解Java编程、游戏逻辑以及核心Java知识的绝佳机会。下面,我们将详细探讨这些游戏源代码所涵盖的知识点。 首先,"3d坦克游戏"是一个展示Java 3D图形编程能力的...
java游戏设计——Java版仙剑奇侠传游戏(画面仿真度非常高)java游戏设计——Java版仙剑奇侠传游戏(画面仿真度非常高)java游戏设计——Java版仙剑奇侠传游戏(画面仿真度非常高)java游戏设计——Java版仙剑奇侠传...
Java小游戏源码集合是一个丰富的资源库,包含了八款经典的Java编程实现的小游戏,这些游戏能够帮助初学者理解和学习Java编程语言以及游戏开发的基本原理。以下是这些游戏的详细讲解: 1. **五子棋**:五子棋是一款...
java 雷电游戏 雷霆战机 swing学习.zipjava 雷电游戏 雷霆战机 swing学习.zip java 雷电游戏 雷霆战机 swing学习.zipjava 雷电游戏 雷霆战机 swing学习.zip java 雷电游戏 雷霆战机 swing学习.zipjava 雷电游戏 雷霆...
《Java游戏俄罗斯方块》是一款非常适合Java初学者学习和实践的游戏项目。这个游戏的开发基于Java编程语言,展示了Java在游戏编程中的应用,尤其对于想要掌握Java GUI(图形用户界面)和事件处理的开发者来说,这是一...
Java游戏编程原理与实践是计算机科学中的一个重要领域,它结合了Java编程语言的特性与游戏设计的技巧。...这些游戏源码不仅是学习工具,也是实践平台,可以帮助开发者逐步掌握Java游戏编程的精髓。
Java游戏源代码下载资源提供了三个不同的游戏项目,这对于学习Java编程和游戏开发的初学者以及经验丰富的开发者来说,都是宝贵的参考资料。这些游戏可能包括基础的命令行游戏到更复杂的图形界面游戏,涵盖了一系列的...
这些小游戏是学习和实践Java编程、尤其是Java Swing库的理想素材。Java Swing是Java AWT(Abstract Window Toolkit)库的扩展,主要用于创建桌面应用程序的用户界面。Swing提供了一组组件,如按钮、文本框和面板,...
【Java小游戏Jar】是一款基于Java编程语言开发的小型游戏,可能是为了学习和娱乐而创作的。在编程领域,Java是一种广泛使用的高级编程语言,以其“一次编写,到处运行”的跨平台特性著称。开发者通常使用Java来构建...
【标题】:Java贪吃蛇小游戏是基于Java编程语言实现的一款经典休闲游戏,它通过源码的形式呈现,供学习者研究和改进。 【描述】:这个压缩包包含的Java源码详细展示了如何利用面向对象的设计思想,实现一个功能完整...
Java雷电游戏是一款基于Java编程语言开发的小型游戏,它展示了Java在游戏开发中的应用,同时也为学习者提供了深入理解Java基础知识和实践编程技巧的机会。这款游戏的开发涉及到多个Java技术点,包括图形用户界面...