为什么触摸事件会破坏我的 Android 帧速率?

发布于 2024-07-17 07:57:39 字数 561 浏览 13 评论 0原文

我正在开发一款 Android 游戏。 虽然发生了很多事情,但运行相当顺利。 当然,直到用户触摸屏幕。

当他们触摸它时,会调用 onTouchEvent(使用 action = ACTION_MOVEx = 0y = 0 >)大约每十毫秒一次,这似乎是相当高的优先级,因为它绝对会消除帧速率。 一旦触摸结束,帧速率就会恢复到良好的状态。

我尝试

  • onTouchEvent 像往常一样处理游戏的输入,
  • onTouchEvent 立即返回 true
  • 没有 onTouchEvent完全实施

该问题在所有三种情况下都存在。

有人遇到过这种情况吗? 有没有办法降低 ACTION_MOVE 事件的生成速率,或者确保它们仅在实际移动时生成,或者使用仅获取当前位置的轮询方法触碰? 或者只是一种完全禁用它的方法?

I'm developing a game for Android. It's got a lot going on but is running reasonably smoothly. That is, of course, until the user touches the screen.

While they're touching it, onTouchEvent is called (with action = ACTION_MOVE, x = 0 and y = 0) roughly once every ten milliseconds at what appears to be a fairly high priority, as it absolutely obliterates the framerate. As soon as the touch ends the framerate returns to its nice state.

I've tried

  • having onTouchEvent handle input for the game as usual
  • having onTouchEvent return true straight away
  • not having onTouchEvent implemented at all

The problem persists in all three situations.

Has anyone encountered this? Is there a way to reduce the rate at which ACTION_MOVE events are generated, or to ensure that they're only generated when there is actual movement, or use a polling method that just gets the current location of the touch? Or even just a way to disable it entirely?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

只是偏爱你 2024-07-24 07:57:39

阅读此帖子。 基本上,您希望使事件线程休眠,否则系统将泵送大量您需要处理的事件(在 x、y 和压力之间总是发生一些运动)。

Read this thread. Basically you want to sleep the event thread since otherwise the system will pump a lot of events (between x,y and pressure there is always some movement going on) that you need to handle.

旧伤慢歌 2024-07-24 07:57:39

我一直在努力听懂你们所说的一切
关于,但我必须承认,在尝试了几种实施方法之后
根据你的建议,我仍然没有取得任何积极的成果
结果。 你们中的一个人可以提供一些示例代码吗? 具体来说,
我想知道如何让主/UI 线程休眠。 如果
它适用于我的游戏,如果知道如何设置也很好
像 Jon 一样建立一个轮询模型。

这是我的代码的样子。 在 UI 线程上:

public boolean onTouchEvent(MotionEvent event) {
    // Store event somewhere the game thread can see it:
    // ...

    synchronized (someObject) {
        try {
            someObject.wait(1000L);
        } catch (InterruptedException e) {
        }
    }

    return true;
}

和在 Game 线程上:

void myGame() {
    while (!stopping) {
        // ...

        // Get a touch event:
        synchronized (someObject) {
            someObject.notify();
        }
        Thread.yield();

        // ...
    }
}

I've been trying to follow everything you guys have been talking
about, but I must admit that after trying several ways of implementing
what you suggest, I still haven't been able to achieve any positive
results. Could one of you provide some example code? Specifically,
I'd like to know how to go about making the main/UI thread sleep. If
it's applicable to my games, it would also be nice to know how to set
up a polling model like Jon implemented.

Here's what my code looks like. On the UI thread:

public boolean onTouchEvent(MotionEvent event) {
    // Store event somewhere the game thread can see it:
    // ...

    synchronized (someObject) {
        try {
            someObject.wait(1000L);
        } catch (InterruptedException e) {
        }
    }

    return true;
}

and on the Game thread:

void myGame() {
    while (!stopping) {
        // ...

        // Get a touch event:
        synchronized (someObject) {
            someObject.notify();
        }
        Thread.yield();

        // ...
    }
}
把时间冻结 2024-07-24 07:57:39

也许这是一个比较明显的解决方案,但是...您是否尝试过只处理其中的大约 1/10? 如果您正在执行 UI 线程上每 10 毫秒触发一次的处理,那么这可能会降低帧速率,是的。 那么,如果您只是累积一个计数器,并且仅在超过某个最小阈值后才进行任何处理,该怎么办?

Perhaps a somewhat obvious solution, but... have you tried only handling about 1/10 of them? If you're doing processing that's triggered every 10ms on the UI thread, that's likely going to slow down the framerate, yes. So what if you just accumulate a counter somewhat instead and only do any processing once that's gotten past some minimal threshold?

硬不硬你别怂 2024-07-24 07:57:39

如果您想要一个无需处理同步线程的解决方案,我建议您使用 Handler 接口,使用 Message/Bundle 将事件和相关数据发送到游戏渲染线程。 这里暗示的睡眠解决方法仍然适用。

If you want a solution without having to deal with synchronizing threads I can recommend using the Handler interface to send the event and relevant data using a Message/Bundle to the game rendering thread. The sleep workaround hinted here still applies.

深陷 2024-07-24 07:57:39

通常,事件带有时间戳属性,因此很容易计算和限制事件速率。

if (currentEventTimestamp - lastEventTimestamp > 500) { 

    lastEventTimestamp = currentEventTimestamp;

    // do something 

}

Generally events comes with a timestamp property so it's easy to compute and throttle event rate.

if (currentEventTimestamp - lastEventTimestamp > 500) { 

    lastEventTimestamp = currentEventTimestamp;

    // do something 

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文