android.graphics包中的一些类的使用

    xiaoxiao2021-03-26  30

    转自:http://yuanzhifei89.iteye.com/blog/1136651

    游戏编程相关参考 

    Matrix学习系列:  http://www.moandroid.com/?p=1781   Android画图学习总结系列:  http://www.moandroid.com/?p=764   游戏开发系列(opengl es基础知识):  http://www.moandroid.com/?p=1730   线性代数(包含矩阵的相关知识):  http://dl.iteye.com/topics/download/b56a388a-3408-3179-972b-3a72bdbaaa28   俄罗斯方块的实现(c# silverlignth实现):  http://www.cnblogs.com/crazy-dave/archive/2011/05/20/Silverlight_Tetris1.html   SurfaceView使用的参考:  http://kb.cnblogs.com/page/80095/   http://blog.csdn.net/hellogv/article/details/5986835   http://www.cnblogs.com/xuling/archive/2011/06/06/android.html   2d游戏编程学习   从俄罗斯方块开始:  还待完善的地方:  1. 仅在320x480的屏幕上画面正常,还没有去兼容多屏幕  2. 使用View进行绘制了,应该使用SurfaceView来绘制  3. 功能还比较简陋,仅实现了主要内容  4. 移动时会出现跳帧现象,主要是重绘是由view自己执行的,而没有在onKey中移动了就重绘,这样就可能导致移了两下而只绘了一次,就出现跳帧了  ...  源码(俄罗斯方块的代码在game.tetris包下,其它包的内容都是学习的测试代码): http://dl.iteye.com/topics/download/4f8ef46f-e5fb-3724-9561-480179a8651c   Region:表示一块区域   和Rect不同的是,它表示的是一个不规则的样子,可以是椭圆、多边形等等,而Rect仅仅是矩形。  Java代码   Region region = new Region();   region.isEmpty();      // width: 100, height: 50的矩形   region.set(100100200150);   Rect bounds = region.getBounds();      // 矩形区域是否在其内部   boolean contains = region.quickContains(120120170150);      // 矩形区域是否不在其内部   boolean reject = region.quickReject(005050);      // INTERSECT 取两者交集   Region r2 = new Region(region);   r2.op(00150120, Region.Op.INTERSECT);      // DIFFERENCE 第一次不同于第二次的部分显示出来   r2 = new Region(region);   r2.op(00150120, Region.Op.DIFFERENCE);      // REPLACE 显示第二次的   r2 = new Region(region);   r2.op(00150120, Region.Op.REPLACE);      // REVERSE_DIFFERENCE 第二次不同于第一次的部分显示   r2 = new Region(region);   r2.op(00150120, Region.Op.REVERSE_DIFFERENCE);      // UNION 取全集   r2 = new Region(region);   r2.op(00150120, Region.Op.UNION);      // XOR 补集,就是全集的减去交集的剩余部分显示   r2 = new Region(region);   r2.op(00150120, Region.Op.XOR);   示意图   Path   path可以看作是一个点集,将它内部的点集按顺序连接起来时可以组成任意边型。一般多边形就是用Path来画。  Java代码   // 公共代码   Path pathToDraw = new Path();   // 移到某点处作为起点   pathToDraw.moveTo(5050);   pathToDraw.lineTo(10050);   pathToDraw.lineTo(150100);   pathToDraw.lineTo(50100);      // 多边形   pathToDraw.lineTo(10075);   pathToDraw.close();      // 不闭合,逆时针   pathToDraw.addCircle(5010030, Path.Direction.CCW);   // 不闭合,顺时针   pathToDraw.addCircle(5010030, Path.Direction.CW);   // 闭合,逆时针   pathToDraw.addCircle(5010030, Path.Direction.CCW);   pathToDraw.close();   // 闭合,逆时针   pathToDraw.addCircle(5010030, Path.Direction.CW);   pathToDraw.close();   // 上面四个画出来是一样的      // 添加弧线,弧线是由矩形来控制的,正方形时是圆弧,矩形时就是椭圆弧了   pathToDraw.addArc(new RectF(257555155), 0270);      // 在最后一个点处添加弧线,如果rectf中指定的点与最后一个点不同,则首先会将其先lineTo最后一个点(图中可以看到,与上面的代码所画的图的区别就是多了个连接线段)   pathToDraw.arcTo(new RectF(257555155), 0270);      // 添加二次曲线,两个控制点(25, 125), (75, 175)   pathToDraw.cubicTo(251257517530200);      // 添加三次曲线,三个控制点(25, 125), (75, 175), (30, 200)   pathToDraw.cubicTo(251257517530200);   Path.FillType路劲的填充类型还不是很理解,主要是文档没有对其做任何解释,api demo只有代码,也不懂啥意思。网上找了也没有解释的很清楚的。可以看下这个连接: http://www.imobilebbs.com/wordpress/?p=1589   Bitmap   Bitmap的density参数的使用  Java代码   // 将完整的图片绘制到(0, 0)处   canvas.drawBitmap(mBmp, 00null);      // 240(hdpi)的图片放到160上时,就会变小1.5倍   mBmp.setDensity(240);   // 将完整的图片绘制到(100, 0)处   canvas.drawBitmap(mBmp, 1000null);      // 将完整的源图片绘制到起点为(0, 100),宽100、高100的矩形范围内   canvas.drawBitmap(mBmp, nullnew Rect(0100100200), null);      // 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(100, 100)宽100, 高50的矩形范围内   canvas.drawBitmap(mBmp, new Rect(0010050), new Rect(100100200150), null);      // 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(200, 100)宽50, 25的矩形范围内   canvas.drawBitmap(mBmp, new Rect(0010050), new Rect(200100250125), null);   效果:    最终得出的结论:bitmap.setDensity并不影响源图片,只是在绘制的时候,canvas会根据该density对图片进行缩放绘制。  Paint介绍   Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色,  样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,  大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。  Text代码       1.图形绘制    setARGB(int a,int r,int g,int b);    设置绘制的颜色,a代表透明度,r,g,b代表颜色值。        setAlpha(int a);    设置绘制图形的透明度。        setColor(int color);    设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。        setAntiAlias(boolean aa);    设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。        setDither(boolean dither);    设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰        setFilterBitmap(boolean filter);    如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示    速度,本设置项依赖于dither和xfermode的设置        setMaskFilter(MaskFilter maskfilter);    设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等        setColorFilter(ColorFilter colorfilter);    设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果        setPathEffect(PathEffect effect);    设置绘制路径的效果,如点画线等        setShader(Shader shader);    设置图像效果,使用Shader可以绘制出各种渐变效果        setShadowLayer(float radius ,float dx,float dy,int color);    在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色        setStyle(Paint.Style style);    设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE        setStrokeCap(Paint.Cap cap);    当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式    Cap.ROUND,或方形样式Cap.SQUARE        setSrokeJoin(Paint.Join join);    设置绘制时各图形的结合方式,如平滑效果等        setStrokeWidth(float width);    当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度        setXfermode(Xfermode xfermode);    设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果        2.文本绘制    setFakeBoldText(boolean fakeBoldText);    模拟实现粗体文字,设置在小字体上效果会非常差        setSubpixelText(boolean subpixelText);    设置该项为true,将有助于文本在LCD屏幕上的显示效果        setTextAlign(Paint.Align align);    设置绘制文字的对齐方向        setTextScaleX(float scaleX);    设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果        setTextSize(float textSize);    设置绘制文字的字号大小        setTextSkewX(float skewX);    设置斜体文字,skewX为倾斜弧度        setTypeface(Typeface typeface);    设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等        setUnderlineText(boolean underlineText);    设置带有下划线的文字效果        setStrikeThruText(boolean strikeThruText);    设置带有删除线的效果    Paint类涉及的几个枚举:(从msdn抄过来的,msdn的文档果然比android文档详细n倍:http://msdn.microsoft.com/en-us/library/cc294944.aspx)  Paint.Cap 如何结束笔触的枚举  Paint.Join path的拐角处如何绘制  Canvas的基本使用   抗锯齿相关参考: http://www.iteye.com/topic/794505   填充颜色,一般清屏时会用这里的方法  Java代码   switch (keyUpCount) {   case 0:       canvas.drawARGB(10025500);       break;      case 1:       canvas.drawColor(Color.argb(10002550));       break;      case 2:       // 指定PorterDuff mode方式绘制颜色       canvas.drawColor(Color.argb(10000255), Mode.SRC);       break;          case 3:       // paint方式的绘制颜色       Paint paint = new Paint();       paint.setARGB(1000xEE0xEE0xEE);       canvas.drawPaint(paint);       break;   }   绘制Bitmap  Java代码   switch (keyUpCount) {   case 0// 在(x, y)除绘制bitmap       canvas.drawBitmap(chameleonBmp, 2020null);       break;          case 1// 利用变换矩阵绘制bimap       Matrix matrix = new Matrix();       matrix.setRotate(10);       matrix.preTranslate(5050);       canvas.drawBitmap(chameleonBmp, matrix, null);       break;          case 2:       // 将图片的(0, 0, 100, 184)区域拉伸或缩放到canvas的       // (50, 50, 250, 418)区域进行绘制       Rect src = new Rect();       src.set(00100184);       Rect dst = new Rect();       dst.set(5050250418);       canvas.drawBitmap(chameleonBmp, src, dst, null);       // canvas.drawBitmap(Bitmap, Rect, RectF, Paint); 与上面类似       // 就是RectF是Rect的float版本       break;          case 3:       // 自己构建bitmap的每个像素点,并将其绘制到canvas上       // 也就是说200x200的bitmap,需要自己构建40000个像素点       int[] bmpPixels = new int[] {               Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,               Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,               Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,                  Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,               Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,               Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,                  Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE,               Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE,               Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE       };       canvas.drawBitmap(bmpPixels, 0152020153falsenull);       break;   }   绘制基本的几何图形(绘制几何图形时,必须使用画笔paint)  Java代码   Paint paint = new Paint();   paint.setColor(Color.RED); // 画笔颜色   paint.setAntiAlias(true); // 反锯齿   paint.setStyle(Paint.Style.STROKE); // 笔触绘制   paint.setStrokeWidth(3); // 笔触宽度      switch (keyUpCount) {   case 0// 点       for (int i = 1; i <= 10; i++) {           canvas.drawPoint(i * 1020, paint);       }       break;          case 1// 直线       for (int i = 1; i < 10; i++) {           canvas.drawLine(10, i * 10200, i * 10, paint);       }       break;          case 2// 圆       canvas.drawCircle(10010090, paint);       break;          case 3// 弧线和矩形       RectF outRect = new RectF(1010110110);       canvas.drawRect(outRect, paint);       float startAngle = 70;       float sweepAngle = 180;       canvas.drawArc(outRect, startAngle, sweepAngle, false, paint);       break;          case 4// 椭圆       canvas.drawOval(new RectF(101011060), paint);       break;          case 5// 路径(任意边型)       Path path = new Path();       path.moveTo(1010);       path.lineTo(20010);       path.lineTo(14060);       path.lineTo(12030);       canvas.drawPath(path, paint);       break;          case 6// 圆角矩形       RectF rect = new RectF(1010100100);       canvas.drawRoundRect(rect, 2040, paint);       break;   }   canvas的一些效果   翻转效果,这样在使用图片时,左和右的图片就可以重用了。  Java代码   Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.image830);      canvas.drawColor(Color.WHITE);   canvas.drawBitmap(bmp, 100160null);   // 水平翻转   canvas.save();   canvas.scale(-11240160);   canvas.drawBitmap(bmp, 240160null);   canvas.restore();      // 垂直翻转   canvas.save();   canvas.scale(1, -1300160);   canvas.drawBitmap(bmp, 300160null);   canvas.restore();     绘制文本   Paint.Align 文本如何对其(x, y)绘制    第一个是(x, y)位于文本左侧;第二个是(x, y)位于文本中间的;第三个是(x, y)位于文本的右侧。但他们都是canvas.drawText("...", x, y, paint); 仅仅是paint设置的不同了哦。  Paint.FontMetrics:字体元数据  下图是对该部分涉及的排版术语的图形描述:    Paint.FontMetrics.top:某种字体中,基线以上的最大距离(就是ascent的最大值)  Paint.FontMetrics.bottom:某种字体中,基线以下的最大距离(就是descent的最小值)  Java代码   Paint paint = new Paint();   paint.setColor(Color.RED); // 画笔颜色   paint.setAntiAlias(true); // 抗锯齿   paint.setStyle(Style.STROKE); // 笔触绘制   paint.setTextSize(30); // 字体大小      switch (keyUpCount) {   case 0// 下划线文本       Paint paint0 = new Paint(paint);       paint0.setUnderlineText(true);       canvas.drawText("underline text"1050, paint0);       break;          case 1// x方向倾斜文本       Paint paint1 = new Paint(paint);       paint1.setTextSkewX(-0.3F);       char[] chars = "text skew x".toCharArray();       canvas.drawText(chars, 0, chars.length, 1050, paint1);       break;          case 2// 缩放文本       Paint paint2 = new Paint(paint);       paint2.setTextScaleX(3.0F);       paint2.setTextSize(15);       canvas.drawText("text scale x"0121050, paint2);       break;          case 3// 使用自定义字体的文本       Paint paint3 = new Paint(paint);       paint3.setTextSize(45);       paint3.setColor(Color.BLUE);       Typeface shift = Typeface.createFromAsset(getAssets(), "fonts/Shift.ttf");       paint3.setTypeface(shift);       canvas.drawText("Shift.ttf"091050, paint3);              /* font attributes      Paint.FontMetrics fontMetrics = paint3.getFontMetrics();      fontMetrics.ascent;      paint3.ascent();      fontMetrics.descent;      paint3.descent();      fontMetrics.leading;      fontMetrics.top;      fontMetrics.bottom;      */       break;          case 4// 路径文本       String text = "abcdefghijklmnOPQRST12345";       Paint paint4 = new Paint();       paint4.setColor(Color.BLUE);       paint4.setStyle(Style.STROKE);       // draw path       Path path = new Path();       path.moveTo(10100);       path.cubicTo(1102002100310100);       canvas.drawPath(path, paint4);       // draw text       paint.setTextSize(20);       canvas.drawTextOnPath(text, path, 20.0F, 5.0F, paint);       break;   canvas变换,save, restore, layer的使用   layer其实就相当于photoshop中图层的概念,对当前图层的操作是不影响其它图层的。  Java代码   Paint paint = new Paint();   paint.setColor(Color.RED);   paint.setAntiAlias(true);   paint.setStyle(Paint.Style.STROKE);   paint.setStrokeWidth(3);      switch (keyUpCount) {   case 0// rotate旋转       canvas.rotate(20);       canvas.drawRect(1010300210, paint);       break;          case 1// translate移动       canvas.translate(1000);       canvas.drawRect(1010300210, paint);       break;          case 2// skew倾斜       canvas.skew(0.2F, 0);       canvas.drawRect(1010300210, paint);       break;          case 3// 缩放       canvas.scale(0.5F, 1);       canvas.drawRect(1010300210, paint);       break;          case 4// 没用save, restore       canvas.rotate(20);       canvas.drawRect(10106060, paint);       canvas.translate(500);       canvas.drawRect(10107070, paint);       break;          case 5// 用了save, restore       int saveCount = canvas.save();       // 将画布旋转20度,然后后面的绘制也都是旋转20度的       canvas.rotate(20);       canvas.drawRect(10106060, paint);       // 将canvas还原到没rotate前       canvas.restoreToCount(saveCount);       canvas.translate(500);       canvas.drawRect(10107070, paint);       break;          case 6// 没使用图层       paint.setStyle(Paint.Style.FILL);       paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));       canvas.drawRect(00100100, paint);       canvas.drawRect(100100200200, paint);       paint.setColor(Color.BLUE);       canvas.drawRect(5050150150, paint);       break;          case 7// 使用了图层layer       paint.setStyle(Paint.Style.FILL);       paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));       canvas.drawRect(00100100, paint);       // 创建一个图层       int layerSC = canvas.saveLayer(nullnull,               Canvas.MATRIX_SAVE_FLAG | // 合并图层时,restore应用于图层的变换               Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |               Canvas.FULL_COLOR_LAYER_SAVE_FLAG);       canvas.translate(100100);       canvas.drawRect(00100100, paint);       paint.setColor(Color.BLUE);       canvas.translate(-50, -50);       canvas.drawRect(00100100, paint);       canvas.restoreToCount(layerSC); // 合并图层       break;  
    转载请注明原文地址: https://ju.6miu.com/read-658433.html

    最新回复(0)