我正在开发一个简单的游戏,它使用普通的安卓视图,而不是openGL或其他apis,只使用视图并在屏幕上移动它们。我有一个游戏循环,它调用AsteroidManager.updateAsteroidsPositions(),在所有屏幕小行星中迭代,计算它的位置。
之后,线程使用runOnUiThread()方法调用一个runOnUiThread方法,因为在Android中,您需要操纵主线程上的视图。AsteroidManager.invalidateAsteroids()方法简单地迭代所有小行星,并将x,y的位置设置为视图,并调用calls ()。
问题是,我发现如果将calculatePositions的逻辑放入视图的onDraw方法中,它会提供一个更平滑和更快的行为。这样,计算位置的逻辑在游戏循环线程中没有被执行.它是在主UI线程中完成的!
那件事怎么可能?它打破了所有游戏发展的逻辑..。关于在游戏循环线程上进行位置计算,而不是像主线程或onDraws这样的位置计算。
这是较慢的原始代码:
AsteroidManager类:
public void updateAsteroidsPositions(){
for (int i = 0; i<onScreenAsteroids.size(); i++){
onScreenAsteroids.get(i).updatePosition();
}
}
public void invalidateAsteroids() {
for (int i = 0; i<onScreenAsteroids.size(); i++){
onScreenAsteroids.get(i).invalidate();
}
}小行星类:
public void updatePosition(){
currentScale = (Float) scaleX.getAnimatedValue();
factor = currentScale/MAX_SCALE;
//adding a minimum of factor, because with too low factor the movement is not realistic
if (factor < 0.250f)
factor = 0.250f;
x = x-((float)GameState.getInstance().getJoyX()*factor);
y = y-((float)GameState.getInstance().getJoyY()*factor);
}
public void invalidate(){
view.setX(x);
view.setY(y);
view.invalidate();
}这是在Asteroid类中所做的技巧,它使游戏的行为变得更流畅和更快:
小行星类:
public Asteroid(Bitmap bitmap, Context context) {
view = new ImageView(context){
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
currentScale = (Float) scaleX.getAnimatedValue();
factor = currentScale/MAX_SCALE;
//adding a minimum of factor, because with too low factor the movement is not realistic
if (factor < 0.250f)
factor = 0.250f;
x = x-((float)GameState.getInstance().getJoyX()*factor);
y = y-((float)GameState.getInstance().getJoyY()*factor);
view.setX(x);
view.setY(y);
}
};
view.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
view.setImageBitmap(bitmap);
}
public void updatePosition(){
}
public void invalidate(){
view.invalidate();
}发布于 2019-09-04 21:09:30
不是所有的游戏都需要游戏循环。线程切换有其自身的成本。
游戏循环将游戏状态与呈现分离开来。理想情况下,游戏循环负责处理游戏中所有屏幕上的对象,对象有责任在其位置绘制自己。这样,我们就有了对事件做出反应的中心位置(鼠标点击、用户触摸等)和更新视图的位置和视图,并有责任在更新的位置绘制自己。
考虑到我们屏幕上有10颗正在移动的小行星,我们正在onDraw()中更新它们,现在它们中的两颗碰撞了,但是asteroid1不知道asteroid2的位置,那么它们将如何检测碰撞呢?根据游戏逻辑,游戏回路知道所有10颗小行星的位置,它可以检测碰撞。如果不关心混乱的代码,那么在onDraw中也可以检测到冲突。但考虑下..。
如果两颗小行星发生碰撞,那么我们需要检查其他小行星是否在碰撞区域附近,如果是的话,那么撞击程度是多少?乱七八糟的东西线性增加。
碰撞后,我们决定显示碰撞图形效果。烂摊子成倍增加..。
小行星相撞,游戏状态=‘天空中的爆炸’,用户接到呼叫,游戏进入后台,游戏状态被拯救,但我们的小行星掌握着自己的命运,现在我们需要为我们的活动提供每个小行星的状态,并在onPause()中保存它。现在一团糟..。
用户在几个小时后返回,我们不能直接欢迎他们‘在天空中爆炸’,需要倒转到小行星即将碰撞的状态,然后显示爆炸.乱得乱七八糟.
观点是奴隶,不应该赋予他们权力。
在哪里显示视图,它的酒窝?->来自外部。
看什么呢?->来自外部/在这里几乎没有发言权。
如何动画视图?->来自外部。
关于您的具体情况,您使用的两个版本不同,在onDraw()的情况下,您是直接使小行星的失效(第一个是立即绘制的),而在游戏循环的情况下,您首先计算所有小行星的位置,然后失效,我不知道您有多少个小行星,但是如果它们是重要的数目,再加上线程切换成本,可能会欺骗您相信onDraw()更快。
https://stackoverflow.com/questions/57792056
复制相似问题