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 格式的图片支持透明度,当然这不是必须的。

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

  1. Windows游戏编程之从零开始d

    Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...

  2. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

  3. Java并发编程的艺术读书笔记(1)-并发编程的挑战

    title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- ...

  4. 读书笔记--Android Gradle权威指南(下)

    前言 最近看了一本书<Android Gradle 权威指南>,收获挺多,就想着来记录一些读书笔记,方便后续查阅. 本篇内容是基于上一篇:读书笔记--Android Gradle权威指南( ...

  5. 《Essential C++》读书笔记 之 C++编程基础

    <Essential C++>读书笔记 之 C++编程基础 2014-07-03 1.1 如何撰写C++程序 头文件 命名空间 1.2 对象的定义与初始化 1.3 撰写表达式 运算符的优先 ...

  6. 【读书笔记《Android游戏编程之从零开始》】18.游戏开发基础(碰撞检测)

    1.矩形碰撞 所谓矩形碰撞,就是利用两个矩形之间的位置关系来进行判断,如果矩形的像素在另外一个矩形之中,或者之上都可以认为这两个矩形发生了碰撞. 如果单纯的去考虑哪些情况会判定两个矩形发生碰撞,倒不如 ...

  7. 【读书笔记《Android游戏编程之从零开始》】19.游戏开发基础(游戏音乐与音效)

    在一款游戏中,除了华丽的界面 UI 直接吸引玩家外,另外重要的就是游戏的背景音乐与音效:合适的背景音乐以及精彩的音效搭配会令整个游戏上升一个档次. 在 Android 中.常用于播放游戏背景音乐的类是 ...

  8. 【读书笔记《Android游戏编程之从零开始》】16.游戏开发基础(动画)

    1. Animation动画   在Android 中,系统提供了动画类 Animation ,其中又分为四种动画效果: ● AlphaAnimation:透明度渐变动画 ● ScaleAnimati ...

  9. 【读书笔记《Android游戏编程之从零开始》】12.游戏开发基础(Canvas 画布)

    1.Canvas 画布 画布类 Canvas 封装了图形和图片绘制等内容,此类常用的函数说明如下: drawColor(int color) 作用:绘制颜色覆盖画布,常用于刷屏 参数:颜色值,也可用十 ...

随机推荐

  1. 启动Eclipse 弹出"Failed to load the JNI shared library jvm.dll"错误

    启动Eclipse 弹出"Failed to load the JNI shared library jvm.dll"错误,如下 原因:eclipse的版本与jre或者jdk版本不 ...

  2. Linux Shell系列教程之(十六) Shell输入输出重定向

    本文是Linux Shell系列教程的第(十六)篇,更多Linux Shell教程请看:Linux Shell系列教程 Shell中的输出和输入的重定向是在使用中经常用到的一个功能,非常实用,今天就为 ...

  3. 【JavaEE】SSH+Spring Security自定义Security的部分处理策略

    本文建立在 SSH与Spring Security整合 一文的基础上,从这篇文章的example上做修改,或者从 配置了AOP 的example上做修改皆可.这里主要补充我在实际使用Spring Se ...

  4. [js开源组件开发]js多选日期控件

    js多选日期控件 详情请见:http://www.lovewebgames.com/jsmodule/calendar.html 它的github地址:https://github.com/tianx ...

  5. 自己写的表格插件autotable

    自己写的表格插件autotable 作者:田想兵,个人网址:http://www.lovewebgames.com 这个表格插件所完成的功能是:ajax请求数据,然后动态绑定到指定表格下,格式化,分页 ...

  6. angular 指令——时钟范例

    <html> <head> <meta charset='utf-8'> <title>模块化</title> <script typ ...

  7. Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结

    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结 1. office word  excel pdf 的web预览要求 ...

  8. 案例分享:电信行业零售业务CRM架构

    最近跟一个客户讨论销售领域的移动化需求,谈到了他们的零售业务系统的整体框架,觉得很有分享的必要. 这次聊到的客户是电信行业的巨头,说的是他们的零售业务.电信公司么,卖出去的无非是设备和服务.大体的业务 ...

  9. Bonobo Git Server (Simple git server for Windows.) 测试备忘

    Bonobo Git Server是一款Windows上的Git Server,它使用IIS即可,走的是Http协议,只要简单的安装就能使用,但是因为我的项目大小有1.35GB在 push 的时候一直 ...

  10. 换SSD硬盘,重装系统,一阵子忙乱

    许久没重装过系统了,低声下气地问老板要了一块SSD硬盘,不马上安装上手痒得难受,但年底这个时候重装系统绝对忙乱,差点耽误了一份申请表和一份培训记录表.   SSD安装:先从网上找相关贴子,最主要的一个 ...