我只想弄清楚在Android设备上运行scolling背景的最佳方法。到目前为止我的方法......它非常滞后。我使用线程,我认为这不是Android平台的最佳选择
@Override
public void run() {
// Game Loop
while(runningThread){
//Scroll background down
bgY += 1;
try {
this.postInvalidate();
t.sleep(10);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其中onDraw函数中的postinvalidate只是向下推送背景图像
canvas.drawBitmap(backgroundImage, bgX, bgY, null);
提前致谢
更新
我发现了问题所在。事实上,我的播放器更新与背景滚动相同的速率(使其看起来波涛汹涌)。从上到下。这是因为两者都被绘制在同一个函数中。我不太确定如何解决这个问题,并且对任何帮助都会感激不尽。即使玩家移动与地图滚动分开处理
另外,我如何控制调用onDraw(画布)的速度?
提前致谢。
但是,我已经为具有相同问题的任何人修补了不同的运行循环。这部分来自Google上的jetboy示例。
以下是我在surfaceview中的内部课程
class MapThread extends Thread{
private Map map;
private SurfaceHolder holder;
private boolean run = false;
public MapThread(Map map, SurfaceHolder holder){
this.holder = holder;
this.map = map;
setRunning(true);
}
public void setRunning(boolean run){
this.run = run;
}
@Override
public void run(){
while(run){
try{
Canvas c = null;
try {
c = holder.lockCanvas(null);
synchronized (holder) {
map.onDraw(c);
}
} finally {
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
}
}
}
解
https://gamedev.stackexchange.com/questions/8127/android-game-scrolling-background
答案 0 :(得分:3)
在屏幕上使用SurfaceView实施图。它允许您更多地控制绘制内容和何时绘制。
SurfaceView是View的一个特殊子类,它在View层次结构中提供专用的绘图表面。目的是将此绘图表面提供给应用程序的辅助线程,以便应用程序不需要等到系统的View层次结构准备好绘制。
基本设计是在一个while循环中连续绘制一个surfaceview。然后添加一个if语句,如果计时器线程告诉您绘制时间,则其条件为true。比方说,每30ms绘制一次位图。这将为您提供大约33 fps。
现在您可能还有另一个计时器线程,它告诉您何时更新bgX或bgY值。比如说每隔60ms就会设置一个布尔值updateFlag = true;然后在你的主线程中,你有一个if语句检查这个标志,将它设置为false,并更新你的bgX和bgY值。通过精确控制计时器和bgX / bgY增量,您应该能够生成平滑的动画。
查看Google提供的LunarLander源代码是个好主意。
答案 1 :(得分:0)
要记住的一件事是睡眠非常不准确。要解决这个问题,你可以准确地记录睡眠过程中经过的时间,并相应地更新你移动的东西。
您的代码不清楚,但您需要确保所有UI更新都在UI线程中发生。
您需要在UI线程之外进行计时,否则UI将永远不会更新。还有其他的计时方法,比如使用Handler可以稍微清洁一点,但我认为它们的开销可能对你要做的事情有点多。我认为一个简单的线程具有最少的开销。
答案 2 :(得分:0)
我在SpaceQuestAlpha游戏的第二级使用此方法。这使得一个无缝的卷轴。
我使用下面两行来设置原始位置。
moony=0;
moon2y=-(heighty);
然后这些行增加背景图像的两个版本。一个从0开始,一个从负屏幕高度开始。每当其中一个图像低于屏幕底部时,它就会向上移动两倍高度以将其移回原位。我正在使用表面视图,没有延迟问题。
moony+=5;
moon2y+=5;
if(moon2y>=heighty) {moon2y=moon2y-(heighty*2);}
canvas.drawBitmap(lavabackground, 0, moon2y, null);
if(moony>=heighty){moony=moony-(heighty*2);}
canvas.drawBitmap(lavabackground, 0, moony, null);