在游戏中要控制角色的移动速度是个比较麻烦的事情,至少对于新人来说,确实是这样的。比如拿贪吃蛇来说,要控制蛇的移动速度,甚至随着关数的增加,还需要加快蛇的移动速度,这个东西怎么来实现的呢?大体想法还是这样,在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,则将蛇的坐标更新一次,然后等待下次达到再更新,这样一直循环下去。
总结,虽然控制角色移动本身是件很简单的事,但要用于实战之中,做到模块的分化,性能的优化等还是很有难度的。在此把贪吃蛇的源码也放上来吧。
分享到:
相关推荐
NULL 博文链接:https://daikainan.iteye.com/blog/1406990
Android跑马灯,可以控制速度,并对对于文本长度大于屏幕分辨率情况,也可适用,史上最强的跑马灯实现。
PC可通过USB线或网络,控制android设备。
本科毕业设计论文,android解密游戏开发,从 1 绪论 1.1 课题的背景及意义1.2 研究现状1.3 论文主要工作1.4 论文结构安排 2 Android平台研究2.1 Android特征 2.2 Android应用的构成2.2.1 活动2.2.2 意图接收器2.2.3...
android手机控制电脑 2012年4月份做的 代码当时写的不是很规范 功能基本没有问题 鼠标控制模式: 鼠标的移动 鼠标左键点击 鼠标右键点击 鼠标滑轮 文件的拖动 自定义音量键功能 键盘输入模式: 向电脑发送文字...
Android 游戏开发之加速度传感器,可以很好的从这个例子中掌握相关技术。
git.diff 文件,包含功能实现的所有提交。...包含:编写控制GPIO脚本,内置到系统,在rc中创建运行脚本的服务,通过系统属性触发,添加selinux权限。 自行编写AndroidStudio Demo 更改系统属性 即可触发脚本,上拉GPIO
android android游戏开发
Android OpenGL 游戏引擎 Android OpenGL 游戏引擎 Android OpenGL 游戏引擎 Android OpenGL 游戏引擎
最近在网络上看到有网友抱怨Android游戏源码找不到,所以小弟收集了一些AndEngine和Libgdx的游戏源码,以Eclipse工程的形式配置好环境,再陆续发出(某引擎避嫌,不在此列)。 虽说主要是由Libgdx与AndEngine开发的...
Android已经成为很多手机厂家的首选操作平台,Android的Application也就越来越火爆了,这是Android游戏开发方面的一些基础知识,希望对大家有所帮助
Android 游戏教程 让人物动起来 源码
用Qt【服务器端】+Android【客户端】实现手机远程控制PC,内含服务器和客户端的所有代码。
方向控制自定义View Android方向控制自定义View Android方向控制自定义View Android
Android Stdio控制开发板
这是demo是android 通讯录,获取联系人的头像,姓名,手机号码,添加联系人;以及修改手机的声音;手机的实时流量
Android平台很经典的游戏Abduction(奶牛跳高)开场动画源代码。
android游戏角色移动地图是否可通行判断
androidTV RecyclerView 遥控器长按焦点丢失。自定义横向布局管理器来控制焦点的移动速度。