关于在Java游戏中实现暂停的讨论

最近写了一个Swing版本的Snake程序,可是不太清楚怎么样来实现游戏中常见的暂停操作,所以我列出自己的一些方案,大家来讨论下什么样的方式会好些,还有就是如何更好的实现暂停这种方法。

方案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.贪吃蛇的程序已经放到论坛上,可以去下载看全部代码[url]http://www.iteye.com/topic/393669[/url]
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值