闲来无聊结合上片surfaceView基础篇,再次改进成一款简易抓球小游戏哦。
圆球随机不停出现在屏幕,你像让他停住吗?那你就去用力抓拄他吧!
通过这个游戏可以进一步了解surfaceView与MotionEvent事件的实现
补充点 :
在android 中使用触摸屏 在模拟机中 我们的鼠标当点击一次模拟器屏幕然后释放,先触发 ACTION_DOWN 然后 ACTION_UP ;如果是在屏幕上移动那么才会触发 ACTION_MOVE 的动作;这个很正常, 但在真机中呢 ,是不是 也是这样的呢 ?答案是否定的如果我们那真机测试的话 流程如下
先触发 ACTION_DOWN 如果手指不抬起的话 会一直触发ACTION_MOVE事件(就是不移动也会触发)然后 ACTION_UP
原因有两点:第一点是因为,Android 对于触屏事件很敏感!第二点:虽然我们的手指感觉是静止没有移动,其实事实不是如此!当我们的手指触摸到手机屏幕上之后,感觉静止没动,其实手指在不停的微颤抖震动。 所以才会一直触发action_move事件
先上图
两java类文件:activity、view
package com.logan.androidtest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import com.logan.androidtest.view.GameSurfaceView;
/**
*
* @author xuan.lx
*
*/
public class GameSurfaceViewActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//GameSurfaceView2 view = new GameSurfaceView2(this);
GameSurfaceView view = new GameSurfaceView(this);
//没有标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏显示
//设置自定义的view
setContentView(view);
//获取屏幕高宽
view.height = getWindowManager().getDefaultDisplay().getHeight();
view.width = getWindowManager().getDefaultDisplay().getWidth();
}
}
package com.logan.androidtest.view;
import java.util.Random;
/**
*
* @author xuan.lx
*
*/
public class GameSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
//屏幕的宽、高
public static int height = 0;
public static int width = 0;
//随机生成的x、y坐标
public volatile static Integer randomY = 0;
public volatile static Integer randomX = 0;
//x、y平方数
private double powX = 0;
private double powY = 0;
//半径
private static float radius = 60;
//距圆心的距离
double distance = 0;
//当前点击的x、y坐标
public volatile static Integer currentY = 0;
public volatile static Integer currentX = 0;
SurfaceView surfaceView;
SurfaceHolder sfh;
int miCount = 0;
static Random random = new Random(47);
// 控制循环
volatile static Boolean isLoop = true;
volatile static Boolean isStop = false;
public GameSurfaceView(Context context) {
super(context);
sfh = this.getHolder();// 获取holder
sfh.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isLoop = true;
isStop = false;
new DrawImage().start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止循环
isLoop = false;
}
/**
* 绘图线程
*/
class DrawImage extends Thread {
public void run() {
while (isLoop) {
if (!isStop) {
randomXY();
synchronized (sfh) {
if (!isStop) {
draw(randomX, randomY);
}
}
}
}
}
public void randomXY() {
if (!isStop) {
Log.e(VIEW_LOG_TAG, "before randomX:" + randomX + " randomY:"
+ randomY);
randomX = random.nextInt(width);
try {
Thread.sleep(random.nextInt(2000));
} catch (Exception e) {
Thread.currentThread().interrupt();
Log.e(VIEW_LOG_TAG, "randomXY Exception");
}
randomY = random.nextInt(height);
Log.e(VIEW_LOG_TAG, "Drawdone randomX:" + randomX + " randomY:"
+ randomY);
}
}
// 绘图方法
public void draw(Integer x, Integer y) {
// 锁定画布,得到canvas
Canvas canvas = sfh.lockCanvas();
if (sfh == null || canvas == null) {
return;
}
currentX = x;
currentY = y;
if (miCount < 100) {
miCount++;
} else {
miCount = 0;
}
// 绘图
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
// 绘制矩形--清屏作用
canvas.drawColor(Color.LTGRAY);
switch (miCount % 4) {
case 0:
mPaint.setColor(Color.BLUE);
break;
case 1:
mPaint.setColor(Color.GREEN);
break;
case 2:
mPaint.setColor(Color.RED);
break;
case 3:
mPaint.setColor(Color.YELLOW);
break;
default:
mPaint.setColor(Color.WHITE);
break;
}
canvas.drawCircle(x, y, radius, mPaint);
// 绘制后解锁,绘制后必须解锁才能显示
sfh.unlockCanvasAndPost(canvas);
}
}
// 触摸事件
public boolean onTouchEvent(MotionEvent event) {
Log.e(VIEW_LOG_TAG, "MotionEvent start ");
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// x,y 的平方数,求距离
powX = Math.pow(Math.abs(event.getX() - currentX), 2);
powY = Math.pow(Math.abs(event.getY() - currentY), 2);
distance = Math.sqrt(powX + powY);
Log.e(VIEW_LOG_TAG, "distance's : " + distance);
if (distance <= radius) {
isStop = true;
}
break;
case MotionEvent.ACTION_UP:
isStop = false;
break;
case MotionEvent.ACTION_MOVE://在实际真机中一定会触发move事件所以这个是不可以不写的
// x,y 的平方数,求距离
powX = Math.pow(Math.abs(event.getX() - currentX), 2);
powY = Math.pow(Math.abs(event.getY() - currentY), 2);
distance = Math.sqrt(powX + powY);
if (distance <= radius) {
isStop = true;
}
break;
}
Log.e(VIEW_LOG_TAG, "onTouchEvent:isStop = " + isStop);
return true;
}
}
以上就是一个简易的抓球(名字自取的),加上背景和音乐、计数估计就好玩点!