Android滚动位图分幅的背景
我试图确定在Android SurfaceView上滚动由平铺位图组成的背景的“最佳”方式。实际上,我已经成功地做到了这一点,但我想确定是否有一种更有效的技术,或者我的技术可能无法在所有Android手机上运行 基本上,我创建了一个新的、可变的位图,略大于我的SurfaceView的尺寸。具体来说,我的位图在顶部、底部、左侧和右侧容纳一行额外的瓷砖。我在新位图周围创建一个画布,并在其上绘制位图平铺。然后,只需将背景位图的“Surfaceview大小”子集绘制到SurfaceHolder的画布上,就可以向上滚动到任何方向的平铺 我的问题是:Android滚动位图分幅的背景,android,Android,我试图确定在Android SurfaceView上滚动由平铺位图组成的背景的“最佳”方式。实际上,我已经成功地做到了这一点,但我想确定是否有一种更有效的技术,或者我的技术可能无法在所有Android手机上运行 基本上,我创建了一个新的、可变的位图,略大于我的SurfaceView的尺寸。具体来说,我的位图在顶部、底部、左侧和右侧容纳一行额外的瓷砖。我在新位图周围创建一个画布,并在其上绘制位图平铺。然后,只需将背景位图的“Surfaceview大小”子集绘制到SurfaceHolder的画布上,
感谢您阅读所有这些内容,如果您有任何建议,我将不胜感激。我最初在我的“Box Fox”platformer游戏和RTS中使用了与您类似的技术,但发现如果您滚动到需要重新绘制位图的程度,会造成相当明显的延迟 我目前在这些游戏中使用的方法与你的选项C类似。我将我的平铺贴图层绘制到一个大位图网格上(大约7x7),占据比屏幕更大的区域。当用户滚动到此网格的边缘时,我将网格中的所有位图移到上面(将结束位图移到前面),更改网格的偏移量,然后重新绘制新的边缘 我不太确定哪个软件渲染更快(您的选项C或我当前的方法)。我认为,如果你改用OpenGL渲染,我的方法可能会更快,因为你不必像用户滚动一样向图形卡上传那么多纹理数据 我不推荐选项A,因为正如您所建议的那样,为平铺贴图绘制数百个小位图会降低性能,并且在较大屏幕上会变得非常糟糕。选项B甚至可能不适用于许多设备,因为在许多手机上堆空间限制设置得很低,因此很容易出现“位图大小超过VM预算”错误 此外,如果您的地图/背景不需要透明度,请尝试使用RGB_565位图,因为在软件中绘制要快得多,并且占用的内存更少
顺便说一下,我的手机和手机的速度上限都是60帧/秒“我的RTS中的平板电脑使用上述方法,在软件中渲染,可以在地图上平滑滚动。因此,您肯定可以从android软件渲染器中获得一些不错的速度。我已经为我的游戏构建了一个2D OpenGL包装器,但还不需要切换到它。我认为一个有效的方法是使用canvas.translate 在第一幅画上,整个画布必须用瓷砖填充。新的安卓手机可以轻松快速地做到这一点 当背景滚动时,我会使用
canvas.translate(scrollX,scrollY),
然后我会逐个绘制平铺以填补空白,但是,我会使用
canvas.drawBitmap(tileImage[i],fromRect,toRect,null)
,通过将fromRect和toRect设置为对应于scrollX和scrollY,只绘制需要显示的分幅部分
因此,所有这些都将由数学来完成,并且不会为背景创建新的位图-节省一些内存
编辑:
但是,将canvas.translate与surfaceView一起使用时出现问题,因为它是双缓冲的,canvas.translate将只转换一个缓冲区,而不会同时转换第二个缓冲区,因此,在依赖surfaceView来保存绘制的图像时,必须考虑缓冲区的这种交替。我在映射应用程序中的解决方案依赖于2级缓存,首先使用位图和位置创建平铺对象,这些对象存储在磁盘或向量中(同步对我来说很重要,到处都是多线程HTTP通信) 当我需要绘制背景时,我会检测到可见区域,并获得我需要的所有瓷砖的列表(这是经过大量优化的,因为它经常被调用),然后要么从内存中提取瓷砖,要么从磁盘加载。即使在稍旧的手机上,我也可以获得非常合理的性能,并且可以平滑地滚动,不会打嗝
作为一个警告,我允许不准备好瓷砖,并将其与加载图像交换,我不知道这是否适用于您,但如果您在APK中加载了所有瓷砖,您应该会很好。我正在使用您原来的方法绘制透视滚动背景。几天前,我在搞乱一张图片时偶然想到了这个想法使用一种简单的技术进行透视滚动星场模拟。该应用程序可在以下位置找到: 只需倾斜你的设备或摇动它以使背景滚动(请原谅2个弹跳精灵-他们在那里帮助我找到一种有效的方法来显示轨迹)。请告诉我你是否找到更好的方法来做这件事,因为多年来我已经编写了几种不同的方法,而这一种似乎更优越。