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

来源:互联网 发布:淘宝模板自己怎么设计 编辑:程序博客网 时间:2024/06/06 02:03

转自: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代码  收藏代码
  1. Region region = new Region();  
  2. region.isEmpty();  
  3.   
  4. // width: 100, height: 50的矩形  
  5. region.set(100100200150);  
  6. Rect bounds = region.getBounds();  
  7.   
  8. // 矩形区域是否在其内部  
  9. boolean contains = region.quickContains(120120170150);  
  10.   
  11. // 矩形区域是否不在其内部  
  12. boolean reject = region.quickReject(005050);  
  13.   
  14. // INTERSECT 取两者交集  
  15. Region r2 = new Region(region);  
  16. r2.op(00150120, Region.Op.INTERSECT);  
  17.   
  18. // DIFFERENCE 第一次不同于第二次的部分显示出来  
  19. r2 = new Region(region);  
  20. r2.op(00150120, Region.Op.DIFFERENCE);  
  21.   
  22. // REPLACE 显示第二次的  
  23. r2 = new Region(region);  
  24. r2.op(00150120, Region.Op.REPLACE);  
  25.   
  26. // REVERSE_DIFFERENCE 第二次不同于第一次的部分显示  
  27. r2 = new Region(region);  
  28. r2.op(00150120, Region.Op.REVERSE_DIFFERENCE);  
  29.   
  30. // UNION 取全集  
  31. r2 = new Region(region);  
  32. r2.op(00150120, Region.Op.UNION);  
  33.   
  34. // XOR 补集,就是全集的减去交集的剩余部分显示  
  35. r2 = new Region(region);  
  36. r2.op(00150120, Region.Op.XOR);  

示意图 



Path 
path可以看作是一个点集,将它内部的点集按顺序连接起来时可以组成任意边型。一般多边形就是用Path来画。 
Java代码  收藏代码
  1. // 公共代码  
  2. Path pathToDraw = new Path();  
  3. // 移到某点处作为起点  
  4. pathToDraw.moveTo(5050);  
  5. pathToDraw.lineTo(10050);  
  6. pathToDraw.lineTo(150100);  
  7. pathToDraw.lineTo(50100);  
  8.   
  9. // 多边形  
  10. pathToDraw.lineTo(10075);  
  11. pathToDraw.close();  
  12.   
  13. // 不闭合,逆时针  
  14. pathToDraw.addCircle(5010030, Path.Direction.CCW);  
  15. // 不闭合,顺时针  
  16. pathToDraw.addCircle(5010030, Path.Direction.CW);  
  17. // 闭合,逆时针  
  18. pathToDraw.addCircle(5010030, Path.Direction.CCW);  
  19. pathToDraw.close();  
  20. // 闭合,逆时针  
  21. pathToDraw.addCircle(5010030, Path.Direction.CW);  
  22. pathToDraw.close();  
  23. // 上面四个画出来是一样的  
  24.   
  25. // 添加弧线,弧线是由矩形来控制的,正方形时是圆弧,矩形时就是椭圆弧了  
  26. pathToDraw.addArc(new RectF(257555155), 0270);  
  27.   
  28. // 在最后一个点处添加弧线,如果rectf中指定的点与最后一个点不同,则首先会将其先lineTo最后一个点(图中可以看到,与上面的代码所画的图的区别就是多了个连接线段)  
  29. pathToDraw.arcTo(new RectF(257555155), 0270);  
  30.   
  31. // 添加二次曲线,两个控制点(25, 125), (75, 175)  
  32. pathToDraw.cubicTo(251257517530200);  
  33.   
  34. // 添加三次曲线,三个控制点(25, 125), (75, 175), (30, 200)  
  35. pathToDraw.cubicTo(251257517530200);  

Path.FillType路劲的填充类型还不是很理解,主要是文档没有对其做任何解释,api demo只有代码,也不懂啥意思。网上找了也没有解释的很清楚的。可以看下这个连接:http://www.imobilebbs.com/wordpress/?p=1589 



Bitmap 
Bitmap的density参数的使用 
Java代码  收藏代码
  1. // 将完整的图片绘制到(0, 0)处  
  2. canvas.drawBitmap(mBmp, 00null);  
  3.   
  4. // 240(hdpi)的图片放到160上时,就会变小1.5倍  
  5. mBmp.setDensity(240);  
  6. // 将完整的图片绘制到(100, 0)处  
  7. canvas.drawBitmap(mBmp, 1000null);  
  8.   
  9. // 将完整的源图片绘制到起点为(0, 100),宽100、高100的矩形范围内  
  10. canvas.drawBitmap(mBmp, nullnew Rect(0100100200), null);  
  11.   
  12. // 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(100, 100)宽100, 高50的矩形范围内  
  13. canvas.drawBitmap(mBmp, new Rect(0010050), new Rect(100100200150), null);  
  14.   
  15. // 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(200, 100)宽50, 25的矩形范围内  
  16. canvas.drawBitmap(mBmp, new Rect(0010050), new Rect(200100250125), null);  

效果: 
 
最终得出的结论:bitmap.setDensity并不影响源图片,只是在绘制的时候,canvas会根据该density对图片进行缩放绘制。 


Paint介绍 
Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, 
样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法, 
大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。 
Text代码  收藏代码
  1.    
  2. 1.图形绘制   
  3. setARGB(int a,int r,int g,int b);   
  4. 设置绘制的颜色,a代表透明度,r,g,b代表颜色值。   
  5.    
  6. setAlpha(int a);   
  7. 设置绘制图形的透明度。   
  8.    
  9. setColor(int color);   
  10. 设置绘制的颜色,使用颜色值来表示,该颜色值包括透明度和RGB颜色。   
  11.    
  12. setAntiAlias(boolean aa);   
  13. 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。   
  14.    
  15. setDither(boolean dither);   
  16. 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰   
  17.    
  18. setFilterBitmap(boolean filter);   
  19. 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加快显示   
  20. 速度,本设置项依赖于dither和xfermode的设置   
  21.    
  22. setMaskFilter(MaskFilter maskfilter);   
  23. 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等   
  24.    
  25. setColorFilter(ColorFilter colorfilter);   
  26. 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果   
  27.    
  28. setPathEffect(PathEffect effect);   
  29. 设置绘制路径的效果,如点画线等   
  30.    
  31. setShader(Shader shader);   
  32. 设置图像效果,使用Shader可以绘制出各种渐变效果   
  33.    
  34. setShadowLayer(float radius ,float dx,float dy,int color);   
  35. 在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色   
  36.    
  37. setStyle(Paint.Style style);   
  38. 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE   
  39.    
  40. setStrokeCap(Paint.Cap cap);   
  41. 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式   
  42. Cap.ROUND,或方形样式Cap.SQUARE   
  43.    
  44. setSrokeJoin(Paint.Join join);   
  45. 设置绘制时各图形的结合方式,如平滑效果等   
  46.    
  47. setStrokeWidth(float width);   
  48. 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度   
  49.    
  50. setXfermode(Xfermode xfermode);   
  51. 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果   
  52.    
  53. 2.文本绘制   
  54. setFakeBoldText(boolean fakeBoldText);   
  55. 模拟实现粗体文字,设置在小字体上效果会非常差   
  56.    
  57. setSubpixelText(boolean subpixelText);   
  58. 设置该项为true,将有助于文本在LCD屏幕上的显示效果   
  59.    
  60. setTextAlign(Paint.Align align);   
  61. 设置绘制文字的对齐方向   
  62.    
  63. setTextScaleX(float scaleX);   
  64. 设置绘制文字x轴的缩放比例,可以实现文字的拉伸的效果   
  65.    
  66. setTextSize(float textSize);   
  67. 设置绘制文字的字号大小   
  68.    
  69. setTextSkewX(float skewX);   
  70. 设置斜体文字,skewX为倾斜弧度   
  71.    
  72. setTypeface(Typeface typeface);   
  73. 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等   
  74.    
  75. setUnderlineText(boolean underlineText);   
  76. 设置带有下划线的文字效果   
  77.    
  78. setStrikeThruText(boolean strikeThruText);   
  79. 设置带有删除线的效果   


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代码  收藏代码
  1. switch (keyUpCount) {  
  2. case 0:  
  3.     canvas.drawARGB(10025500);  
  4.     break;  
  5.   
  6. case 1:  
  7.     canvas.drawColor(Color.argb(10002550));  
  8.     break;  
  9.   
  10. case 2:  
  11.     // 指定PorterDuff mode方式绘制颜色  
  12.     canvas.drawColor(Color.argb(10000255), Mode.SRC);  
  13.     break;  
  14.       
  15. case 3:  
  16.     // paint方式的绘制颜色  
  17.     Paint paint = new Paint();  
  18.     paint.setARGB(1000xEE0xEE0xEE);  
  19.     canvas.drawPaint(paint);  
  20.     break;  
  21. }  



绘制Bitmap 
Java代码  收藏代码
  1. switch (keyUpCount) {  
  2. case 0// 在(x, y)除绘制bitmap  
  3.     canvas.drawBitmap(chameleonBmp, 2020null);  
  4.     break;  
  5.       
  6. case 1// 利用变换矩阵绘制bimap  
  7.     Matrix matrix = new Matrix();  
  8.     matrix.setRotate(10);  
  9.     matrix.preTranslate(5050);  
  10.     canvas.drawBitmap(chameleonBmp, matrix, null);  
  11.     break;  
  12.       
  13. case 2:  
  14.     // 将图片的(0, 0, 100, 184)区域拉伸或缩放到canvas的  
  15.     // (50, 50, 250, 418)区域进行绘制  
  16.     Rect src = new Rect();  
  17.     src.set(00100184);  
  18.     Rect dst = new Rect();  
  19.     dst.set(5050250418);  
  20.     canvas.drawBitmap(chameleonBmp, src, dst, null);  
  21.     // canvas.drawBitmap(Bitmap, Rect, RectF, Paint); 与上面类似  
  22.     // 就是RectF是Rect的float版本  
  23.     break;  
  24.       
  25. case 3:  
  26.     // 自己构建bitmap的每个像素点,并将其绘制到canvas上  
  27.     // 也就是说200x200的bitmap,需要自己构建40000个像素点  
  28.     int[] bmpPixels = new int[] {  
  29.             Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,  
  30.             Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,  
  31.             Color.RED, Color.RED, Color.RED, Color.RED, Color.RED,  
  32.   
  33.             Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,  
  34.             Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,  
  35.             Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN, Color.GREEN,  
  36.   
  37.             Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE,  
  38.             Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE,  
  39.             Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE  
  40.     };  
  41.     canvas.drawBitmap(bmpPixels, 0152020153falsenull);  
  42.     break;  
  43. }  



绘制基本的几何图形(绘制几何图形时,必须使用画笔paint) 
Java代码  收藏代码
  1. Paint paint = new Paint();  
  2. paint.setColor(Color.RED); // 画笔颜色  
  3. paint.setAntiAlias(true); // 反锯齿  
  4. paint.setStyle(Paint.Style.STROKE); // 笔触绘制  
  5. paint.setStrokeWidth(3); // 笔触宽度  
  6.   
  7. switch (keyUpCount) {  
  8. case 0// 点  
  9.     for (int i = 1; i <= 10; i++) {  
  10.         canvas.drawPoint(i * 1020, paint);  
  11.     }  
  12.     break;  
  13.       
  14. case 1// 直线  
  15.     for (int i = 1; i < 10; i++) {  
  16.         canvas.drawLine(10, i * 10200, i * 10, paint);  
  17.     }  
  18.     break;  
  19.       
  20. case 2// 圆  
  21.     canvas.drawCircle(10010090, paint);  
  22.     break;  
  23.       
  24. case 3// 弧线和矩形  
  25.     RectF outRect = new RectF(1010110110);  
  26.     canvas.drawRect(outRect, paint);  
  27.     float startAngle = 70;  
  28.     float sweepAngle = 180;  
  29.     canvas.drawArc(outRect, startAngle, sweepAngle, false, paint);  
  30.     break;  
  31.       
  32. case 4// 椭圆  
  33.     canvas.drawOval(new RectF(101011060), paint);  
  34.     break;  
  35.       
  36. case 5// 路径(任意边型)  
  37.     Path path = new Path();  
  38.     path.moveTo(1010);  
  39.     path.lineTo(20010);  
  40.     path.lineTo(14060);  
  41.     path.lineTo(12030);  
  42.     canvas.drawPath(path, paint);  
  43.     break;  
  44.       
  45. case 6// 圆角矩形  
  46.     RectF rect = new RectF(1010100100);  
  47.     canvas.drawRoundRect(rect, 2040, paint);  
  48.     break;  
  49. }  




canvas的一些效果 
翻转效果,这样在使用图片时,左和右的图片就可以重用了。 
Java代码  收藏代码
  1. Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.image830);  
  2.   
  3. canvas.drawColor(Color.WHITE);  
  4. canvas.drawBitmap(bmp, 100160null);  
  5. // 水平翻转  
  6. canvas.save();  
  7. canvas.scale(-11240160);  
  8. canvas.drawBitmap(bmp, 240160null);  
  9. canvas.restore();  
  10.   
  11. // 垂直翻转  
  12. canvas.save();  
  13. canvas.scale(1, -1300160);  
  14. canvas.drawBitmap(bmp, 300160null);  
  15. 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代码  收藏代码
  1. Paint paint = new Paint();  
  2. paint.setColor(Color.RED); // 画笔颜色  
  3. paint.setAntiAlias(true); // 抗锯齿  
  4. paint.setStyle(Style.STROKE); // 笔触绘制  
  5. paint.setTextSize(30); // 字体大小  
  6.   
  7. switch (keyUpCount) {  
  8. case 0// 下划线文本  
  9.     Paint paint0 = new Paint(paint);  
  10.     paint0.setUnderlineText(true);  
  11.     canvas.drawText("underline text"1050, paint0);  
  12.     break;  
  13.       
  14. case 1// x方向倾斜文本  
  15.     Paint paint1 = new Paint(paint);  
  16.     paint1.setTextSkewX(-0.3F);  
  17.     char[] chars = "text skew x".toCharArray();  
  18.     canvas.drawText(chars, 0, chars.length, 1050, paint1);  
  19.     break;  
  20.       
  21. case 2// 缩放文本  
  22.     Paint paint2 = new Paint(paint);  
  23.     paint2.setTextScaleX(3.0F);  
  24.     paint2.setTextSize(15);  
  25.     canvas.drawText("text scale x"0121050, paint2);  
  26.     break;  
  27.       
  28. case 3// 使用自定义字体的文本  
  29.     Paint paint3 = new Paint(paint);  
  30.     paint3.setTextSize(45);  
  31.     paint3.setColor(Color.BLUE);  
  32.     Typeface shift = Typeface.createFromAsset(getAssets(), "fonts/Shift.ttf");  
  33.     paint3.setTypeface(shift);  
  34.     canvas.drawText("Shift.ttf"091050, paint3);  
  35.       
  36.     /* font attributes 
  37.     Paint.FontMetrics fontMetrics = paint3.getFontMetrics(); 
  38.     fontMetrics.ascent; 
  39.     paint3.ascent(); 
  40.     fontMetrics.descent; 
  41.     paint3.descent(); 
  42.     fontMetrics.leading; 
  43.     fontMetrics.top; 
  44.     fontMetrics.bottom; 
  45.     */  
  46.     break;  
  47.       
  48. case 4// 路径文本  
  49.     String text = "abcdefghijklmnOPQRST12345";  
  50.     Paint paint4 = new Paint();  
  51.     paint4.setColor(Color.BLUE);  
  52.     paint4.setStyle(Style.STROKE);  
  53.     // draw path  
  54.     Path path = new Path();  
  55.     path.moveTo(10100);  
  56.     path.cubicTo(1102002100310100);  
  57.     canvas.drawPath(path, paint4);  
  58.     // draw text  
  59.     paint.setTextSize(20);  
  60.     canvas.drawTextOnPath(text, path, 20.0F, 5.0F, paint);  
  61.     break;  




canvas变换,save, restore, layer的使用 
layer其实就相当于photoshop中图层的概念,对当前图层的操作是不影响其它图层的。 
Java代码  收藏代码
  1. Paint paint = new Paint();  
  2. paint.setColor(Color.RED);  
  3. paint.setAntiAlias(true);  
  4. paint.setStyle(Paint.Style.STROKE);  
  5. paint.setStrokeWidth(3);  
  6.   
  7. switch (keyUpCount) {  
  8. case 0// rotate旋转  
  9.     canvas.rotate(20);  
  10.     canvas.drawRect(1010300210, paint);  
  11.     break;  
  12.       
  13. case 1// translate移动  
  14.     canvas.translate(1000);  
  15.     canvas.drawRect(1010300210, paint);  
  16.     break;  
  17.       
  18. case 2// skew倾斜  
  19.     canvas.skew(0.2F, 0);  
  20.     canvas.drawRect(1010300210, paint);  
  21.     break;  
  22.       
  23. case 3// 缩放  
  24.     canvas.scale(0.5F, 1);  
  25.     canvas.drawRect(1010300210, paint);  
  26.     break;  
  27.       
  28. case 4// 没用save, restore  
  29.     canvas.rotate(20);  
  30.     canvas.drawRect(10106060, paint);  
  31.     canvas.translate(500);  
  32.     canvas.drawRect(10107070, paint);  
  33.     break;  
  34.       
  35. case 5// 用了save, restore  
  36.     int saveCount = canvas.save();  
  37.     // 将画布旋转20度,然后后面的绘制也都是旋转20度的  
  38.     canvas.rotate(20);  
  39.     canvas.drawRect(10106060, paint);  
  40.     // 将canvas还原到没rotate前  
  41.     canvas.restoreToCount(saveCount);  
  42.     canvas.translate(500);  
  43.     canvas.drawRect(10107070, paint);  
  44.     break;  
  45.       
  46. case 6// 没使用图层  
  47.     paint.setStyle(Paint.Style.FILL);  
  48.     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));  
  49.     canvas.drawRect(00100100, paint);  
  50.     canvas.drawRect(100100200200, paint);  
  51.     paint.setColor(Color.BLUE);  
  52.     canvas.drawRect(5050150150, paint);  
  53.     break;  
  54.       
  55. case 7// 使用了图层layer  
  56.     paint.setStyle(Paint.Style.FILL);  
  57.     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));  
  58.     canvas.drawRect(00100100, paint);  
  59.     // 创建一个图层  
  60.     int layerSC = canvas.saveLayer(nullnull,  
  61.             Canvas.MATRIX_SAVE_FLAG | // 合并图层时,restore应用于图层的变换  
  62.             Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |  
  63.             Canvas.FULL_COLOR_LAYER_SAVE_FLAG);  
  64.     canvas.translate(100100);  
  65.     canvas.drawRect(00100100, paint);  
  66.     paint.setColor(Color.BLUE);  
  67.     canvas.translate(-50, -50);  
  68.     canvas.drawRect(00100100, paint);  
  69.     canvas.restoreToCount(layerSC); // 合并图层  
  70.     break;  

0 0
原创粉丝点击