今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧。

Android游戏开发教程之二:最全的自定义View界面用法汇总

       1.自定义view绘制字符串

       相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便、省内存。我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要,而且使用它还可以带来一个更重要的好处就是可以很方便的实现多国语言的切换。笔者现在在正在做的一个产品就是可以多语言切换的软件,有英语、繁体中文等等。设想如果使用图片字的话那每个语言都须要出一套图,我用一个例子简单介绍一下绘制字符串。 

Android游戏开发教程之二:最全的自定义View界面用法汇总

Java代码
  1. package cn.m15.xys;    
  2.    
  3. import android.app.Activity;    
  4. import android.content.Context;    
  5. import android.graphics.Canvas;    
  6. import android.graphics.Color;    
  7. import android.graphics.Paint;    
  8. import android.graphics.Paint.FontMetrics;    
  9. import android.os.Bundle;    
  10. import android.view.Display;    
  11. import android.view.View;    
  12.    
  13. public class Font extends Activity {    
  14.     public int mScreenWidth = 0;    
  15.     public int mScreenHeight = 0;    
  16.     @Override    
  17.     protected void onCreate(Bundle savedInstanceState) {    
  18.     setContentView(new FontView(this));    
  19.     // 获取屏幕宽高    
  20.     Display display = getWindowManager().getDefaultDisplay();    
  21.     mScreenWidth  = display.getWidth();    
  22.     mScreenHeight = display.getHeight();    
  23.     super.onCreate(savedInstanceState);    
  24.    
  25.     }    
  26.    
  27.     class FontView extends View {    
  28.         public final static String STR_WIDTH = "获取字符串宽为:";     
  29.         public final static String STR_HEIGHT = "获取字体高度为:";     
  30.         Paint mPaint = null;    
  31.             
  32.     public FontView(Context context) {    
  33.         super(context);    
  34.         mPaint = new Paint();    
  35.     }    
  36.    
  37.     @Override    
  38.     protected void onDraw(Canvas canvas) {    
  39.         //设置字符串颜色    
  40.         mPaint.setColor(Color.WHITE);    
  41.         canvas.drawText("当前屏幕宽" + mScreenWidth, 030, mPaint);    
  42.         canvas.drawText("当前屏幕高"+ mScreenHeight, 060, mPaint);    
  43.         //设置字体大小    
  44.         mPaint.setColor(Color.RED);    
  45.         mPaint.setTextSize(18);    
  46.         canvas.drawText("字体大小为18"090, mPaint);    
  47.         //消除字体锯齿    
  48.         mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);    
  49.         canvas.drawText("消除字体锯齿后"0120, mPaint);    
  50.         //获取字符串宽度    
  51.         canvas.drawText(STR_WIDTH + getStringWidth(STR_WIDTH), 0150, mPaint);    
  52.         //获取字体高度    
  53.         canvas.drawText(STR_HEIGHT + getFontHeight(), 0180, mPaint);    
  54.         //从string.xml读取字符串绘制    
  55.         mPaint.setColor(Color.YELLOW);    
  56.         canvas.drawText(getResources().getString(R.string.string_font), 0210, mPaint);    
  57.         super.onDraw(canvas);    
  58.     }    
  59.         
  60.     /**   
  61.      * 获取字符串宽   
  62.      * @param str   
  63.      * @return   
  64.      */    
  65.     private int getStringWidth(String str) {    
  66.         return (int) mPaint.measureText(STR_WIDTH);     
  67.     }    
  68.     /*   
  69.      * 获取字体高度   
  70.      */    
  71.     private int getFontHeight() {    
  72.         FontMetrics fm = mPaint.getFontMetrics();    
  73.         return (int)Math.ceil(fm.descent - fm.top) + 2;    
  74.     }    
  75.     }    
  76. }   

       2.绘制无规则几何图形

       绘制无规则几何图形似乎在实际工作中很少可以用到 原因是用程序去绘制图形即使在精准再好看也不会有美术出的图片好看 但是使用程序绘制图形作为学习来说却是基础中的基础,所以建议大家都看一看。

Android游戏开发教程之二:最全的自定义View界面用法汇总

Java代码
  1. package cn.m15.xys;    
  2.    
  3. import android.app.Activity;    
  4. import android.content.Context;    
  5. import android.graphics.Canvas;    
  6. import android.graphics.Color;    
  7. import android.graphics.Paint;    
  8. import android.graphics.Path;    
  9. import android.graphics.RectF;    
  10. import android.os.Bundle;    
  11. import android.view.View;    
  12.    
  13. public class Geometry extends Activity {    
  14.     public int mScreenWidth = 0;    
  15.     public int mScreenHeight = 0;    
  16.    
  17.     @Override    
  18.     protected void onCreate(Bundle savedInstanceState) {    
  19.     setContentView(new GeometryView(this));    
  20.     super.onCreate(savedInstanceState);    
  21.    
  22.     }    
  23.    
  24.     class GeometryView extends View {    
  25.     Paint mPaint = null;    
  26.    
  27.     public GeometryView(Context context) {    
  28.         super(context);    
  29.         mPaint = new Paint();    
  30.         mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);    
  31.     }    
  32.    
  33.     @Override    
  34.     protected void onDraw(Canvas canvas) {    
  35.         super.onDraw(canvas);    
  36.         
  37.         //设置画布颜色 也就是背景颜色    
  38.         canvas.drawColor(Color.WHITE);    
  39.            
  40.         mPaint.setColor(Color.BLACK);    
  41.         canvas.drawText("绘制无规则几何图形喔!!!"15030, mPaint);    
  42.             
  43.         //绘制一条线    
  44.         mPaint.setColor(Color.BLACK);    
  45.         mPaint.setStrokeWidth(4);    
  46.         canvas.drawLine(00100100, mPaint);    
  47.             
  48.         //绘制一个矩形    
  49.         mPaint.setColor(Color.YELLOW);    
  50.         canvas.drawRect(0120100200, mPaint);    
  51.             
  52.         //绘制一个圆形    
  53.         mPaint.setColor(Color.BLUE);    
  54.         canvas.drawCircle(8030050, mPaint);    
  55.             
  56.         //绘制一个椭圆    
  57.         mPaint.setColor(Color.CYAN);    
  58.         canvas.drawOval(new RectF(300,370,120,100), mPaint);    
  59.             
  60.         //绘制多边形    
  61.         mPaint.setColor(Color.BLACK);    
  62.         Path path = new Path();    
  63.         path.moveTo(150+5 , 400 -50);    
  64.         path.lineTo(150+45400 - 50);    
  65.         path.lineTo(150+30460 - 50);    
  66.         path.lineTo(150+20460 - 50);    
  67.         path.close();    
  68.         canvas.drawPath(path, mPaint);    
  69.             
  70.     }    
  71.     }    
  72. }   

       3.图片的绘制以及旋转缩放的实现

       在这点上Android 确实比J2ME 强大很多 手机游戏开发最痛苦的是什么?? 是游戏引擎的开发,但是工程师会把大部分时间浪费在对坐标上,如果写引擎的时候没有把自适应考虑周全后期会非常痛苦,现在手机屏幕分辨率是各式各样 内存大小也是各式各样 所以可见自适应屏幕算法有多么的重要。

Android游戏开发教程之二:最全的自定义View界面用法汇总

Java代码
  1. package cn.m15.xys;    
  2.    
  3. import android.app.Activity;    
  4. import android.content.Context;    
  5. import android.graphics.Bitmap;    
  6. import android.graphics.BitmapFactory;    
  7. import android.graphics.Canvas;    
  8. import android.graphics.Matrix;    
  9. import android.graphics.Paint;    
  10. import android.os.Bundle;    
  11. import android.view.View;    
  12. import android.view.View.OnClickListener;    
  13. import android.widget.Button;    
  14. import android.widget.LinearLayout;    
  15.    
  16. public class Image extends Activity {    
  17.     ImageView imageView = null;    
  18.    
  19.     @Override    
  20.     protected void onCreate(Bundle savedInstanceState) {    
  21.     imageView = new ImageView(this);    
  22.     setContentView(R.layout.image);    
  23.     LinearLayout ll = (LinearLayout) findViewById(R.id.iamgeid);    
  24.     ll.addView(imageView);    
  25.     // 向左移动    
  26.     Button botton0 = (Button) findViewById(R.id.buttonLeft);    
  27.     botton0.setOnClickListener(new OnClickListener() {    
  28.         @Override    
  29.         public void onClick(View arg0) {    
  30.         imageView.setPosLeft();    
  31.         }    
  32.     });    
  33.    
  34.     // 向右移动    
  35.     Button botton1 = (Button) findViewById(R.id.buttonRight);    
  36.     botton1.setOnClickListener(new OnClickListener() {    
  37.         @Override    
  38.         public void onClick(View arg0) {    
  39.         imageView.setPosRight();    
  40.         }    
  41.     });    
  42.     // 左旋转    
  43.     Button botton2 = (Button) findViewById(R.id.buttonRotationLeft);    
  44.     botton2.setOnClickListener(new OnClickListener() {    
  45.         @Override    
  46.         public void onClick(View arg0) {    
  47.         imageView.setRotationLeft();    
  48.         }    
  49.     });    
  50.    
  51.     // 右旋转    
  52.     Button botton3 = (Button) findViewById(R.id.buttonRotationRight);    
  53.     botton3.setOnClickListener(new OnClickListener() {    
  54.         @Override    
  55.         public void onClick(View arg0) {    
  56.         imageView.setRotationRight();    
  57.         }    
  58.     });    
  59.    
  60.     // 缩小    
  61.     Button botton4 = (Button) findViewById(R.id.buttonNarrow);    
  62.     botton4.setOnClickListener(new OnClickListener() {    
  63.    
  64.         @Override    
  65.         public void onClick(View arg0) {    
  66.         imageView.setNarrow();    
  67.         }    
  68.     });    
  69.    
  70.     // 放大    
  71.     Button botton5 = (Button) findViewById(R.id.buttonEnlarge);    
  72.     botton5.setOnClickListener(new OnClickListener() {    
  73.    
  74.         @Override    
  75.         public void onClick(View arg0) {    
  76.         imageView.setEnlarge();    
  77.         }    
  78.     });    
  79.    
  80.     super.onCreate(savedInstanceState);    
  81.    
  82.     }    
  83.    
  84.     class ImageView extends View {    
  85.     Paint mPaint = null;    
  86.     Bitmap bitMap = null;    
  87.     Bitmap bitMapDisplay = null;    
  88.     int m_posX = 120;    
  89.     int m_posY = 50;    
  90.     int m_bitMapWidth = 0;    
  91.     int m_bitMapHeight = 0;    
  92.     Matrix mMatrix = null;    
  93.     float mAngle = 0.0f;    
  94.     float mScale = 1f;//1为原图的大小    
  95.    
  96.     public ImageView(Context context) {    
  97.         super(context);    
  98.         mPaint = new Paint();    
  99.         mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);    
  100.         bitMap = BitmapFactory.decodeResource(this.getResources(),    
  101.             R.drawable.image);    
  102.         bitMapbitMapDisplay = bitMap;    
  103.         mMatrix = new Matrix();    
  104.         // 获取图片宽高    
  105.         m_bitMapWidth = bitMap.getWidth();    
  106.         m_bitMapHeight = bitMap.getHeight();    
  107.     }    
  108.    
  109.     // 向左移动    
  110.     public void setPosLeft() {    
  111.         m_posX -= 10;    
  112.     }    
  113.    
  114.     // 向右移动    
  115.     public void setPosRight() {    
  116.         m_posX += 10;    
  117.     }    
  118.    
  119.     // 向左旋转    
  120.     public void setRotationLeft() {    
  121.         mAngle--;    
  122.         setAngle();    
  123.     }    
  124.    
  125.     // 向右旋转    
  126.     public void setRotationRight() {    
  127.         mAngle++;    
  128.         setAngle();    
  129.     }    
  130.    
  131.     // 缩小图片    
  132.     public void setNarrow() {    
  133.         if (mScale > 0.5) {    
  134.         mScale -= 0.1;    
  135.         setScale();    
  136.         }    
  137.     }    
  138.    
  139.     // 放大图片    
  140.     public void setEnlarge() {    
  141.         if (mScale < 2) {    
  142.         mScale += 0.1;    
  143.         setScale();    
  144.         }    
  145.     }    
  146.    
  147.     // 设置缩放比例    
  148.     public void setAngle() {    
  149.         mMatrix.reset();    
  150.         mMatrix.setRotate(mAngle);    
  151.         bitMapDisplay = Bitmap.createBitmap(bitMap, 00, m_bitMapWidth,    
  152.             m_bitMapHeight, mMatrix, true);    
  153.     }    
  154.    
  155.     // 设置旋转比例    
  156.     public void setScale() {    
  157.         mMatrix.reset();    
  158.         //float sx X轴缩放     
  159.         //float sy Y轴缩放    
  160.         mMatrix.postScale(mScale, mScale);    
  161.         bitMapDisplay = Bitmap.createBitmap(bitMap, 00, m_bitMapWidth,    
  162.             m_bitMapHeight, mMatrix, true);    
  163.     }    
  164.    
  165.     @Override    
  166.     protected void onDraw(Canvas canvas) {    
  167.         super.onDraw(canvas);    
  168.         canvas.drawBitmap(bitMapDisplay, m_posX, m_posY, mPaint);    
  169.         invalidate();    
  170.     }    
  171.     }    
  172. }   
XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:id="@+id/iamgeid"   
  4.     android:orientation="vertical"   
  5.     android:layout_width="fill_parent"   
  6.     android:layout_height="fill_parent"   
  7.     >   
  8.         <Button android:id="@+id/buttonLeft"   
  9.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  10.             android:text="图片向左移动"   
  11.             />   
  12.         <Button android:id="@+id/buttonRight"   
  13.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  14.             android:text="图片向右移动"   
  15.             />   
  16.         <Button android:id="@+id/buttonRotationLeft"   
  17.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  18.             android:text="图片左旋转"   
  19.             />   
  20.         <Button android:id="@+id/buttonRotationRight"   
  21.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  22.             android:text="图片右旋转"   
  23.             />   
  24.         <Button android:id="@+id/buttonNarrow"   
  25.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  26.             android:text="图片缩小"   
  27.             />   
  28.         <Button android:id="@+id/buttonEnlarge"   
  29.             android:layout_width="fill_parent" android:layout_height="wrap_content"   
  30.             android:text="图片放大"   
  31.             />   
  32. </LinearLayout>   

       4.播放frame动画

       做游戏的话播放动画可就是必不可少的元素 帧动画帧动画 顾名思义是一帧一帧的播放 。 实际在开发中为了节省内存美术会把人物的图片切成一小块一小块然后由程序根据编辑器生成的点把图片在拼接起来这样就可以做到用更少的图片去实现更多的动画效果因为不太方便介绍图片编辑器 这个demo我只给大家简单的介绍一下播放动画的原理 后期我会深入讲解。

       如图所示这个小人一直在行走 实际上是4张图片在来回切换 每张图片延迟500毫秒 后播下一张 以此类推。

Android游戏开发教程之二:最全的自定义View界面用法汇总

Java代码
  1. package cn.m15.xys;    
  2.    
  3. import android.app.Activity;    
  4. import android.content.Context;    
  5. import android.graphics.Bitmap;    
  6. import android.graphics.BitmapFactory;    
  7. import android.graphics.Canvas;    
  8. import android.graphics.Color;    
  9. import android.graphics.Paint;    
  10. import android.os.Bundle;    
  11. import android.view.View;    
  12.    
  13. public class FramAnimation extends Activity {    
  14.     public final static int ANIM_COUNT = 4;    
  15.    
  16.     @Override    
  17.     protected void onCreate(Bundle savedInstanceState) {    
  18.     setContentView(new FramView(this));    
  19.     super.onCreate(savedInstanceState);    
  20.    
  21.     }    
  22.    
  23.     class FramView extends View {    
  24.     Bitmap[] bitmap = new Bitmap[ANIM_COUNT];    
  25.     Bitmap display = null;    
  26.     Paint paint = null;    
  27.     long startTime = 0;    
  28.     int playID = 0;    
  29.    
  30.     public FramView(Context context) {    
  31.         super(context);    
  32.         for (int i = 0; i < ANIM_COUNT; i++) {    
  33.         bitmap[i] = BitmapFactory.decodeResource(this.getResources(),    
  34.             R.drawable.hero_a + i);    
  35.         }    
  36.         display = bitmap[0];    
  37.         paint = new Paint();    
  38.         startTime = System.currentTimeMillis();    
  39.     }    
  40.    
  41.     @Override    
  42.     protected void onDraw(Canvas canvas) {    
  43.         super.onDraw(canvas);    
  44.         paint.setColor(Color.WHITE);    
  45.         canvas.drawText("播放动画中..."10030, paint);    
  46.         long nowTime = System.currentTimeMillis();    
  47.         if (nowTime - startTime >= 500) {    
  48.         startTime=nowTime;    
  49.         playID++;    
  50.         if (playID >= ANIM_COUNT) {    
  51.             playID = 0;    
  52.         }    
  53.         canvas.drawBitmap(bitmap[playID], 100100, paint);    
  54.         }    
  55.         invalidate();    
  56.     }    
  57.     }    
  58.    
  59. }   

        源码下载地址:http://download.csdn.net/source/3448152

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/course/466.html
2015年8月24日
发布:鸡啄米 分类:Android开发教程 浏览: 评论:0