1.画一个球,在遇到四周的墙壁会反弹。

package com.example.draw2d;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RadialGradient;import android.graphics.Rect;import android.graphics.Shader;import android.graphics.drawable.ShapeDrawable;import android.graphics.drawable.shapes.OvalShape;import android.view.View;public class Draw2D extends Activity {            @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);                setContentView(new BallView(this));    }    /**     * 定义一个View,用来显示球     * @author siqi     *     */    public class BallView extends View {        private Ball ball = new Ball();        private BallThread ballThread = new BallThread(this);                public BallView(Context context) {            super(context);                        /**             * 启动线程             */            ballThread.start();        }        public Ball getBall() {            return ball;        }                /**         * onDraw在每次View被刷新的时候执行。         */        @Override        protected void onDraw(Canvas canvas) {            ball.draw(canvas);            super.onDraw(canvas);        }    }        /**     * 定义一个线程来刷新View,处理球的运动     * @author siqi     *     */    public class BallThread extends Thread {        /**         * 当bAlive是false的时候退出线程         */        private boolean bAlive = true;                private BallView ballView;                /**         * 球运动的速度         */        private int speed = 3;        /**         * x方向的运动速度,正表示向右,负表示向左         */        private int xDir = speed;        /**         * y方向的运动速度,正表示向下,负表示向上         */        private int yDir = speed;                /**         * 我们需要在线程里面刷新view,和获取view中的那个球对象         * 所以我们需要传入view         * @param view         */        public BallThread(BallView view) {            this.ballView = view;        }                /**         * 线程运行         */        @Override        public void run() {            /**             * 我们想要获取view的宽度和高度,但是在activity             * setContentView(new BallView(this)); 后,获取的宽度和长度             * 有可能为0,设置view需要大约200ms的时间。所以在这里,我们用一个             * 循环,直到view准备好。             */            while(ballView.getWidth()<1) {                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                }            }            /**             * 获取view的长度和宽度(不包括标题栏(有标题的那个)和通知栏(有信号图标的那个))             */            int screenWidth = ballView.getWidth();            int screenHeight = ballView.getHeight();            /**             * 获取球的宽度             */            int ballW = ballView.getBall().getRect().width();            /**             * 球下一个运动位置             */            int xNext, yNext;            /**             * 设置循环,我们需要有一个手段,能够结束线程,所以我们定义了bAlive             * 当bAlive为false的时候,退出。             */            while(bAlive) {                try {                    /**                     * 刷新一次view的显示后,都等待30ms。当图像每秒刷新30次的时候,                     * 大部分人的眼睛就已经认为图像是连续的了,1000ms/30 = 33.33ms,在这里                     * 省略成30。                      */                    Thread.sleep(30);                    /**                     * 获取球当前位置,范围                     */                    Rect ballRect = ballView.getBall().getRect();                    /**                     * 按照X,Y方向的速度,下一个位置                     */                    xNext = ballRect.left + xDir;                    yNext = ballRect.top + yDir;                                        /**                     * 表示撞到了右边/左边的墙壁                     */                    if(xNext>=screenWidth-ballW || xNext<0) {                        xDir = -1 * xDir;    //转向                        xNext = ballRect.left + xDir;                    }                                        /**                     * 表示撞到了下边/上边的墙壁                     */                    if(yNext>=screenHeight-ballW || yNext<0) {                        yDir = -1 * yDir;                        yNext = ballRect.top + yDir;                    }                    /**                     * 更新球的位置                     */                    ballView.ball.move(xNext, yNext);                                        /**                     * 通知View,重画View                     */                    ballView.post(new Runnable() {                        @Override                        public void run() {                            ballView.invalidate();                        }                    });                                    } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }                /**         * 调用destory,我们把bAlive设置成false,这样         * run()里面的循环就不会再继续。线程在执行完成后退出。         */        @Override        public void destroy() {            bAlive = false;        }    }    /**     * 定义球的类     * @author siqi     *     */    public class Ball {                private ShapeDrawable mBall;        public Ball() {            this.mBall = createBall(10);        }        public Ball(int r) {            this.mBall = createBall(r);        }                public Rect getRect() {            if (this.mBall == null) {                return null;            } else {                return this.mBall.getBounds();            }        }                /**         * 创建一个球的绘图对象(Drawable),如果不用着色器的话,画出来的         * 球很难看,没有立体感。         * @param r 球的半径         * @return 返回球的绘图对象         */        private ShapeDrawable createBall(float r) {            //直径            float diameter = 2 * r;            //用椭圆模板创建一个绘图对象            ShapeDrawable drawable = new ShapeDrawable(new OvalShape());            //设置球的颜色和深颜色,在这里,我们设置的是绿色RGB(128,255,30)            //RGB值可以通过windows画图程序->颜色(菜单)->编辑颜色->自定义颜色得到            int red = 128;            int green = 225;            int blue = 30;            int color = 0xff000000 | red << 16 | green << 8 | blue;            //RGB各个颜色的值越小,颜色越黑(深)            int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;                        //得到绘图对象的画笔            Paint paint = drawable.getPaint();            //创建着色器            RadialGradient gradient = new RadialGradient(r, r,                    r, color, darkColor, Shader.TileMode.CLAMP);            //设置着色器            paint.setShader(gradient);            //设置绘图对象区域            //注意,在android中(0,0,150,1)表示一条x轴范围为0-149,y=0的直线;并不像有些语言            //的实现,有些语言中(0,0,150,1)表示一个矩形,X范围:0-150,Y范围0-1。            drawable.setBounds(0, 0, (int)diameter, (int)diameter);                        return drawable;        }                /**         * 将球移动到指定位置         * @param x 球的最左边X坐标,不是中心X坐标         * @param y 球的最上边Y坐标,不是中心Y坐标         */        public void move(int x, int y) {            Rect rectOld = this.mBall.getBounds();            Rect rectNew = new Rect(rectOld);                        int relativeX = x - rectOld.left;            int relativeY = y - rectOld.top;                        rectNew.left = rectNew.left + relativeX;            rectNew.right = rectNew.right + relativeX;            rectNew.top = rectNew.top + relativeY;            rectNew.bottom = rectNew.bottom + relativeY;                        this.mBall.setBounds(rectNew);        }                /**         * 在给定的画布上画球         * @param canvas 画布         */        public void draw(Canvas canvas) {            this.mBall.draw(canvas);        }    }    }



运行效果:




源代码下载:http://dom4j-android.googlecode.com/files/Draw2D.zip

参考的资料:

1.API Demo:com.example.android.apis.animation.AnimationCloning.java

2.http://developer.android.com/guide/topics/graphics/overview.html

更多相关文章

  1. android之线程访问网络并解析数据
  2. Android TextView 个别文字字体颜色格式
  3. [Android] 任意时刻从子线程切换到主线程的实现
  4. Android 线程的使用(传递多个参数)
  5. android handler 线程机制的研究
  6. Android Audio代码分析21 - 创建AudioEffect对象
  7. 点击listitem按下效果替换默认颜色
  8. Android Training精要(六)如何防止Bitmap对象出现OOM
  9. android listview 与 一般多线程配合产生的错误,资料汇总

随机推荐

  1. linux环境下写C++操作mysql(二)
  2. Linux生成随机字符串
  3. 在VNC远程桌面环境Xfce4中Tab键失效的解
  4. Linux防火墙配置
  5. Shell脚本编写简明教程
  6. 手把手教你在ubuntu下创建桌面快捷方式
  7. 在Linux里设置用户环境变量的方法
  8. 来点基础的--诡异的极客们的符号--流、管
  9. Linux Box上运行哪个SQL服务器?
  10. linux中创建公私钥