为什么不是';t view.invalidate立即在我的android游戏中重新绘制屏幕
我正在尝试制作一款android游戏 我有一个游戏类,可以扩展活动并处理所有用户输入。然后我有一个missionView类,它扩展了view,并在屏幕上绘制了标高 当用户单击门时,我想添加一些动画 发生的事情是:游戏调用door.open。更改状态,以便view.onDraw函数将门半开。游戏调用view.invalidate,这将重新绘制屏幕。然后游戏暂停半秒钟。然后它叫门,再开门。第二次调用该函数时,它会更改状态,以便view.onDraw函数将门完全打开。然后游戏再次调用view.invalidate 问题是它在进入view.invalidate时不会重新绘制屏幕。如果在该行上设置断点并运行调试器并单击“单步执行”,则不会单步执行我的view.onDraw函数。它甚至不能向我显示它正在执行的代码 我得到的是: 门类别:为什么不是';t view.invalidate立即在我的android游戏中重新绘制屏幕,android,Android,我正在尝试制作一款android游戏 我有一个游戏类,可以扩展活动并处理所有用户输入。然后我有一个missionView类,它扩展了view,并在屏幕上绘制了标高 当用户单击门时,我想添加一些动画 发生的事情是:游戏调用door.open。更改状态,以便view.onDraw函数将门半开。游戏调用view.invalidate,这将重新绘制屏幕。然后游戏暂停半秒钟。然后它叫门,再开门。第二次调用该函数时,它会更改状态,以便view.onDraw函数将门完全打开。然后游戏再次调用view.inva
public boolean open()
{
if (doorState == DoorState.Closed)
{
doorState = DoorState.Opening;
return true;
}
else if (doorState == DoorState.Opening)
{
doorState = doorState.Open;
return true;
}
else
{
return false;
}
}
游戏类别:
if (tile instanceof DoorTile)
{
DoorTile doorTile = (DoorTile) tile;
Door door = doorTile.getDoor();
if (door.isClosed())
{
door.open();
selectedEntity.openDoor();
view.invalidate(); // This line does not work
try
{
Thread.sleep(500);
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
door.open();
// Handled touch event so break switch statement
break;
}
}
View#invalidate告诉系统在主线程空闲时重新绘制(通过onDraw)视图。也就是说,调用invalidate计划在所有其他即时工作完成后重新绘制视图。如果游戏类中的代码是从主线程调用的,并且它使该线程处于休眠状态,那么您不仅仅是暂停渲染,而是同时暂停输入处理(通常是个坏主意)。根据经验,除非你知道自己在做什么,否则不要睡一根你自己没有产生的线
如果你想让你的游戏逻辑周期性地延迟使用线程#sleep,那么在一个单独的线程中运行它,并使用view.postInvalidate()来通知主线程唤醒并调用onDraw。对于游戏,我实际上会使用较低级别的图形访问。来自谷歌的消息就是一个很好的例子。基本上你需要做两件事:
- 使用SurfaceView而不是View
- 从SurfaceView获取处理程序
- 将view.invalidate()替换为包含
private void repaint() { Canvas c = null; try { c = surfaceHolder.lockCanvas(); paint(c); } finally { if (c != null) { surfaceHolder.unlockCanvasAndPost(c); } } }
绘制方法将包含您所看到的内容。onDraw目前我在应用程序中遇到了相同的问题 在我的例子中,我试图从
[doInBackground()][1]
方法的[AsyncTask][2]
调用invalidate()
通过将
invalidate()
移动到[onProgressUpdate()][3]
异步任务的方法,问题得以解决。也就是说,您不能从AsyncTask
的doInBackground()方法更新UI。Android文档中提到了它,但很容易忘记它。。。所以,别忘了检查一下。我可能会迟到,但我相信这对你有用
我是与Kotlin一起做这件事的。您可以根据Java进行修改
将代码放入runOnUIThread()
中
示例代码:
activity?.runOnUiThread {
// Your code goes here
}
希望这能有所帮助。只是为了添加…除非您自己创建线程,否则所有代码都会在UI线程中执行。如果你在这个线程中睡眠或进行大量计算,那么用户界面的响应性就会降低,最终你会得到一个应用程序无响应(ANR)框。它是有效的。。。某种程度上。门现在是动画,但现在当我在屏幕上滚动时,图形会出现问题。我的游戏类中有一个手势监听器,当用户用手指滚动时,它会重新绘制屏幕。它允许你在地图上滚动。它过去画得很好。但是现在我画了一半的屏幕,另一半在校正自身之前半秒钟都没有更新。使用不同的视图类并不能解决这个“问题”。有必要了解永远不要在主线程中调用sleep,失效不会立即触发绘图,而是在下次UI线程有机会重新绘制时“记住”需要重新绘制的区域。您可能想看看相关的讨论,我已经阅读了此讨论,但我不明白我该怎么做才能让我的代码正常工作。我不知道如何使用“Handler”和“Message”。