【读书笔记《Android游戏编程之从零开始》】14.游戏开发基础(Bitmap 位图的渲染与操作)

简介:

Bitmap 是图形类,Android 系统支持的图片格式有 png、jpg、bmp 等。

对位图操作在游戏中是很重要的知识点,比如游戏中需要两张除了大小之外其他完全相同的图,那么如果会对位图进行缩放操作,很容易就节约了一张图片资源;这样既节约了美工的时间,更节约游戏安装包的大小;当然除了缩放,还有很多操作,例如对位图进行旋转、镜像、设置透明度等等操作都会节约很大的资源。

首先创建一个位图实例。位图的实例不能通过 new,如果想通过一张图片资源文件创建一个位图,则要通过位图工厂来索引图片资源文件,从而生成一张位图实例,如下所示:

BitmapFactory.decodeResource(Resources res,int Id)

作用:通过资源文件生成一张位图

第一个参数:资源实例

第二个参数:资源ID

 

懂得如何通过图片资源创建位图实例后,下面就来详细介绍如何操作位图。创建项目“BitmapProject”,游戏框架为 SurfaceView 游戏框架。具体步骤参照“11.游戏开发基础(SurfaceView 游戏框架、View 和 SurfaceView 的区别)”。

我这个准备了一张图片pic01.png:

修改 MySurfaceView.java ,代码中 bmp 是由图片资源生成一个位图实例。

Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.drawable.pic01);

 

下面讲解位图常用的操作函数:

1.绘制位图

复制代码
                /**
                 * 在画布上绘制一张位图
                 * 第一个参数:位图实例
                 * 第二、三个参数:位图的X,Y坐标
                 * 第四个参数:画笔实例
                 */
                canvas.drawBitmap(bmp,0,0,paint);
复制代码

代码执行效果如下:

 

2.旋转位图

复制代码
                /**
                 * 旋转画布
                 * 第一个参数:画布旋转的角度
                 * 第二、三个参数:画布的旋转点
                 * 如果旋转的角度大于0,顺时针旋转;旋转的角度小于0,则逆时针旋转
                 *
                 * Canvas 中旋转画布还有一个函数:rotate(float degress),参数传入的是旋转画布的角度,此种方法无法设置旋转点,默认旋转点为屏幕中心点。
                 */
                canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2);
                canvas.drawBitmap(bmp,0,0,paint);
复制代码

代码执行效果如下:

如果想让位图进行旋转,那么通过这种旋转画布的方法即可实现。但是当使用此种实现画布旋转时,需要注意两点:

• 如果希望图片的旋转是以图片中心点进行旋转,那么在使用 rotate 旋转画布函数对画布进行旋转时,其旋转点坐标应该设置为图片的中心点坐标;

• rotate 函数是对整个画布进行旋转操作,也就是意味着,画布上所有绘制的元素都会因画布的旋转而进行对应的旋转。

例如代码修改为:

                canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2);
                canvas.drawBitmap(bmp,0,0,paint);
                canvas.drawBitmap(bmp,100,0,paint);

当旋转画布后,绘制两个位图,效果图如下所示:

通过图片可以明显看出,第二次绘制的图片也被旋转!当然这并不是想要的效果,那么如果只想对一张位图进行旋转操作该如何实现呢?

Canvas 类中有两个很重要的函数 save() 与 restore():

• save():作用是用于保存当前画布的状态;

• restore():作用是恢复上次保存的画布状态。

这两个函数是配对出现的。 注意 save() 函数出现的次数不能大于 restore() 函数。

 

对位图旋转代码进行修改:

复制代码
                //先保持画布的状态
                canvas.save();
                canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2);
                canvas.drawBitmap(bmp,0,0,paint);
                //再将画布恢复状态
                canvas.restore();
                canvas.drawBitmap(bmp,100,0,paint);
复制代码

项目运行效果如下:

所以,当对画布进行缩放、旋转和位移操作时,为了保证其他绘制的元素不受影响,应该利用 save() 与 restore() 对画布进行适当的保持与恢复操作。

 

除此之外 还有一种对位图进行旋转的方式,就是利用矩阵 Matrix 来实现,代码如下:

复制代码
                //首先创建一个矩阵实例
                Matrix mx = new Matrix();
                //然后对矩阵进行旋转缩放
                mx.postRotate(30,bmp.getWidth()/2,bmp.getHeight()/2);
                //最后使用画布绘制位图时,将矩阵信息作为参数传入
                canvas.drawBitmap(bmp,mx,paint);
复制代码

效果如下:

Matrix 类的 postRotate 函数与 Canvas 中的 rotate 函数的作用相同,参数表示的函数也都一致。

使用矩阵对位图进行操作时,可以免去对画布的状态保持和恢复,因为矩阵就是针对单独位图进行的操作,所以不会影响画布其他元素的绘制。

 

3.平移位图

复制代码
                //创建位图实例
                Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01);
                
                canvas.save();
                /**
                 * 平移图片
                 * 第一个参数:在X轴上平移画布的距离
                 * 第二个参数:在Y轴上平移画布的距离
                 */
                canvas.translate(100, 0);
                canvas.drawBitmap(bmp, 0, 0, paint);
                canvas.restore();
                
                canvas.save();
                canvas.translate(-90, 280);
                canvas.drawBitmap(bmp, 0, 0, paint);
                canvas.restore();
                
                canvas.save();
                //利用矩阵也可以完成对位图的平移操作
                Matrix maT = new Matrix();
                maT.postTranslate(380,-90);
                canvas.drawBitmap(bmp, maT, paint);
                canvas.restore();
复制代码

代码执行效果如下:

 

4.缩放位图

复制代码
                //创建位图实例
                Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01);
                
                canvas.save();        
                canvas.drawText("原图:", 0, 20, paint);    
                canvas.drawBitmap(bmp, 0, 40, paint);
                canvas.restore();

                canvas.save();
                /**
                 * 对画布进行缩放
                 * 第一个参数:对画布X轴的缩放比例
                 * 第二个参数:对画布Y轴的缩放比例
                 * 此方法无法设置缩放起始点,默认缩放起始点为屏幕的(0,0)点
                 */
                //缩小到0.5倍
                canvas.scale(0.5f, 0.5f);
                canvas.drawBitmap(bmp, 600, 40, paint);
                canvas.restore();
                
                canvas.save();
                /**
                 * 对画布进行缩放
                 * 第一个参数:对画布X轴的缩放比例
                 * 第二个参数:对画布Y轴的缩放比例
                 * 第三、四个参数:对画布进行缩放的起始点
                 */
                //放大为2倍
                canvas.scale(2f, 2f, 0, 0);
                canvas.drawBitmap(bmp, 0, 220, paint);
                canvas.restore();
                
                canvas.save();
                //,利用矩阵实现对位图的缩放操作,当前为缩小到0.75倍
                Matrix ma = new Matrix();
                ma.postTranslate(700, 40);
                ma.postScale(0.75f, 0.75f);
                canvas.drawBitmap(bmp,ma, paint);
                canvas.restore();
复制代码

代码执行效果如下:

 

5.镜像反转位图

复制代码
                //创建位图实例
                Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01);
                
                canvas.save();        
                canvas.drawText("原图:", 10, 20, paint);    
                canvas.drawBitmap(bmp, 10, 40, paint);
                canvas.restore();                
                
                //X 轴镜像
                canvas.save();
                canvas.drawText("X 轴镜像:", 10, 320, paint); 
                //当X轴的比例值小于0时,其实是对画布进行X轴的镜像后的缩放。
                canvas.scale(-1, 1, 10+bmp.getWidth()/2, 340+bmp.getHeight()/2);
                canvas.drawBitmap(bmp, 10, 340,paint);
                canvas.restore();
                
                //Y 轴镜像
                canvas.save();
                canvas.drawText("Y 轴镜像:", 10, 620, paint); 
                //利用矩阵实现对位图的镜像操作
                Matrix ma = new Matrix();
                ma.postTranslate(10, 640);
                ma.postScale(1, -1, bmp.getWidth()/2+10,bmp.getHeight()/2+640);
                canvas.drawBitmap(bmp,ma, paint);
                canvas.restore();
                
                //XY 轴镜像
                canvas.save();
                canvas.drawText("XY轴镜像:", 10, 920, paint); 
                canvas.scale(-1, -1, 10+bmp.getWidth()/2, 940+bmp.getHeight()/2);
                canvas.drawBitmap(bmp, 10, 940,paint);
                canvas.restore();
复制代码

代码执行效果如下:

 

在游戏开发中,一般最经常用的是 png 格式的图片,原因在于 png 格式的图片支持透明度,当然这不是必须的。






本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/p/4163943.html,如需转载请自行联系原作者
目录
相关文章
|
11月前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
327 5
|
11月前
|
Java Android开发
Android系统 获取用户最后操作时间回调实现和原理分析
Android系统 获取用户最后操作时间回调实现和原理分析
290 0
|
11月前
|
Linux Android开发
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
测试程序之提供ioctl函数应用操作GPIO适用于Linux/Android
218 0
|
7月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
118 20
Android经典面试题之图片Bitmap怎么做优化
|
8月前
|
编解码 开发工具 Android开发
Android平台RTSP|RTMP播放器如何实现TextureView渲染
本文介绍了在Android平台上使用TextureView进行RTSP和RTMP视频流渲染的技术背景和实现方法。TextureView相较于SurfaceView具备更高性能、更强功能性和更灵活的绘制方式等优势,但也有必须在硬件加速环境下运行和较高内存占用等局限。文中详细展示了如何在SmartPlayerV2工程中创建和配置TextureView,并通过代码示例解释了如何根据视频分辨率信息调整显示比例,以及处理TextureView的各种生命周期回调。此外,还列举了该播放器SDK支持的多项高级功能,如多实例播放、多种编码格式支持、硬解码能力等,旨在帮助开发者更好地理解和实现高性能的直播播放器。
153 3
|
10月前
|
存储 Java Android开发
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
68 2
|
10月前
|
XML API 开发工具
Android Bitmap 加载与像素操作
Android Bitmap 加载与像素操作
81 2
|
10月前
|
XML 前端开发 API
Android中实现Bitmap在自定义View中的放大与拖动
Android中实现Bitmap在自定义View中的放大与拖动
184 1
|
9月前
|
Android开发
Android kernel 操作gpio
Android kernel 操作gpio
123 0
|
11月前
|
Android开发 开发者
Android开发之通过渲染纹理展示地球仪
该文阐述了如何使用OpenGL为三维物体添加纹理,以增强其真实感。纹理坐标是二维的,用于标记摊平后的“布料”对应物体的哪个部位,类似裁缝制作衣服的过程。在OpenGL中,启用纹理和深度测试是关键,还包括设置纹理参数、分配纹理编号、绑定位图材质等步骤。计算材质的纹理坐标后,通过`glDrawArrays`结合顶点和纹理坐标逐个贴图。最终示例展示了将世界地图贴到球体上形成逼真的地球仪效果。通过控制旋转、平移和缩放,能实现简单的三维动画效果。
139 2
Android开发之通过渲染纹理展示地球仪
下一篇
oss创建bucket