【Android游戏开发十一】手把手让你爱上Android sdk自带“9妹”

本站文章均为 李华明Himi 原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/321.html

 

    前几天群成员讨论过关于9patch的工具【我比较喜欢喊它9妹子,西西(*^_^*)】、然后研究了一下,比较简单但是很实用的一个Android sdk 自带工具、这里给大家做一个分享下经验!

 1.什么是“9妹”(9patch)?

    它是一个对png图片做处理的一个工具,能够为我们生成一个"*.9.png"的图片;

2.何为"*.9.png"?

    所谓"*.9.png"这是Android os里所支持的一种特殊的图片格式,用它可以实现部分拉伸;这种图片是经过”9妹“进行特殊处理过的,如果不处理的话,直接用PNG图就会有失真,拉伸不正常的现象出现。

3.它的用途是?

    说到用途,这种特殊格式的png图,我也看了网上的相关文章但都是用一个能自适应的button举例子!(如下图)清一色抄袭.. - -、

 

 (此实例咱们直接无视掉,在后面我会给大家灌输游戏中实例)

    这个例子是指当button上的字体大小改变,那么文字底下的png图也会自动适应文字。

    这似乎表明做Android 软件应用 使用一些组件的的时候会时常用到;

4.那么实际在游戏中到底如何使用呢?什么情况下去使用呢?

    当然啦,身为做游戏我一定要”9妹“利用在咱们游戏中才行,不然岂不是白研究了、经过思考突然想到了一些情况,并且发现“9妹”确实在游戏开发中占有一定的分量!下面我们来先熟习“9妹”工具,然后再跟大家举例,贴图来说明其用途、毕竟有图有真相 呵呵~

 启动9妹:

    在你Android SDK 路径下 X:/android sdk/tools ,你会找到一个 【draw9patch.bat】,没错这就是9妹啦、官方名 NinePatch ; 

 提示导入一张png图片,然后真正进入"9妹"的操作界面(如下图): (图1) 

      序列 ① :在拉伸区域周围用红色边框显示可能会对拉伸后的图片产生变形的区域,如果完全消除该内容则图片拉伸后是没有变形的,也就是说,不管如何缩放图片显示都是良 好的。 (实际试 发现NinePatch编辑器是根据图片的颜色值来区分是否为bad patch的,一边来说只要色差不是太大不用考虑这个设置。)

    序列 ② :区域是导入的图片,以及可操作区域。

    序列 ③ :这里 zoom:的长条bar 是对导入的图放大缩小操作,这里的放大缩小只是为了让使用者更方便操作,毕竟是对像素点操作比较费眼,下面的 patch scale 是序列 ④区域中的三种形态的拉伸后的一个预览操作,可以看到操作后的图片拉伸后的效果。

    序列 ④: 区域这里从上到下,依次为:纵向拉伸的效果预览、横向拉伸的效果预览,以及整体拉伸的效果预览

    序列 ⑤: 这里如果你勾选上,那么当你鼠标放在 ② 区域内的时候并且当前位置为不可操作区域就会出现lock的一张图,就是显示不可编辑区域 ;

    序列 ⑥: 这里勾选上,那么在④ 区域中你就会看到当前操作的像素点在拉伸预览图中的相对位置和效果。

    序列 ⑦: 在编辑区域显示图片拉伸的区域;

 

如何操作:鼠标左键选取需要拉伸的像素点; shift+鼠标左键取消当前像素点。

操作区域: 

    大家看到导入的png图片默认周围多了一像素点,也就是这一圈一像素点就是咱们的可操作区域。因为方和右方可操作区域是指定内容的显示区域,属于可选区域,可不予理会;但是要注意内容区域的标记不能有间断,也就是说标记要连续且仅有一处,否则.9.png图片在放入项目下会报错。

主要大家注意Left 和 top 操作区域;

     Top操作区域的一排像素点,表示横向拉伸的像素点;

    Left操作区的一排像素点,表示纵向拉伸的像素点;

  

下图是我对图片的操作:(图2)

    大家看到上方和左边的黑色像素了么?对,这些是我手动操作的地方,我这里是想让此png图像拉伸操作的时候,只是中间区域被拉伸。选择上方中间区域是为了横向拉伸的时候选取的拉伸像素点,左边则是纵向拉伸的;

     那么大家现在回头看一眼(图1)然后对比(图2),看到区别了吧!很明显,(图1)我们没有任何操作,默认整体拉伸,那么拉伸的效果很明显的失真了...而(图2)我们指定了拉伸的像素点所以只是中间的被拉伸,图片的花边我们保留不拉伸这样看起来就好太多啦 娃哈哈、

    然后通过“9妹”就可以保存出来一张“*.9.png”图片,我们放在android 项目的res 下的 drawable 下就可以拉!

 现在我就可以跟大家讲下使用“*.9.png”的好处:

     在我们手机游戏开发的过程中,我们最关系的是生成的安装文件、比如j2me 的jar 包,塞班的sis、sisx 以及咱们andrid中的apk都希望打包后的包越小越好、虽然现在的手机趋向于智能了,但是毕竟手机的容量和内存还是有限、身为移动设备开发者的我们对此都很看重,那么通过"9妹"处理后的图片我们就可以省去不少的内存和容量。

1. 省精力和时间!

    如果我们有一张50*50的类似上面那种带花边的png图片,那么我们在android或者大分辨率的机器上使用的画,肯定需要对其处理,那么要不就是让美工的mm们给咱们重新做一张,那么通过"9妹"处理得到的“*.9.png”就会省去美工的负担了。

2.省内存!

    如果不想用代码来对其小图进行缩放来再次使用(因为考虑会失真),那么可能会多加了图片,这样一来游戏包的大小就会增加了,几K—几十K不等,而利用"9妹"处理的就省去了这些麻烦。

3.减少代码量!

    有些童鞋该说啦,我用代码一样能实现(图2)的效果不失真,OK,我也知道。当初我在J2ME平台做RPG的时候也是利用设置可视区域等代码来实现的,但是如果你用“.9.png”的方式就更简单!!!

     不多吹 “9妹”的好处,下面我们来看看代码如何实现此格式的方式和效果吧! 

  1. package com.himi;  
  2. import android.content.Context;  
  3. import android.graphics.Bitmap;  
  4. import android.graphics.BitmapFactory;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.NinePatch;  
  8. import android.graphics.Paint;  
  9. import android.graphics.RectF;  
  10. import android.util.Log;  
  11. import android.view.SurfaceHolder;  
  12. import android.view.SurfaceView;  
  13. import android.view.SurfaceHolder.Callback;  
  14. public class MySurfaceView extends SurfaceView implements Callback, Runnable {  
  15.     private Thread th = new Thread(this);  
  16.     private SurfaceHolder sfh;  
  17.     private Canvas canvas;  
  18.     private Paint paint;  
  19.     private Bitmap bmp_old;  
  20.     private Bitmap bmp_9path;  
  21.     private NinePatch np;  
  22.     public MySurfaceView(Context context) {  
  23.         super(context);  
  24.         this.setKeepScreenOn(true);  
  25.         bmp_old = BitmapFactory.decodeResource(getResources(), R.drawable.himi_old);  
  26.         bmp_9path = BitmapFactory.decodeResource(getResources(), R.drawable.himi_9path);  
  27.         np = new NinePatch(bmp_9path, bmp_9path.getNinePatchChunk(), null);  
  28.         //创建一个ninePatch的对象实例,第一个参数是bitmap、第二个参数是byte[],这里其实要求我们传入  
  29.         //如何处理拉伸方式,当然我们不需要自己传入,因为“.9.png”图片自身有这些信息数据,  
  30.         //也就是我们用“9妹”工具操作的信息! 我们直接用“.9.png”图片自身的数据调用getNinePatchChunk()即可  
  31.         //第三个参数是图片源的名称,这个参数为可选参数,直接null~就OK~  
  32.         sfh = this.getHolder();  
  33.         sfh.addCallback(this);  
  34.         paint = new Paint();  
  35.         paint.setAntiAlias(true);  
  36.         setFocusable(true);  
  37.     }  
  38.     public void surfaceCreated(SurfaceHolder holder) {  
  39.         Log.v("Himi", "surfaceCreated");  
  40.         th.start();  
  41.     }  
  42.     /**  
  43.      * @author Himi  
  44.      */  
  45.     public void draw() {  
  46.         canvas = sfh.lockCanvas();  
  47.         canvas.drawColor(Color.BLACK);  
  48.         RectF rectf_old_two = new RectF(0, 50, bmp_old.getWidth() * 2, 120 + bmp_old.getHeight() * 2);//备注1  
  49.         RectF rectf_old_third = new RectF(0, 120 + bmp_old.getHeight() * 2, bmp_old.getWidth() * 3,  
  50.                 140 + bmp_old.getHeight() * 2 + bmp_old.getHeight() * 3);  
  51.         // --------下面是对正常png绘画方法-----------  
  52.         canvas.drawBitmap(bmp_old, 0, 0, paint);  
  53.         canvas.drawBitmap(bmp_old, null, rectf_old_two, paint);  
  54.         canvas.drawBitmap(bmp_old, null, rectf_old_third, paint);  
  55.         RectF rectf_9path_two = new RectF(250, 50, 250 + bmp_9path.getWidth() * 2, 90 + bmp_9path.getHeight() * 2);  
  56.         RectF rectf_9path_third = new RectF(250, 120 + bmp_9path.getHeight() * 2, 250 + bmp_9path.getWidth() * 3,  
  57.                     140 + bmp_9path.getHeight() * 2  
  58.                 + bmp_9path.getHeight() * 3);  
  59.         canvas.drawBitmap(bmp_9path, 250, 0, paint);  
  60.         // --------下面是".9.png"图像的绘画方法-----------  
  61.         np.draw(canvas, rectf_9path_two);  
  62.         np.draw(canvas, rectf_9path_third);  
  63.         sfh.unlockCanvasAndPost(canvas);  
  64.     }  
  65.     public void run() {  
  66.         // TODO Auto-generated method stub  
  67.         while (true) {  
  68.             draw();  
  69.             try {  
  70.                 Thread.sleep(100);  
  71.             } catch (Exception ex) {  
  72.             }  
  73.         }  
  74.     }  
  75.     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  76.         Log.v("Himi", "surfaceChanged");  
  77.     }  
  78.     public void surfaceDestroyed(SurfaceHolder holder) {  
  79.         Log.v("Himi", "surfaceDestroyed");  
  80.     }  

下图是模拟器中的效果图、

  

    左边是正常png的缩放不同大小的情况,右边是咱们的9妹处理过的“*.9.png”、娃哈哈,怎么样 效果明显不一样吧!

  好啦,到这里就结篇吧,挺累的 写了三个多小时了....... 希望大家以后多多的利用 “9妹”哦、

 (推荐大家订阅本博客,因为咱的更新速度可是很快的~娃哈哈)

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297488.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么PostgreSQL比MongoDB还快之完结篇(深挖单点索引查询)

之前两篇测试中发现:单点索引查询中PostgreSQL的速度是MongoDB(WiredTiger引擎)的4倍。http://blog.chinaunix.net/xmlrpc.php?rblog/article&uid20726500&id4960138http://blog.chinaunix.net/xmlrpc.php?rblog/article&uid20726500&id4981629虽…

ajax和spa的区别,在XX团上消费过一次不正规的Spa,现在过来两个月公安局打电话叫我过去...

咨询我帮助人数:36021721.公安局打电话来的原因比较多,具体需要根据电话的内容进行分析。而且公安局的范围比较大,涉及到的部门比较多,每个部门负责处理各自的工作问题,有民事的,也有刑事的。有派出所的&am…

centos7 iptables 端口转发 保存_iptables 防火墙

目录:yum 在线安装yum卸载安装包rpm 卸载yum安装rpm离线安装利用 Downloadonly 插件下载 RPM 软件包及其所有依赖包使用 Yumdownloader 工具来下载 RPM 软件包及其所有依赖包yum 在线安装CentOS7默认的防火墙不是iptables,而是firewalle.yum卸载安装包yum remove to…

日本惊现神操作!偷偷研究飞刀方程致使厕所爆炸......

欢快如厕为何大声惨叫前几天,竟然有模友私信超模君,说这是不是真的。网友私信截图WTF!数学史上就有一道“奇葩的”难题,是历代数学家们在厕所里解决的。厕所冥想1917年,为了给日本武士增添生活趣味,数学家挂…

抓取手机https_python爬虫入门02:教你通过 Fiddler 进行手机抓包

哟~哟~哟~hi起来everybody今天要说说怎么在我们的手机抓包通过python爬虫入门01:教你在 Chrome 浏览器轻松抓包我们知道了 HTTP 的请求方式以及在 Chrome 中摸清了一些套路但是除了对数据进行解析之外有时候我们想对请求的数据或者响应的数据进行篡改怎么做呢&#…

BeetleX进程服务管理组件应用

有些时候需要在程序中启动和管理其他应用进程,当碰到这样的需求的时候可以通过Process对象来完成;为了让使用和管理更方便在这基础上封装 了BeetleX.ServicesProcess组件,通过组件的管理中心让进程操作更方便,同时还集成了Web套件…

升级总代分享思路_桃生企业至尊七郎瓷砖新展厅全新升级惊艳亮相

桃生企业至尊七郎瓷砖新展厅惊艳亮相,将艺术和时尚完美融合,即将成为晋江天工建材城的新地标!2020年桃生企业逆流升级进行中,全新展厅即将揭幕!全新空间 对话年轻轻奢于行,优雅于里,全新一楼的…

烧脑又过瘾!关于c²= b² + a²,你不知道的N个事实

全世界只有3.14 % 的人关注了爆炸吧知识勾股定理你真的懂吗一般人看来,勾股定理只存在于特定的三角形或几何图形中。但实际上,绝大多数人都小看了这条有2600年历史的公式,很多看似不可能的图形,只要涉及到了平方数,勾股…

[snmp++]读取cisco路由交换机信息[一] - 环境搭建

首先从网上下载gn3这个摸拟器以及cisco路由器的bin. 如图,下面的clouds里添加本地连接,这样表示路由器与本机的网卡桥接。即在R2里的接口设置一个与本机的IP地址同一网段。这样局域网的机就可以与R2通信 R2的配置如下 snmp-server community public RO 读…

Dapr + .NET 实战(六)绑定

什么是绑定处理外部事件或调用外部接口的功能就是绑定,绑定可以提供以下好处:避免连接到消息系统 ( 如队列和消息总线 ) 并进行轮询的复杂性聚焦于业务逻辑,而不是如何与系统交互使代码不受 SDK 或外部库的强耦合处理重试和故障恢复Dapr提供了…

对象中multipartfile 空报错_Python 为什么会有个奇怪的“...”对象?

我想到一种特别的写法,很多人会把它当成 pass 语句的替代。在文章发布后,果然有三条留言提及了它。所谓特别的写法就是下面这个:# 用 ... 替代 passdef foo():...它是中文标点符号的半个省略号,也即由英文的 3 个点组成。如果你是…

XP硬盘安装Fedora14图文教程

XP硬盘安装Fedora14图文教程发表于:2010年11月03日 分类:Fedora 26 条评论 5,044 次阅读 昨天是Fedora 14的发布,这篇文章介绍的是如何在windows XP下硬盘安装Fedora 14。 之前写过2篇文章: Linux下硬盘安装Fedora 13:…

用wamper打开php源码_php源码该怎么设置数据库

php源码该怎么设置数据库php源码修改数据库的设置方法:首先在源码中找到程序的配置文件;然后用文本编辑器打开;之后修改数据库地址、数据库名、用户名、连接密码、数据库前缀等参数;最后保存即可。这里以织梦程序为例,…

豆瓣评分9.0+,这几部纪录片看一部少一部!

纪录片是以真实生活为创作素材,以真人真事为表现对象,并对其进行艺术的加工与展现的,以展现真实为本质,并用真实引发人们思考的电影或电视艺术形式。好的纪录片就像打开了一扇新世界的大门,让我们了解更多世界的奇妙之…

记一次 .NET 某纺织工厂 MES系统 API 挂死分析

一:背景 1. 讲故事这个月中旬,有位朋友加我wx求助他的程序线程占有率很高,寻求如何解决,截图如下:说实话,和不同行业的程序员聊天还是蛮有意思的,广交朋友,也能扩大自己的圈子&#…

python求斜边上的高_直角三角形斜边上的高怎么求

展开全部 直角三角形斜边32313133353236313431303231363533e78988e69d8331333431336666上的高的求法: 1. 直角三角形斜边上的高等于两条直角边的乘积除以斜边的商。 例如:直角三角形的两个直角边分别为a和b,斜边为c,那么&#xff…

使用identity+jwt保护你的webapi(一)——identity基础配置

前言用户模块几乎是每个系统必备的基础功能,如果每次开发一个新项目时都要做个用户模块,确实非常无聊。好在asp.net core给我们提供了Identity,使用起来也是比较方便,如果对用户这块需求不是非常个性化的话,identity是…

年轻人不能“饥渴”太久,否则……

全世界只有3.14 % 的人关注了爆炸吧知识文 / 较高端人类来源 / 较高端人类(ID:xinji656)转发到朋友圈健康生活从饮水做起本文来源于微信公众号:较高端人类(ID:xinji656)我们只研究那些你感兴趣的…

Redis集群(一):集群搭建

2019独角兽企业重金招聘Python工程师标准>>> 概述 这里只记录操作步骤和集群测试,保证快速搭建集群环境。具体原理请查阅官方文档(中文版): http://www.redis.cn/topics/cluster-spec.html 集群容灾:Redis集…

python优惠券机器人_python实现机器人卡牌

介绍 这个例子主要利用turtle库实现根据输入动态展示不同机器人的图像和属性信息。 代码部分非原创只是做了些许修改和整理使得更易阅读。 图片和文件资源请访问git仓库获取:链接地址 涉及以下知识点: 1.文件读取 2.字典 3.turtle库的使用 4.控制语句 实…