我没有2D图形和游戏体验。我教了几百个错误和几十个小时。我从简单的装扮游戏开始。我使用Nexus 5x进行开发,屏幕看起来不错。当我完成一个里程碑时,我在大联想平板电脑和小巧的三星迷你手机上试玩游戏。它看起来很可怕。
原始矢量PSD文件看起来很完美,PNG导出也没有任何问题。但是,当我缩放图片时,它是颠簸的。我知道它是位图。但是还有另一张我在其他地方缩放的图片,它看起来很好(两张图片都是32位):
当我从Google Play玩一些游戏时,他们从未遇到过扩展问题。他们是如何实施的?他们使用载体吗?有一些技巧吗?
我将所有内容放入assets
文件夹中,尽管耗时1 MB。我反编译了一些apk,他们没有为每个分辨率设置变种。虽然他们很好地缩放图片。
一些源代码片段:
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.w = w;
this.h = h;
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
protected void onDraw(Canvas canvas) {
if (baseBitmap != null) {
double scale = Math.min((double) w / (double) figure.getW(), (double) h / (double) figure.getH());
figure.setScaleRatio(scale);
int sw = (int) (scale * figure.getW());
int x = ((w - sw) >> 1);
figure.setX(x);
paintDressPart(canvas, figure, figure.getMain());
if (displayedParts != null) {
for (DressPart dressPart : figure.getParts()) {
if (displayedParts.contains(dressPart.getId())) {
paintDressPart(canvas, figure, dressPart);
}
}
}
}
}
private void paintDressPart(Canvas canvas, Figure figure, DressPart part) {
double scale = figure.getScaleRatio();
int sh = (int) (scale * part.getH());
int sw = (int) (scale * part.getW());
int sdx = (int) (scale * part.getDestX());
int sdy = (int) (scale * part.getDestY());
scaledRect.set(figure.getX() + sdx, sdy, figure.getX() + sw + sdx, sh + sdy);
Rect partRect = part.getRect();
canvas.drawBitmap(baseBitmap, partRect, scaledRect, canvasPaint);
}
如果您想亲眼看到它,我会在GitHub上准备完整的项目,以便您可以下载并自行运行:
https://github.com/literakl/DressUp
更新
缩小规模也很糟糕。但是由于Paavnet的评论,我意识到Paint非常重要。看图片上的差异:
我在3,2“AVD图像上运行了演示应用程序。图片278x786缩放到107x303。
十月更新
我重写了应用程序以使用资源文件夹而不是资产。 Android缩放图片,然后我再次重新缩放。虽然它看起来比我不使用Android资源扩展时更好。资源缩放图片看起来通常比未缩放的nodpi / assets图片好。
我发现mdpi效果最好。我甚至有xxhdpi图片,它看起来比mdpi更糟糕。我认为即使在xxhdpi设备上!但它可能是图片的一个麻烦,它没有很好地绘制。 Android资源缩放可能会平滑线条边缘。
答案 0 :(得分:1)
我面临同样的问题..缩放不是那么顺利..最好的标准方法
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);
你可以在网上找到更多优化的尺寸转换器..但实际上我最终使用的最佳解决方案是:
第一。使用矢量SVG资源..这是100%工作与完美的质量。只需确保SVG元素与android兼容(参见:https://developer.android.com/studio/write/vector-asset-studio.html)
的优点:
缺点:
或者
第二。提供高分辨率图像(一个在xxxhdpi就足够了)
的优点:
缺点:
我希望这可能有所帮助,'。
答案 1 :(得分:1)
他们使用矢量吗?
SVG / Vector 是一个方便的解决方案,但矢量艺术需要极高的精度,使其不适合许多艺术风格。它很容易使用基本形状的矢量艺术,但很难添加使用SVG符号样式的简单细节虽然可以使用png,jpeg
的颜色轻松添加。您可以在SVG上观看性能模式视频,其中googlers建议SVG
进行图标设计。大多数游戏都不会将其用于丰富而复杂的图像。
所以我不会去SVG
,尤其是那些小细节在游戏中很重要的地方。
他们是如何实施的?有一些技巧吗?
一种方法是使用单个常规资产支持(MDPI,HDPI)发布应用程序,如果屏幕密度需要高分辨率,则向用户显示一个对话框,询问他是否要下载高 - 决议资产。
您可以使用DisplayMetrics
根据手机密度要求,在运行时使用更高密度的图像并缩小图像。理想情况下,您应该保持相同的宽高比。为4制作的游戏: 3显示在16:9看起来很可怕,但16:10适合16:10,没有人注意到。read for more。
您可以使用这种方式轻松获取屏幕的高度和宽度(考虑到您使用SurfaceView
作为最佳做法)
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenHeight = metrics.heightPixels;
int screenWidth = metrics.widthPixels;
要在旋转时获得新的宽度高度:
surfaceChanged(SurfaceHolder holder, int format, int width, int height)
该方法为您提供表面的宽度/高度,因此您现在可以使用:
Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)
从Bitmap类中按照您要绘制的曲面大小的比例重新调整图像大小。您可以查看一些技术来查找合适的缩放因子。
OpenGL,kotlin
可以为您创建丰富的图形应用程序带来优势。使用这些可以控制内存和GPU
性能,这基本上是大多数游戏的支柱加上您可以利用使用GPU and native memory space
更有效地控制渲染加上你可以想到更多,如果你不熟悉它们需要一些时间,但一旦你得到它,它们可以做很多神奇的技巧。
Webp
将帮助您将大图像的大小减小到相当大的差异。应该尝试使用webp。 (建议,webp在某些设备上对图像的alpha通道有一点问题,但对于图像尺寸压缩来说太好了)
结论:使用 OpenGL,SurfaceView,NDK 实现最佳实践,并使用缩放因子docs link 有效加载图像,并且也应该尝试这样做。
您还可以查看9patch
图像,您可以在其中放置约束来缩放图像的某些部分而不是整体。这非常有用。
更新:根据建议,如果您要使用更高分辨率的图像,则also look into this和this禁用缩放或手动计算缩放系数。祝你好运
注意:如果您愿意,可以随时使用有效信息编辑此答案。