从零開始开发Android版2048 (二)获取手势信息
今天是尝试開始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 (二)获取手势信息的更多相关文章
- 从零開始开发Android版2048 (一)初始化界面
自学Android一个月多了,一直在工作之余零零散散地看一些东西.感觉经常使用的东西都有些了解了,可是一開始写代码总会出各种奇葩的问题.感觉还是代码写得太少.这样继续杂乱地学习下去进度也太慢了,并且学 ...
- 从零開始开发Android版2048 (四) 分数、重置、结束
这一篇的内容主要是在上一篇的基础上,增加分数计算(包含当前分数和最高分数).游戏结束的推断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存 首先,2048这个游戏的分数包含 ...
- 从零開始开发Android版2048 (三)逻辑推断
近期工作比較忙,所以更新的慢了一点,今天的主要内容是关于Android版2048的逻辑推断,经过本篇的解说,基本上完毕了这个游戏的主体部分. 首先还是看一下,我在实现2048时用到的一些存储的数据结构 ...
- 从零開始开发Android版2048 (五) 撤销的实现
本篇的内容是,在前一篇的基础上添�了撤销的功能.撤销事实上就是将当前的用户界面恢复到这次滑动值前的样子.我实现撤销的主要原理是,将每次滑动后界面上的格子和相应的数字记录下来,当然还有分数,把这些数据写 ...
- 从零開始学android<TabHost标签组件.二十九.>
TabHost主要特点是能够在一个窗体中显示多组标签栏的内容,在Android系统之中每一个标签栏就称为一个Tab.而包括这多个标签栏的容器就将其称为TabHost.TabHost类的继承结构例如以下 ...
- 第13章、布局Layouts之RelativeLayout相对布局(从零開始学Android)
RelativeLayout相对布局 RelativeLayout是一种相对布局,控件的位置是依照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最经常使用,也是最灵活的一种布 ...
- 从零開始学android<SeekBar滑动组件.二十二.>
拖动条能够由用户自己进行手工的调节,比如:当用户须要调整播放器音量或者是电影的播放进度时都会使用到拖动条,SeekBar类的定义结构例如以下所看到的: java.lang.Object ↳ an ...
- 从零開始学android<数据存储(1)SharedPreferences属性文件.三十五.>
在android中有五种保存数据的方法.各自是: Shared Preferences Store private primitive data in key-value pairs. 相应属性的键值 ...
- 从零開始学android<mediaplayer自带播放器(视频播放).四十九.>
MediaPlayer除了能够对音频播放之外,也能够对视频进行播放,可是假设要播放视频仅仅依靠MediaPlayer还是不够的.还须要编写一个能够用于视频显示的空间,而这块显示空间要求能够高速的进行G ...
随机推荐
- STW Family
序言 一次作业致使我们成为了一个团体,相聚即是缘分,让我们一起为STW绘制一幅完美的画卷,交一份满意的答卷. 这不是一个人的王者,是团队的荣耀. Team成员 队长:王筱哲 201631062220 ...
- selenium - 常用等待操作
# 4. 等待操作 # 强制等待from time import sleepsleep(10) # 隐性等待# 设置最长等待时间,在这个时间在只要有个时间点加载完成,则执行下一步代码,比sleep智能 ...
- 使用mysql监视器即命令行下的mysql
命令行下登录mysql 首先必须在alias下有设置mysql, 我的mysql安装的位置在/usr/local/mysql 于是做了一个别名: alias mysql='/usr/local/mys ...
- Learning Deconvolution Network for Semantic Segme小结
题目:Learning Deconvolution Network for Semantic Segmentation 作者:Hyeonwoo Noh, Seunghoon Hong, Bohyung ...
- 安装adb工包
下载android sdk (很大) 从D:\AndroidSdk\platform-tools目录可以看到: 将adb工具包: adb.exe,AdbWinapi.dll,AdbWinUSBapi. ...
- 九度oj 题目1355:扑克牌顺子
题目描述: LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他 ...
- 二进制<3>
Matrix67:位运算简介及实用技巧(三) 进阶篇(2) (2010-07-27 11:10:44) 转载▼ 标签: it 分类: 老贾·OI相关 n皇后问题位运算版 n皇后问题是啥我就不说了 ...
- 刷题总结——松鼠的新家(bzoj3631)
题目: Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上. ...
- UVa11424 GCD - Extreme (I)
直接两重循环O(n^2)算gcd……未免太耗时 枚举因数a和a的倍数n,考虑gcd(i,n)==a的i数量(i<=n) 由于gcd(i,n)==a等价于gcd(i/a,n/a)==1,所以满足g ...
- 【MFC】利用单一对话框内的分页技术实现向导功能(转)
原文转自 http://blog.csdn.net/yongh701/article/details/43793151 所谓的向导功能,在win32的程序中常常见于安装程序或者程序内的设置向导,该向导 ...