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

    博客分类:
  • android
Canvas Region Path SurfaceView android game 游戏编程相关参考
Matrix学习系列:
http://www.moandroid.com/?p=1781
Android画图学习总结系列:
http://www.moandroid.com/?p=764
游戏开发系列(opengl es基础知识):
http://www.moandroid.com/?p=17 30
线性代数(包含矩阵的相关知识):
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仅仅是矩形。
Region region = new Region();region.isEmpty();// width: 100, height: 50的矩形region.set(100, 100, 200, 150);Rect bounds = region.getBounds();// 矩形区域是否在其内部boolean contains = region.quickContains(120, 120, 170, 150);// 矩形区域是否不在其内部boolean reject = region.quickReject(0, 0, 50, 50);// INTERSECT 取两者交集Region r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.INTERSECT);// DIFFERENCE 第一次不同于第二次的部分显示出来r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.DIFFERENCE);// REPLACE 显示第二次的r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.REPLACE);// REVERSE_DIFFERENCE 第二次不同于第一次的部分显示r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.REVERSE_DIFFERENCE);// UNION 取全集r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.UNION);// XOR 补集,就是全集的减去交集的剩余部分显示r2 = new Region(region);r2.op(0, 0, 150, 120, Region.Op.XOR);

示意图



Path
path可以看作是一个点集,将它内部的点集按顺序连接起来时可以组成任意边型。一般多边形就是用Path来画。
// 公共代码Path pathToDraw = new Path();// 移到某点处作为起点pathToDraw.moveTo(50, 50);pathToDraw.lineTo(100, 50);pathToDraw.lineTo(150, 100);pathToDraw.lineTo(50, 100);// 多边形pathToDraw.lineTo(100, 75);pathToDraw.close();// 不闭合,逆时针pathToDraw.addCircle(50, 100, <span style="background-color: rgb(255, 102, 255);">30</span>, <a target=_blank name="baidusnap0" style="color: rgb(16, 138, 198); text-decoration: underline;"></a><span style="background-color: rgb(255, 255, 102);">Path.</span>Direction.CCW);// 不闭合,顺时针pathToDraw.addCircle(50, 100, <span style="background-color: rgb(255, 102, 255);">30</span>, <span style="background-color: rgb(255, 255, 102);">Path.</span>Direction.CW);// 闭合,逆时针pathToDraw.addCircle(50, 100, <span style="background-color: rgb(255, 102, 255);">30</span>, <span style="background-color: rgb(255, 255, 102);">Path.</span>Direction.CCW);pathToDraw.close();// 闭合,逆时针pathToDraw.addCircle(50, 100, <span style="background-color: rgb(255, 102, 255);">30</span>, <span style="background-color: rgb(255, 255, 102);">Path.</span>Direction.CW);pathToDraw.close();// 上面四个画出来是一样的// 添加弧线,弧线是由矩形来控制的,正方形时是圆弧,矩形时就是椭圆弧了pathToDraw.addArc(new RectF(25, 75, 55, 155), 0, 270);// 在最后一个点处添加弧线,如果rectf中指定的点与最后一个点不同,则首先会将其先lineTo最后一个点(图中可以看到,与上面的代码所画的图的区别就是多了个连接线段)pathToDraw.arcTo(new RectF(25, 75, 55, 155), 0, 270);// 添加二次曲线,两个控制点(25, 125), (75, 175)pathToDraw.cubicTo(25, 125, 75, 175, <span style="background-color: rgb(255, 102, 255);">30</span>, 200);// 添加三次曲线,三个控制点(25, 125), (75, 175), (<span style="background-color: rgb(255, 102, 255);">30</span>, 200)pathToDraw.cubicTo(25, 125, 75, 175, <span style="background-color: rgb(255, 102, 255);">30</span>, 200);

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



Bitmap
Bitmap的density参数的使用
// 将完整的图片绘制到(0, 0)处canvas.drawBitmap(mBmp, 0, 0, null);// 240(hdpi)的图片放到160上时,就会变小1.5倍mBmp.setDensity(240);// 将完整的图片绘制到(100, 0)处canvas.drawBitmap(mBmp, 100, 0, null);// 将完整的源图片绘制到起点为(0, 100),宽100、高100的矩形范围内canvas.drawBitmap(mBmp, null, new Rect(0, 100, 100, 200), null);// 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(100, 100)宽100, 高50的矩形范围内canvas.drawBitmap(mBmp, new Rect(0, 0, 100, 50), new Rect(100, 100, 200, 150), null);// 将源图片的(0, 0)开始宽100、高100部分绘制到起点为(200, 100)宽50, 25的矩形范围内canvas.drawBitmap(mBmp, new Rect(0, 0, 100, 50), new Rect(200, 100, 250, 125), null);

效果:

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


Paint介绍
Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色,
样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法,
大体上可以分为两类,一类与图形绘制相关,一类与文本绘制相关。
 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
填充颜色,一般清屏时会用这里的方法
switch (keyUpCount) {case 0:canvas.drawARGB(100, 255, 0, 0);break;case 1:canvas.drawColor(Color.argb(100, 0, 255, 0));break;case 2:// 指定PorterDuff mode方式绘制颜色canvas.drawColor(Color.argb(100, 0, 0, 255), Mode.SRC);break;case 3:// paint方式的绘制颜色Paint paint = new Paint();paint.setARGB(100, 0xEE, 0xEE, 0xEE);canvas.drawPaint(paint);break;}



绘制Bitmap
switch (keyUpCount) {case 0: // 在(x, y)除绘制bitmapcanvas.drawBitmap(chameleonBmp, 20, 20, null);break;case 1: // 利用变换矩阵绘制bimapMatrix matrix = new Matrix();matrix.setRotate(10);matrix.preTranslate(50, 50);canvas.drawBitmap(chameleonBmp, matrix, null);break;case 2:// 将图片的(0, 0, 100, 184)区域拉伸或缩放到canvas的// (50, 50, 250, 418)区域进行绘制Rect src = new Rect();src.set(0, 0, 100, 184);Rect dst = new Rect();dst.set(50, 50, 250, 418);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, 0, 15, 20, 20, 15, 3, false, null);break;}



绘制基本的几何图形(绘制几何图形时,必须使用画笔paint)
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<a target=_blank name="baidusnap9" style="color: rgb(16, 138, 198); text-decoration: underline;"></a><span style="color: white; background-color: rgb(153, 0, 153);">++</span>) {canvas.drawPoint(i * 10, 20, paint);}break;case 1: // 直线for (int i = 1; i < 10; i<span style="color: white; background-color: rgb(153, 0, 153);">++</span>) {canvas.drawLine(10, i * 10, 200, i * 10, paint);}break;case 2: // 圆canvas.drawCircle(100, 100, 90, paint);break;case 3: // 弧线和矩形RectF outRect = new RectF(10, 10, 110, 110);canvas.drawRect(outRect, paint);float startAngle = 70;float sweepAngle = 180;canvas.drawArc(outRect, startAngle, sweepAngle, false, paint);break;case 4: // 椭圆canvas.drawOval(new RectF(10, 10, 110, 60), paint);break;case 5: // 路径(任意边型)Path path = new Path();<span style="background-color: rgb(255, 255, 102);">path.</span>moveTo(10, 10);<span style="background-color: rgb(255, 255, 102);">path.</span>lineTo(200, 10);<span style="background-color: rgb(255, 255, 102);">path.</span>lineTo(140, 60);<span style="background-color: rgb(255, 255, 102);">path.</span>lineTo(120, <span style="background-color: rgb(255, 102, 255);">30</span>);canvas.drawPath(path, paint);break;case 6: // 圆角矩形RectF rect = new RectF(10, 10, 100, 100);canvas.drawRoundRect(rect, 20, 40, paint);break;}




canvas的一些效果
翻转效果,这样在使用图片时,左和右的图片就可以重用了。
Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.image8<span style="background-color: rgb(255, 102, 255);">30</span>);canvas.drawColor(Color.WHITE);canvas.drawBitmap(bmp, 100, 160, null);// 水平翻转canvas.save();canvas.scale(-1, 1, 240, 160);canvas.drawBitmap(bmp, 240, 160, null);canvas.restore();// 垂直翻转canvas.save();canvas.scale(1, -1, <span style="background-color: rgb(255, 102, 255);">30</span>0, 160);canvas.drawBitmap(bmp, <span style="background-color: rgb(255, 102, 255);">30</span>0, 160, null);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的最小值)

Paint paint = new Paint();paint.setColor(Color.RED); // 画笔颜色paint.setAntiAlias(true); // 抗锯齿paint.setStyle(Style.STROKE); // 笔触绘制paint.setTextSize(<span style="background-color: rgb(255, 102, 255);">30</span>); // 字体大小switch (keyUpCount) {case 0: // 下划线文本Paint paint0 = new Paint(paint);paint0.setUnderlineText(true);canvas.drawText("underline text", 10, 50, 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, 10, 50, paint1);break;case 2: // 缩放文本Paint paint2 = new Paint(paint);paint2.setTextScaleX(3.0F);paint2.setTextSize(15);canvas.drawText("text scale x", 0, 12, 10, 50, 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", 0, 9, 10, 50, paint3);/* font attributesPaint.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 pathPath path = new Path();<span style="background-color: rgb(255, 255, 102);">path.</span>moveTo(10, 100);<span style="background-color: rgb(255, 255, 102);">path.</span>cubicTo(110, 200, 210, 0, 310, 100);canvas.drawPath(path, paint4);// draw textpaint.setTextSize(20);canvas.drawTextOnPath(text, path, 20.0F, 5.0F, paint);break;




canvas变换,save, restore, layer的使用
layer其实就相当于photoshop中图层的概念,对当前图层的操作是不影响其它图层的。
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(10, 10, <span style="background-color: rgb(255, 102, 255);">30</span>0, 210, paint);break;case 1: // translate移动canvas.translate(100, 0);canvas.drawRect(10, 10, <span style="background-color: rgb(255, 102, 255);">30</span>0, 210, paint);break;case 2: // skew倾斜canvas.skew(0.2F, 0);canvas.drawRect(10, 10, <span style="background-color: rgb(255, 102, 255);">30</span>0, 210, paint);break;case 3: // 缩放canvas.scale(0.5F, 1);canvas.drawRect(10, 10, <span style="background-color: rgb(255, 102, 255);">30</span>0, 210, paint);break;case 4: // 没用save, restorecanvas.rotate(20);canvas.drawRect(10, 10, 60, 60, paint);canvas.translate(50, 0);canvas.drawRect(10, 10, 70, 70, paint);break;case 5: // 用了save, restoreint saveCount = canvas.save();// 将画布旋转20度,然后后面的绘制也都是旋转20度的canvas.rotate(20);canvas.drawRect(10, 10, 60, 60, paint);// 将canvas还原到没rotate前canvas.restoreToCount(saveCount);canvas.translate(50, 0);canvas.drawRect(10, 10, 70, 70, paint);break;case 6: // 没使用图层paint.setStyle(Paint.Style.FILL);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));canvas.drawRect(0, 0, 100, 100, paint);canvas.drawRect(100, 100, 200, 200, paint);paint.setColor(Color.BLUE);canvas.drawRect(50, 50, 150, 150, paint);break;case 7: // 使用了图层layerpaint.setStyle(Paint.Style.FILL);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN));canvas.drawRect(0, 0, 100, 100, paint);// 创建一个图层int layerSC = canvas.saveLayer(null, null,Canvas.MATRIX_SAVE_FLAG | // 合并图层时,restore应用于图层的变换Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |Canvas.FULL_COLOR_LAYER_SAVE_FLAG);canvas.translate(100, 100);canvas.drawRect(0, 0, 100, 100, paint);paint.setColor(Color.BLUE);canvas.translate(-50, -50);canvas.drawRect(0, 0, 100, 100, paint);canvas.restoreToCount(layerSC); // 合并图层break;


  • 线性代数清华第二版.pdf(4.2 MB)
  • 下载次数: 65
  • demo_game.rar(397.6 KB)

更多相关文章

  1. Android播放器中我喜欢的一个地方-----高斯模糊效果
  2. Android(安卓)ApiDemo 笔记(一)Content与Graphics
  3. 解决WebView加载URL跳转到系统浏览器的问题
  4. Android设置TextView的Selector来控制点击的颜色
  5. (4.2.0)GitHub开源项目收集
  6. android手势实现图片的拖动和缩放效果
  7. Android刮刮乐效果-proterDuffXfermode的示例代码
  8. Android(安卓)CardView 设置点击效果
  9. Android(安卓)学习之Drawable-shape使用方法

随机推荐

  1. Android绘图之drawText绘制文本相关(4)
  2. Android bitmap图片处理
  3. Ubuntu下 eclipse搭建android集成开发环
  4. 近期工作计划
  5. Android开发人员终于在“app-构建控制台
  6. Android 框架模式 MVC 在Android中的使用
  7. Android EGL
  8. Handler知识点总结
  9. 画一个可以动的Android 小机器人
  10. Android 手机卡了怎么办