canvas教程

Android欢乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮

字号+ 作者:H5之家 来源:H5之家 2016-08-29 18:04 我要评论( )

Android快乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一、如何

当前位置:我的异常网» Android » Android欢乐贪吃蛇游戏实战项目开发教程-05虚拟方向

Android欢乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮

  网友分享于:2013-08-29  浏览:0次

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

该系列教程概述与目录:

一、如何判断点击的是哪个方向键按钮

在上篇教程中我们实现了左边的三角形按钮效果,本篇教程我们将左、上、右、下四个三角形按钮都一起实现了。
能做出一个来,另外三个应该不难了吧?但实际并非怎么简单哦。
首先我们来解决一下上节课遗留的一个问题,如何判断当前手指点击的是哪个三角形按钮?


这个需要用解析几何大法来解决。
假设我们的控件是边长为1的正方形,建立平面直角坐标系(注意:计算机中坐标系原点在左上角哦),如下图:


正方形的对角线将控件分成了4个三角形区域,也就是我们的4个方向键按钮。

据上图可知:
左上角到右下角对角线的方程为y=x;
    y>x的区域包含左和下三角形
    y<x的区域包含右和上三角形

右上角到左下角的对角线方程为y=-x+1;
    y>1-x的区域包含右和下三角形
    y<1-x的区域包含左和上三角形

综上可得:
    y>x 且 y<1-x 表示左三角
    y<x 且 y<1-x 表示上三角
    y<x 且 y>1-x 表示右三角
    y>x 且 y>1-x 表示下三角

以上是按照边长为1的正方形得到的结论,但实际中,我们的控件不一定是正方形,边长也不是1,而是一个不确定的矩形,这该怎么办呢?
这就需要经过一定的转换,将普通的矩形转换为边长为1的正方形。
这个转变也简单,如下:
设画布上被触摸到的点的坐标为(x,y),则:

relativeY = y / height;//0<=relativeY<=1

我们将画布上被触摸的点的横纵坐标分别除以画布的宽和高,这样就得到了一个相对坐标,而这个相对坐标的取值一定在0到1之间。这样就相当于把一个不确定的矩形简化成了一个边长为1的正方形处理。

二、程序代码

有了上面的了解,下面就可以写代码了。由于有4个三角形按钮,而每个按钮又有两种状态,代码会稍微长点。但每个按钮的逻辑都是一样的,都是按哪个那个高亮,不按时都恢复正常状态。代码中的注释比较详细,相信大家如果看了前面的教程内容,看这个应该问题不大。唯一需要注意的是每次调用invalidate方法重绘界面时,是需要对整个画布都重绘的,而不能只重绘一个三角形。

这里我们需要先引入一个表示方向的枚举:Direction

package net.chengyujia.happysnake; /** * 用来表示方向的枚举 * Created by ChengYuJia on 2016/8/21. Direction { //none表示没有方向键按下 none, // left, // up, // right, // down; }

 
下面是当前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. DirectionKeys extends View { leftPressedColor = 0xFFFF0000; leftNormalColor = 0xFFAA0000; upPressedColor = 0xFF00FF00; upNormalColor = 0xFF00AA00; rightPressedColor = 0xFF0000FF; rightNormalColor = 0xFF0000AA; downPressedColor = 0xFFFFFF00; downNormalColor = 0xFFAAAA00; Paint paint = new Paint(); Path pathLeft = new Path(); Path pathUp = new Path(); Path pathRight = new Path(); Path pathDown = new Path(); width; height; initDone = false; Direction currentDirection = Direction.none; DirectionKeys(Context context) { super(context); } DirectionKeys(Context context, AttributeSet attrs) { super(context, attrs); } 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(); pathUp.moveTo(0, 0); pathUp.lineTo(width / 2, height / 2); pathUp.lineTo(width, 0); pathUp.close(); pathRight.moveTo(width, 0); pathRight.lineTo(width / 2, height / 2); pathRight.lineTo(width, height); pathRight.close(); pathDown.moveTo(width, height); pathDown.lineTo(width / 2, height / 2); pathDown.lineTo(0, height); pathDown.close(); } drawPath(Path path, int color, Canvas canvas) { //设置画笔颜色 paint.setColor(color); //用画笔在画布上按照路径数据画出图形 canvas.drawPath(path, paint); } drawLeftNormal(Canvas canvas) { drawPath(pathLeft, leftNormalColor, canvas); } drawLeftPressed(Canvas canvas) { drawPath(pathLeft, leftPressedColor, canvas); } drawUpNormal(Canvas canvas) { drawPath(pathUp, upNormalColor, canvas); } drawUpPressed(Canvas canvas) { drawPath(pathUp, upPressedColor, canvas); } drawRightNormal(Canvas canvas) { drawPath(pathRight, rightNormalColor, canvas); } drawRightPressed(Canvas canvas) { drawPath(pathRight, rightPressedColor, canvas); } drawDownNormal(Canvas canvas) { drawPath(pathDown, downNormalColor, canvas); } drawDownPressed(Canvas canvas) { drawPath(pathDown, downPressedColor, canvas); } reset(Canvas canvas) { drawLeftNormal(canvas); drawUpNormal(canvas); drawRightNormal(canvas); drawDownNormal(canvas); } drawWhenLeftPressed(Canvas canvas) { drawLeftPressed(canvas); drawUpNormal(canvas); drawRightNormal(canvas); drawDownNormal(canvas); } drawWhenUpPressed(Canvas canvas) { drawLeftNormal(canvas); drawUpPressed(canvas); drawRightNormal(canvas); drawDownNormal(canvas); } drawWhenRightPressed(Canvas canvas) { drawLeftNormal(canvas); drawUpNormal(canvas); drawRightPressed(canvas); drawDownNormal(canvas); } drawWhenDownPressed(Canvas canvas) { drawLeftNormal(canvas); drawUpNormal(canvas); drawRightNormal(canvas); drawDownPressed(canvas); } /** * 通过重写父类的onDraw方法来绘制我们需要的图形 * 该方法会在控件第一次显示时被系统调用,并在之后每次调用invalidate方法后被系统调用。 * * @param canvas 这里的canvas是系统提供的一块矩形画布,我们要做的就是在这块画布上画我们想要的东西。 */ @Override protected void onDraw(Canvas canvas) { if (!initDone) { init(canvas); //确保初始化方法只执行一次 initDone = true; } (currentDirection) { case left://按下左键时 drawWhenLeftPressed(canvas); break; case up://按下上键时 drawWhenUpPressed(canvas); break; case right://按下右键时 drawWhenRightPressed(canvas); break; case down://按下下键时 drawWhenDownPressed(canvas); break; default://其它情况 reset(canvas); } } /** * 当用户触摸到该控件时,系统通过该方法告诉控件“你被摸了,要不要有反应啊?有反应返回true,没反应返回false。” * 控件说“那要看是怎么摸的了。如果是按下,我就将对应的三角形按键高亮显示;如果是抬起,我就将所有的三角形按键恢复成正常的颜色。其它情况我就不反应了,摸就摸吧。” * * @param event 系统给我们传递的触摸事件参数 * @return 如果该触摸事件被我们处理了返回true,反之返回false。 */ @Override public boolean onTouchEvent(MotionEvent event) { action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) {//按下 x = event.getX(); float y = event.getY(); currentDirection = getDirection(x, y); invalidate();; } currentDirection = Direction.none; invalidate();; } ; } } Direction getDirection(float x, float y) { relativeX = x / width;relativeY = y / height; 注意:原点是左上角。 左上角到右下角对角线方程为y=x; 则: y>x的区域包含左和下三角形 y<x的区域包含右和上三角形 左下角到右上角对角线方程为y=-x+1; 则: y>1-x的区域包含右和下三角形 y<1-x的区域包含左和上三角形 综上可得: y>x 且 y<1-x 表示左三角 y<x 且 y<1-x 表示上三角 y<x 且 y>1-x 表示右三角 y>x 且 y>1-x 表示下三角 (relativeY < 1 - relativeX) { Direction.left; } Direction.down; } } (relativeY < 1 - relativeX) { Direction.up; } Direction.right; } } } }

 

三、运行效果

没有点击时的效果:

 

点击左键时的效果:

 

点击上建时的效果:

 

点击右键时的效果:

 

点击下键时的效果:

 

到这里,我们的自定义方向键的4个背景三角形已经做好了,而且实现了点击变色的按钮效果。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
网友点评