【问题标题】:android game surfaceview with framelayout slow带有框架布局的android游戏surfaceview慢
【发布时间】:2012-04-14 14:49:52
【问题描述】:

我目前正在编写游戏,现在遇到了问题。

在我的游戏中,如果我在我的自定义表面视图类上覆盖一个框架布局,我的帧速率将根据放置在框架布局中的视图小部件的数量而下降。

我正在使用框架布局来放置一些游戏控件和文本视图以进行点显示..

我曾想过直接在游戏循环中的表面视图上实现控件,但这基本上破坏了 Android UI 小部件的用途,而且必须在 XML 中移动会更容易。

如何解决这个问题?

这是我的代码: XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/FrameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<com.sora.game.npc.Panel
    android:id="@+id/myview1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="179dp"
    android:columnCount="8"
    android:rowCount="5" android:layout_gravity="bottom|left" android:visibility="visible">

    <Button
        android:id="@+id/upleft"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_column="0"
        android:layout_gravity="bottom|right"
        android:layout_row="0"
        android:text="↖" />

    <Button
        android:id="@+id/up"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_column="1"
        android:layout_gravity="bottom"
        android:layout_row="0"
        android:text="↑" />

    <Button
        android:id="@+id/upright"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_column="2"
        android:layout_columnSpan="4"
        android:layout_gravity="bottom"
        android:layout_row="0"
        android:text="↗" />

    <Button
        android:id="@+id/left"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_column="0"
        android:layout_gravity="bottom"
        android:layout_row="1"
        android:text="←" />

    <Button
        android:id="@+id/vdp"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_column="1"
        android:layout_gravity="bottom"
        android:layout_row="1"
        android:text="⥁" />

    <Button
        android:id="@+id/right"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_column="2"
        android:layout_columnSpan="4"
        android:layout_gravity="left"
        android:layout_row="1"
        android:text="→" />

    <Button
        android:id="@+id/downleft"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_column="0"
        android:layout_gravity="right"
        android:layout_row="2"
        android:text="↙" />

    <Button
        android:id="@+id/down"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_column="1"
        android:layout_gravity="left"
        android:layout_row="2"
        android:text="↓" />

    <Button
        android:id="@+id/downright"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_column="2"
        android:layout_columnSpan="4"
        android:layout_gravity="left"
        android:layout_row="2"
        android:text="↘" />

    <Space
        android:layout_width="1dp"
        android:layout_height="47dp"
        android:layout_column="0"
        android:layout_gravity="fill_horizontal"
        android:layout_row="1" />

    <Space
        android:layout_width="61dp"
        android:layout_height="1dp"
        android:layout_column="1"
        android:layout_gravity="fill_horizontal"
        android:layout_row="0" />

    <Space
        android:layout_width="30dp"
        android:layout_height="1dp"
        android:layout_column="2"
        android:layout_gravity="fill_horizontal"
        android:layout_row="0" />
</GridLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:drawingCacheQuality="high"
    android:visibility="visible" >

    <TextView
        android:id="@+id/life"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Life"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/score"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="Score"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:id="@+id/npcqt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="NPC quantity"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <Button
        android:id="@+id/strike"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/score"
        android:layout_marginTop="67dp"
        android:text="strike" />

    <Button
        android:id="@+id/fire"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:text="----Fire!----"/>

    <Button
        android:id="@+id/cycle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/strike"
        android:text="cycle" />

</RelativeLayout>

</FrameLayout>

编辑:我做了一些实验:

如果我将自定义表面视图缩放到顶部没有 UI 小部件(覆盖)表面视图的大小,则不会发生 FPS 的滞后和下降,这让我认为问题与渲​​染无关......

【问题讨论】:

    标签: android user-interface surfaceview android-framelayout


    【解决方案1】:

    我认为没有简单的解决方案。 只是为了确保我会首先使用 TraceView 来检查性能瓶颈的真正位置。 现在,如果这个瓶颈确实与 Android Widgets 相关(很可能是因为已知 SurfaceViews 与 Android Widgets 的结合成本很高)你可以尝试这样做。

        getWindow().setFormat(PixelFormat.RGB_565);
        holder.setFormat(PixelFormat.RGB_565);
    

    这可能有助于表面合成的性能,但您会失去 alpha。还要确保您的精灵具有相同的格式。 如果这没有帮助,您将需要使用更少的小部件或开始在画布上绘制您自己的小部件。但请务必查看 AndEngine 等游戏引擎。无需为基本任务重新发明*:-)

    另一个想法: 您是否在所有设备上或仅在平板电脑上看到性能问题? 以我个人的经验,平板电脑对性能问题更加敏感,因为它们的像素数比它们的 gpu 功率更高。那么你有没有在 manifest.xml 中开启硬件加速呢?

    【讨论】:

    • “这很可能是因为已知将 SurfaceViews 与 Android Widgets 结合起来成本很高”真的吗?我以前不知道!
    • 是的,表面视图绘制到单独的表面上,因此系统需要进行额外的表面合成。所以 SurfaceViews 总会有额外的开销。
    • 我还没有在平板电脑上尝试过我的游戏,但是在我的手机上(960*540)我可以在没有 UI 小部件的情况下获得 55~60fps 和 14~19fps 的 UI 小部件......跨度>