今天是尝试開始Android版2048小游戏的第二天。在今天,我主要学习了怎样获取用户在屏幕滑动的手势,以及对布局进行了一些小小的完好。

获取用户操作的手势(比方向左滑。向右滑等)主要用到了GestureDetector。这个类能够帮助我们获取一些常见的用户对屏幕的操作。比如单击、双击、按压、拖动等。详细的使用说明。大家能够查API也能够去百度,或者看我之前有一篇使用GestureDetector实现的小样例(http://blog.csdn.net/xiapinnong/article/details/21970419)在这里就不多说了。

以下还是看代码吧。相对与第一篇,我在代码中主要增加一个内部类MygestureDetector。而且让这个类实现了OnTouchListener和OnGestureListener这两个接口。

当中OnTouchListener这个接口主要用来为我的GridLayout绑定对touch这个动作的监听,然后将详细的动作传递到GestureDetector。通过将用户详细的操作相应到不同的手势上。

	public class MygestureDetector implements OnGestureListener,OnTouchListener{

		@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return gd.onTouchEvent(event);
} @Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { // 參数解释:
// e1:第1个ACTION_DOWN MotionEvent
// e2:最后一个ACTION_MOVE MotionEvent
// velocityX:X轴上的移动速度,像素/秒
// velocityY:Y轴上的移动速度。像素/秒 // 触发条件 :
// X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 if(e1.getX()-e2.getX()>100){
System.out.println("向左");
return true;
}else if(e1.getX()-e2.getX()<-100){
System.out.println("向右");
return true;
}else if(e1.getY()-e2.getY()>100){
System.out.println("向上");
return true;
}else if(e1.getY()-e2.getY()<-00){
System.out.println("向下");
return true;
}
return false;
} @Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
return false;
} @Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
} }

onFiling()这个回调函数主要是指用户点击屏幕,并移动一小段距离。然后放开。

这种方法里的四个參数:

e1是指: 第1个ACTION_DOWN MotionEvent

e2是指:  最后一个ACTION_MOVE MotionEvent

velocityX:X轴上的移动速度,像素/秒

velocityY:Y轴上的移动速度。像素/秒

(其他回调函数和參数的说明,能够參考这篇博客http://blog.csdn.net/xiapinnong/article/details/21970419

推断用户手指滑动的方向:

通过比較e1和e2这两个MotinEvent的坐标来计算的

比方e1的x坐标减去e2的x坐标大于零。说明用户的手指是向左滑动的

然后我们须要声明并初始化一个GestureDetector相应,并传入我们的MygestureDetector的对象,然后为我们的GridLayout绑定onTouchListener

完整的Activity代码例如以下:

package com.example.t2048;

import java.util.ArrayList;
import java.util.List;
import java.util.Random; import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridLayout;
import android.widget.ImageView; public class MainActivity extends Activity { GridLayout gridLayout = null; //用于保存空格的位置
List<Integer> spaceList = new ArrayList<Integer>();
//用于保存有数字格的位置
List<Integer> stuffList = new ArrayList<Integer>(); GestureDetector gd = null; /**
* 图标数组
*/
private final int[] icons = { R.drawable.but_empty, R.drawable.but2,
R.drawable.but4, R.drawable.but8, R.drawable.but16,
R.drawable.but32, R.drawable.but64, R.drawable.but128,
R.drawable.but256, R.drawable.but512, R.drawable.but1024,
R.drawable.but2048, R.drawable.but4096 }; protected void onCreate(Bundle savedInstanceState) {
System.out.println("程序启动");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); gridLayout = (GridLayout) findViewById(R.id.GridLayout1);
init(); MygestureDetector mg = new MygestureDetector(); gd = new GestureDetector(mg);
gridLayout.setOnTouchListener(mg);
gridLayout.setLongClickable(true); } //初始化界面
public void init(){
System.out.println("初始化"); //首先在16个各种都填上空白的图片
for(int i=0;i<16;i++){
View view = View.inflate(this, R.layout.item, null);
ImageView image = (ImageView) view.findViewById(R.id.image); image.setBackgroundResource(icons[0]);
spaceList.add(i);
gridLayout.addView(view);
} //在界面中随机增加两个2或者4
addRandomItem();
addRandomItem();
} //从空格列表中随机获取位置
public int getRandomIndex(){
Random random = new Random();
if(spaceList.size()>0)
return random.nextInt(spaceList.size());
else
return -1;
} //在空白格中随机增加数字2
public void addRandomItem(){
int index = getRandomIndex();
if(index!=-1){
//获取相应坐标所相应的View
View view = gridLayout.getChildAt(spaceList.get(index));
ImageView image = (ImageView) view.findViewById(R.id.image);
//随机生成数字1或2
int i = (int) Math.round(Math.random()+1);
//将当前格子的图片置换为2或者4
image.setBackgroundResource(icons[i]);
//在空白列表中去掉这个格子
spaceList.remove(index);
}
} public class MygestureDetector implements OnGestureListener,OnTouchListener{ @Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return gd.onTouchEvent(event);
} @Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return false;
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { // 參数解释:
// e1:第1个ACTION_DOWN MotionEvent
// e2:最后一个ACTION_MOVE MotionEvent
// velocityX:X轴上的移动速度,像素/秒
// velocityY:Y轴上的移动速度。像素/秒 // 触发条件 :
// X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 if(e1.getX()-e2.getX()>100){
System.out.println("向左");
return true;
}else if(e1.getX()-e2.getX()<-100){
System.out.println("向右");
return true;
}else if(e1.getY()-e2.getY()>100){
System.out.println("向上");
return true;
}else if(e1.getY()-e2.getY()<-00){
System.out.println("向下");
return true;
}
return false;
} @Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// TODO Auto-generated method stub
return false;
} @Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub } @Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
} } public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

程序执行界面例如以下(界面比較难看):

用手指在GridLayout上滑动,在Log中能够打印出详细的滑动方向

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhcGlubm9uZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">

从零開始开发Android版2048 (二)获取手势信息的更多相关文章

  1. 从零開始开发Android版2048 (一)初始化界面

    自学Android一个月多了,一直在工作之余零零散散地看一些东西.感觉经常使用的东西都有些了解了,可是一開始写代码总会出各种奇葩的问题.感觉还是代码写得太少.这样继续杂乱地学习下去进度也太慢了,并且学 ...

  2. 从零開始开发Android版2048 (四) 分数、重置、结束

    这一篇的内容主要是在上一篇的基础上,增加分数计算(包含当前分数和最高分数).游戏结束的推断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存          首先,2048这个游戏的分数包含 ...

  3. 从零開始开发Android版2048 (三)逻辑推断

    近期工作比較忙,所以更新的慢了一点,今天的主要内容是关于Android版2048的逻辑推断,经过本篇的解说,基本上完毕了这个游戏的主体部分. 首先还是看一下,我在实现2048时用到的一些存储的数据结构 ...

  4. 从零開始开发Android版2048 (五) 撤销的实现

    本篇的内容是,在前一篇的基础上添�了撤销的功能.撤销事实上就是将当前的用户界面恢复到这次滑动值前的样子.我实现撤销的主要原理是,将每次滑动后界面上的格子和相应的数字记录下来,当然还有分数,把这些数据写 ...

  5. 从零開始学android&lt;TabHost标签组件.二十九.&gt;

    TabHost主要特点是能够在一个窗体中显示多组标签栏的内容,在Android系统之中每一个标签栏就称为一个Tab.而包括这多个标签栏的容器就将其称为TabHost.TabHost类的继承结构例如以下 ...

  6. 第13章、布局Layouts之RelativeLayout相对布局(从零開始学Android)

    RelativeLayout相对布局 RelativeLayout是一种相对布局,控件的位置是依照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最经常使用,也是最灵活的一种布 ...

  7. 从零開始学android&lt;SeekBar滑动组件.二十二.&gt;

    拖动条能够由用户自己进行手工的调节,比如:当用户须要调整播放器音量或者是电影的播放进度时都会使用到拖动条,SeekBar类的定义结构例如以下所看到的: java.lang.Object    ↳ an ...

  8. 从零開始学android&lt;数据存储(1)SharedPreferences属性文件.三十五.&gt;

    在android中有五种保存数据的方法.各自是: Shared Preferences Store private primitive data in key-value pairs. 相应属性的键值 ...

  9. 从零開始学android&lt;mediaplayer自带播放器(视频播放).四十九.&gt;

    MediaPlayer除了能够对音频播放之外,也能够对视频进行播放,可是假设要播放视频仅仅依靠MediaPlayer还是不够的.还须要编写一个能够用于视频显示的空间,而这块显示空间要求能够高速的进行G ...

随机推荐

  1. TensorFlow——小练习:counter

    下面的例子演示了如何使用变量实现一个 简单的计数器(counter) # _*_coding:utf-8_*_ import tensorflow as tf import numpy as np # ...

  2. [linux time命令学习篇] time 统计命令执行的时间

    注意: 命令后面一定要有分号; http://codingstandards.iteye.com/blog/798788 用途说明 time命令常用于测量一个命令的运行时间,注意不是用来显示和修改系统 ...

  3. 【Luogu】P2057善意的投票(最小割转最大流)

    题目链接 也算水题一道吧,不过Round1感性理解一下就xjb建了个图,40 Round2仔细分析了一会,理性建了个图,90 然后分析了半天……改大数组就A了…… 从S到所有值为1的点连一条inf的边 ...

  4. BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树

    同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...

  5. [USACO13JAN] Cow Lineup (单调队列,尺取法)

    题目链接 Solution 尺取法板子,算是复习一波. 题中说最多删除 \(k\) 种,那么其实就是找一个颜色种类最多为 \(k+1\) 的区间; 统计一下其中最多的颜色出现次数. 然后直接尺取法,然 ...

  6. 【bzoj1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 SA+二分

    Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质 ...

  7. mod性质 学习笔记

    mod性质小结 \(a\equiv b(\mod m)\) $ \rightarrow \( \)a-b=k*m,k\in Z$ \(a\equiv b且c\equiv d(\mod m)\) \(\ ...

  8. 【bzoj4031】[HEOI2015]小Z的房间 && 【bzoj4894】天赋 (矩阵树定理)

    来两道矩阵树模板: T1:[bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形 ...

  9. LOJ#2303. 「NOI2017」蚯蚓排队

    $n \leq 200000$的$1 \leq a_i \leq 6$的蚯蚓,有三种操作:让一只队头蚯蚓接在一只队尾蚯蚓后面:让一队蚯蚓从某个蚯蚓后面断成两队:问:给个字符串,问他的..算了你们直接看 ...

  10. MySQL 5.7.17绿色版安装

    下载地址 :https://dev.mysql.com/downloads/mysql/   ,需要oracle帐号 下载  Windows (x86, 64-bit), ZIP Archive 是个 ...