游戏编程相关参考 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仅仅是矩形。
- Region region = new Region();
- region.isEmpty();
-
- 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);
-
- Region r2 = new Region(region);
- r2.op(0, 0, 150, 120, Region.Op.INTERSECT);
-
- r2 = new Region(region);
- r2.op(0, 0, 150, 120, Region.Op.DIFFERENCE);
-
- r2 = new Region(region);
- r2.op(0, 0, 150, 120, Region.Op.REPLACE);
-
- r2 = new Region(region);
- r2.op(0, 0, 150, 120, Region.Op.REVERSE_DIFFERENCE);
-
- r2 = new Region(region);
- r2.op(0, 0, 150, 120, Region.Op.UNION);
-
- 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, 30, Path.Direction.CCW);
- pathToDraw.addCircle(50, 100, 30, Path.Direction.CW);
- pathToDraw.addCircle(50, 100, 30, Path.Direction.CCW);
- pathToDraw.close();
- pathToDraw.addCircle(50, 100, 30, Path.Direction.CW);
- pathToDraw.close();
-
- pathToDraw.addArc(new RectF(25, 75, 55, 155), 0, 270);
-
- pathToDraw.arcTo(new RectF(25, 75, 55, 155), 0, 270);
-
- pathToDraw.cubicTo(25, 125, 75, 175, 30, 200);
-
- pathToDraw.cubicTo(25, 125, 75, 175, 30, 200);
Path.FillType路劲的填充类型还不是很理解,主要是文档没有对其做任何解释,api demo只有代码,也不懂啥意思。网上找了也没有解释的很清楚的。可以看下这个连接:http://www.imobilebbs.com/wordpress/?p=1589
Bitmap Bitmap的density参数的使用
- canvas.drawBitmap(mBmp, 0, 0, null);
-
- mBmp.setDensity(240);
- canvas.drawBitmap(mBmp, 100, 0, null);
-
- canvas.drawBitmap(mBmp, null, new Rect(0, 100, 100, 200), null);
-
- canvas.drawBitmap(mBmp, new Rect(0, 0, 100, 50), new Rect(100, 100, 200, 150), null);
-
- 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:
-
- canvas.drawColor(Color.argb(100, 0, 0, 255), Mode.SRC);
- break;
-
- case 3:
-
- Paint paint = new Paint();
- paint.setARGB(100, 0xEE, 0xEE, 0xEE);
- canvas.drawPaint(paint);
- break;
- }
绘制Bitmap
- switch (keyUpCount) {
- case 0:
- canvas.drawBitmap(chameleonBmp, 20, 20, null);
- break;
-
- case 1:
- Matrix matrix = new Matrix();
- matrix.setRotate(10);
- matrix.preTranslate(50, 50);
- canvas.drawBitmap(chameleonBmp, matrix, null);
- break;
-
- case 2:
-
-
- 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);
-
-
- break;
-
- case 3:
-
-
- 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++) {
- canvas.drawPoint(i * 10, 20, paint);
- }
- break;
-
- case 1:
- for (int i = 1; i < 10; i++) {
- 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();
- path.moveTo(10, 10);
- path.lineTo(200, 10);
- path.lineTo(140, 60);
- path.lineTo(120, 30);
- 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.image830);
-
- 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, 300, 160);
- canvas.drawBitmap(bmp, 300, 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(30);
-
- switch (keyUpCount) {
- case 0:
- Paint paint0 = new Paint(paint);
- paint0.setUnderlineText(true);
- canvas.drawText("underline text", 10, 50, paint0);
- break;
-
- case 1:
- 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);
-
-
- break;
-
- case 4:
- String text = "abcdefghijklmnOPQRST12345";
- Paint paint4 = new Paint();
- paint4.setColor(Color.BLUE);
- paint4.setStyle(Style.STROKE);
-
- Path path = new Path();
- path.moveTo(10, 100);
- path.cubicTo(110, 200, 210, 0, 310, 100);
- canvas.drawPath(path, paint4);
-
- paint.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:
- canvas.rotate(20);
- canvas.drawRect(10, 10, 300, 210, paint);
- break;
-
- case 1:
- canvas.translate(100, 0);
- canvas.drawRect(10, 10, 300, 210, paint);
- break;
-
- case 2:
- canvas.skew(0.2F, 0);
- canvas.drawRect(10, 10, 300, 210, paint);
- break;
-
- case 3:
- canvas.scale(0.5F, 1);
- canvas.drawRect(10, 10, 300, 210, paint);
- break;
-
- case 4:
- canvas.rotate(20);
- canvas.drawRect(10, 10, 60, 60, paint);
- canvas.translate(50, 0);
- canvas.drawRect(10, 10, 70, 70, paint);
- break;
-
- case 5:
- int saveCount = canvas.save();
-
- canvas.rotate(20);
- canvas.drawRect(10, 10, 60, 60, paint);
-
- 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:
- paint.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 |
- 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;

android.graphics包中的一些类的使用
原文:http://www.cnblogs.com/Free-Thinker/p/4831740.html