锁定老帖子 主题:关于在Java游戏中实现暂停的讨论
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-15
最后修改:2009-05-23
方案1,直接利用状态变量,如果处于暂停状态,则什么也不做(空循环) public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); int mDirection = sv.getMoveDirection(); // KEY_START //如果是开始键,就设置程序状态为开始 if (keyCode == SnakeKey.START) { gameState == RUNNING; return; } // KEY_PAUSE //如果是暂停键,就设置程序状态为开始 if (keyCode == SnakeKey.PAUSE) { gameState == PAUSE; return; } //设置方向 //省略其它按键的操作 //... return; } 更新画面的线程 private Thread mRedrawHandler = new Thread() { @Override public void run() { try { while (true) { // if pause mode, do nothing if (mMode == PAUSE) { continue; } if (mMode == RUNNING) { // 进行更新操作 // 省略部分代码 } Thread.sleep(mMoveDelay); } if (mMode == LOSE) { // TODO sss // 重置 mScore // 重置 mMoveDelay // 记录当前得分,如果有排行榜的话 } } catch (InterruptedException ex) { } } }; 觉得这样的话 while 循环会占用大量的 CPU 时间 , 所以在 continue 前加了一个 Thread.sleep(1000); 先让程序停止 1s 钟。虽然不知道系统的原理是什么,但感觉自己写的空循环占用的资源要比 Thread.sleep() 要多吧。 if (mMode == PAUSE) { Thread.sleep(1000); continue; } 可是觉得这样也不好,会影响程序的响应速度。 后来学习了线程的同步,就想着改成同步,在系统中加入一个锁,平时这个锁可以由画面线程获得,可是当按下 pause 时,就让另外的线程取得锁,这样的话,画面线程取得不到锁,就会自已停下来了。 接收键盘事件的函数 public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); int mDirection = sv.getMoveDirection(); // KEY_START if (keyCode == SnakeKey.START) { pauseOrResume(); return; } // KEY_PAUSE if (keyCode == SnakeKey.PAUSE) { pauseOrResume(); return; } //设置方向 //省略其它按键的操作 //... return; } 更新画面的线程 private Thread mRedrawHandler = new Thread() { @Override public void run() { try { while (true) { synchronized (pauseLock) { // if pause mode, wait the lock. if (mMode == PAUSE) { pauseLock.wait(); } pauseLock.notifyAll(); } if (mMode == RUNNING) { // 进行更新操作 // 省略部分代码 } Thread.sleep(mMoveDelay); } if (mMode == LOSE) { // TODO sss // 重置 mScore // 重置 mMoveDelay // 记录当前得分,如果有排行榜的话 } } catch (InterruptedException ex) { } } }; 另外加了一个方法来控制锁: private Object pauseLock = new Object(); /** * Pause or resume the game */ private void pauseOrResume() { while (true) synchronized (pauseLock) { if (mMode == RUNNING) { mMode = PAUSE; break; } if (mMode == PAUSE || mMode == LOSE) { mMode = RUNNING; // Tell the screen to run. pauseLock.notifyAll(); break; } } } 但是不知道在这种情况下会有什么不好,欢迎大家讨论。 附件是一个小的示例程序,大家可以看一下,可以是因为代码贴多了,不好容易看,可以下载附件看看示例。 ================================================= 2009-05-23 1.更新了代码,删除了无用的部分代码 2.更新了TrafficLightsDemo.jar代码,修正原来的代码,使用在暂停时的响应时间减少。 3.贪吃蛇的程序已经放到论坛上,可以去下载看全部代码http://www.iteye.com/topic/393669 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-16
Memento模式.
|
|
返回顶楼 | |
发表时间:2009-05-19
最后修改:2009-05-19
怕麻烦的话就用thread.sleep();好了。。。虽然会出现很多不良效果。。
|
|
返回顶楼 | |
发表时间:2009-05-19
Saito 写道 Memento模式.
不太了解设计模式,不过我看这个模块好像是保存状态的,在网上找了一下,好像做Undo操作的啊。不知道如果实现暂停。 |
|
返回顶楼 | |
发表时间:2009-05-19
wjyjimy 写道 怕麻烦的话就用thread.sleep();好了。。。虽然会出现很多不良效果。。 已经说明了Thread.sleep()有很多的不好,不知道其它的程序是如何实现的,如果使用这个的话,时间设置多少才会好些呢?
|
|
返回顶楼 | |
发表时间:2009-05-20
你最多可以thread.sleep(922337203685477587);哦~
你直接就填10000000好了,以前学Midlet的时候老师好象说不要用pauseApp()来暂 停,要用就用thread.Sleep(),现在我都忘了Midlet怎么个写法了,呵呵~ |
|
返回顶楼 | |
发表时间:2009-05-20
wjyjimy 写道 你最多可以thread.sleep(922337203685477587);哦~
你直接就填10000000好了,以前学Midlet的时候老师好象说不要用pauseApp()来暂 停,要用就用thread.Sleep(),现在我都忘了Midlet怎么个写法了,呵呵~ 兄弟, 用点头脑好不好,你让它sleep了这么久,当你点开始的时候它还会反应么~~ |
|
返回顶楼 | |
发表时间:2009-05-20
iceliushuai 写道 wjyjimy 写道 你最多可以thread.sleep(922337203685477587);哦~
你直接就填10000000好了,以前学Midlet的时候老师好象说不要用pauseApp()来暂 停,要用就用thread.Sleep(),现在我都忘了Midlet怎么个写法了,呵呵~ 兄弟, 用点头脑好不好,你让它sleep了这么久,当你点开始的时候它还会反应么~~ 晕哦,,还说我不用脑子呢,你怎么连线程睡眠和唤醒都不知呢,你想什么时候不SLEEP(),就是直接调用interrupt() 终止睡眠咯,别告诉我你不会用,太没礼貌了。 |
|
返回顶楼 | |
发表时间:2009-05-21
最后修改:2009-05-21
wjyjimy 写道 晕哦,,还说我不用脑子呢,你怎么连线程睡眠和唤醒都不知呢,你想什么时候不SLEEP(),就是直接调用interrupt() 终止睡眠咯,别告诉我你不会用,太没礼貌了。 首先对我说有话表示歉意,说的有点重了。 在JAVA的API中,interrupt()是用来中断一个线程的,而不是中断睡眠的,如果调用了这个方法,这个线程就已经停止了,这和暂停的这种说法已经不同了。当然喽,经过你的启发,我想也可以设计成在点击”暂停“时直接中断“刷新界面”的线程,在点击”开始“时再次启动一个新线程,做同样的工作,但这和当前的讨论无关。 Java2 Platform Standard Ed. 6 写道 interrupt public void interrupt()中断线程。 如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException。 如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException。 如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。 如果以前的条件都没有保存,则该线程的中断状态将被设置。 中断一个不处于活动状态的线程不需要任何作用。 抛出: SecurityException - 如果当前线程无法修改该线程 |
|
返回顶楼 | |
发表时间:2009-05-21
唉 基础不是一般般的差
|
|
返回顶楼 | |