android 游戏 人物控制,android游戏角色的速度控制

在游戏中要控制角色的移动速度是个比较麻烦的事情,至少对于新人来说,确实是这样的。比如拿贪吃蛇来说,要控制蛇的移动速度,甚至随着关数的增加,还需要加快蛇的移动速度,这个东西怎么来实现的呢?大体想法还是这样,在while循环里判断当前时间是否已经达到角色移动一步所需要的时间,如果达到则更新角色坐标,再更新画面。

如果这样的话,我也就不用单独写博客了,这里主要是以《beginning android games》的贪吃蛇为例,最近发现这本书确实写得很好。作者将游戏的模块封装得很好,很值得学习与借鉴。

关于游戏角色的画面更新有一个很重要的类AndroidFastRenderView:

public class AndroidFastRenderView extends SurfaceView implements Runnable {

AndroidGame game;

Bitmap framebuffer;

Thread renderThread = null;

SurfaceHolder holder;

volatile boolean running = false;

public AndroidFastRenderView(AndroidGame game, Bitmap framebuffer) {

super(game);

this.game = game;

this.framebuffer = framebuffer;

this.holder = getHolder();

}

public void resume() {

running = true;

renderThread = new Thread(this);

renderThread.start();

}

public void run() {

Rect dstRect = new Rect();

long startTime = System.nanoTime();

while(running) {

if(!holder.getSurface().isValid())

continue;

float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;

startTime = System.nanoTime();

game.getCurrentScreen().update(deltaTime);

game.getCurrentScreen().present(deltaTime);

Canvas canvas = holder.lockCanvas();

canvas.getClipBounds(dstRect);

canvas.drawBitmap(framebuffer, null, dstRect, null);

holder.unlockCanvasAndPost(canvas);

}

}

public void pause() {

running = false;

while(true) {

try {

renderThread.join();

break;

} catch (InterruptedException e) {

// retry

}

}

}

}

这个类里面有很多值得学习或者注意的东西。

1.这个类继承了SurfaceView类,这个SurfaceView也是一个View类,主要作用是在开启另外一个线程,并通过GPU等硬件加速功能将视图渲染显示出来。基本上所有的UI组件显示最好的方法最是单独开启线程显示,这样就不会因独占主线程而导致界面不流畅。

由于AndroidFastRenderView本身继承了Runnable接口,所以它是一个线程,其最重要的逻辑放在run方法内。

2.要使用画图功能时,需要用到Canvas,这个Canvas不是像平时那样直接通过new Canvas()而得到,而是通过SurfaceHolder的lockCanvas方法而来,而得到SurfaceHolder的实例是通过父类的getHolder()方法。在画图时,先由holder.lockCanvas()得到Canvas实例,将所有图画完这后再由holder.unlockCanvasAndPost(canvas)统一提交,这时才开始所有的绘图工作。这样一次性处理既可以利用GPU加速,也可以使用缓冲技术,以此达到性能优化的目的。

3.还有一点需要注意,那就是running字段,这个字段的作用是判断游戏当前是否在运行,需要用volatile关键字申明。这样能保证running的值每次都从主存中读取而不是来自本地内存中。

上面这个类非常关键,但它只保证不停的执行update与present方法,并不能达到精确控制角色移动速度的目的。而控制速度的方法是由World类的update完成的。

。。。

public void update(float deltaTime) {

if (gameOver)

return;

tickTime += deltaTime;

while (tickTime > tick) {

tickTime -= tick;

snake.advance();

if (snake.checkBitten()) {

gameOver = true;

return;

}

SnakePart head = snake.parts.get(0);

//头部接触到stain时

if (head.x == stain.x && head.y == stain.y) {

score += SCORE_INCREMENT;

snake.eat();

if (snake.parts.size() == WORLD_WIDTH * WORLD_HEIGHT) {

gameOver = true;

return;

} else {

placeStain();

}

//增加移动速度

if (score % 100 == 0 && tick - TICK_DECREMENT > 0) {

tick -= TICK_DECREMENT;

}

}

}

}

。。。

上面方法中,deltaTime表示AndroidFastRenderView执行每次循环所需要的时间,tickTime用于存储移动一步所需要累计的时间,如果达到累计时间tickTime达到移动一步所需要的时间tick,则将蛇的坐标更新一次,然后等待下次达到再更新,这样一直循环下去。

总结,虽然控制角色移动本身是件很简单的事,但要用于实战之中,做到模块的分化,性能的优化等还是很有难度的。在此把贪吃蛇的源码也放上来吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值