Android快乐贪吃蛇游戏实战项目开发教程-04虚拟方向键(三)三角形按钮效果

该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html

一、知识点讲解

当我们点击系统自带的按钮时,按钮的外观会发生变化。上篇博文中我们画了一个三角形按钮,但点击还不能变色,下面我们就来实现点击变色功能。

从知识体系上我们需要了解以下两个知识点

  • 1.如何知道手指点击了我们的控件?

办法是重写View中的onTouchEvent方法。当手指触摸到我们的控件时,系统会通过该方法告诉我们。该方法还有一个类型为MotionEvent的参数,通过该参数我们就能知道当前触摸事件的具体类型,比如按下、移动、抬起等。
我们可以让按钮在正常情况下显示一个较暗的颜色,按下时显示一个较亮的颜色,抬起后再恢复到较暗的颜色。这样就实现了点击变色的效果了。

  • 2.如何变色?

View中提供了一个叫invalidate的方法,每次调用该方法,系统都会重新调用onDraw方法来重绘本控件。我们要做的就是在onDraw中判断当前的触摸动作,如果是按下就画一个高亮的三角形,没有触摸或按下抬起后就画一个较暗的三角形。

了解了相关的知识点,下面我们就通过代码来实现。

二、代码实现

以下是当前DirectionKeys类的全部代码:

package net.chengyujia.happysnake;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by ChengYuJia on 2016/8/19.
 * 屏幕上的虚拟方向键
 */
public class DirectionKeys extends View {
    //左三角形按压时的颜色(较亮)
    private int leftPressedColor = 0xFFFF0000;
    //左三角形正常显示的颜色(较暗)
    private int leftNormalColor = 0xFFAA0000;
    //手触摸屏幕的动作,初始值用一个MotionEvent中没有用到的action值,比如-10,表示还没有任何触屏动作发生。
    private int action = -10;
    //画布的宽
    private int width;
    //画布的高
    private int height;
    //画左三角形的路径
    private Path pathLeft = new Path();
    //画笔
    private Paint paint = new Paint();
    //初始化方法是否执行过,确保初始化方法只执行一次。
    private boolean initDone = false;

    //只有一个参数的构造方法是我们在程序中通过“new”关键字创建实例时调用。
    public DirectionKeys(Context context) {
        super(context);
    }

    //有两个参数的构造方法是系统在XML布局文件中创建实例时调用。
    public DirectionKeys(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //初始化方法
    private void init(Canvas canvas) {
        /*获取画布的长和宽*/
        width = canvas.getWidth();
        height = canvas.getHeight();
        /*
        (小提示:在计算机中一般都是将左上角作为坐标原点的)
        画布上四个顶点和中心点的坐标如下:
        左上点 0,0
        左下点 0,height
        右上点 width,0
        右下点 width,height
        中心点 width/2,height/2
        */

        /*设置左三角形的路径数据*/
        //从画布左上点开始
        pathLeft.moveTo(0, 0);
        //画直线到画布中心点
        pathLeft.lineTo(width / 2, height / 2);
        //再画直线到画布左下点
        pathLeft.lineTo(0, height);
        //自动闭合图形。从最后一个点(左下点)画直线到第一个点(左上点)。
        pathLeft.close();
    }

    /**
     * 通过重写父类的onDraw方法来绘制我们需要的图形
     * 该方法会在控件第一次显示时被系统调用,并在之后每次调用invalidate方法后被系统调用。
     *
     * @param canvas 这里的canvas是系统提供的一块矩形画布,我们要做的就是在这块画布上画我们想要的东西。
     */
    @Override
    protected void onDraw(Canvas canvas) {
        if (!initDone) {
            init(canvas);
            //确保初始化方法只执行一次
            initDone = true;
        }

        if (action == MotionEvent.ACTION_DOWN) {
            //手按压时高亮显示
            paint.setColor(leftPressedColor);
        } else {
            //没有按或按下抬起后显示较暗的颜色
            paint.setColor(leftNormalColor);
        }
        //画左三角形
        canvas.drawPath(pathLeft, paint);
    }

    /**
     * 如果手触摸到我们的控件,系统会通过该方法告诉我们
     *
     * @param event 系统给我们传递的触摸事件参数
     * @return 如果该触摸事件被我们处理了返回true,反之返回false。
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        action = event.getAction();
        //ACTION_DOWN表示手按到屏幕,ACTION_UP表示手从屏幕上抬起。我们只处理这两种动作。
        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
            //invalidate方法是告诉系统当前控件需要重绘,系统会再次调用onDraw方法来实现重绘。
            invalidate();
            return true;
        }
        return false;
    }
}

 

上面注释比较详细,主要就3个方法onDraw(绘图)、onTouchEvent(监听触摸事件)、invalidate(让系统调用onDraw方法实现重绘)。

另外Path对象和Paint对象只要初始化一次就可以了,没必要每次onDraw的时候重新创建,提高程序性能。

三、运行效果

正常时显示暗色:

按下时显示亮色:

测试的时候会发现,点击非三角形区域也会变色,这因为我们还没有对点击的位置做判断,这个会在后面讲解。

先到这里,下文继续。:)

posted @ 2016-08-21 12:59  成宇佳  阅读(1817)  评论(0编辑  收藏  举报