接下来咱们就要实现点击事件了
首先我们要先找到空白的那个控件
代码如下
/**
* 定义空白ImageView控件获取空白ImageView下标
*
* @return 空白ImageView的下标
*/
public int FindZero() {
for (int i = 0; i < 9; i++) {
if (number[i] == R.drawable.nulls) {
return i;
}
}
return 0;
}
接着就可以利用这个空白控件来控制移动了
向左
/**
* 向左滑动一个ImageView
*/
protected void left() {
int numzero = FindZero();
int exchanged;
// 如果空白ImageView的下标不是0,3,6,它右边的ImageView 与它互换位置
if (!(numzero % 3 == 0)) {
exchanged = number[numzero];
number[numzero] = number[numzero - 1];
number[numzero - 1] = exchanged;
socer += 1;
tv2.setText("当前移动了 " + String.valueOf(socer) + " 步");
}
}
向右
/**
* 向右滑动一个ImageView
*
*/
protected void right() {
int numzero = FindZero();
int exchanged;
// 如果空白ImageView的下标不是2,5,8,它左边的ImageView 与它互换位置
if (!(numzero % 3 == 2)) {
exchanged = number[numzero];
number[numzero] = number[numzero + 1];
number[numzero + 1] = exchanged;
socer += 1;
tv2.setText("当前移动了 " + String.valueOf(socer) + " 步");
}
}
向上
/**
* 向上滑动一个ImageView
*/
protected void up() {
int numzero = FindZero();
int exchanged;
// 如果空白ImageView的下标不是6,7,8,它上边的ImageView 与它互换位置
if (!(numzero > 5)) {
exchanged = number[numzero];
number[numzero] = number[numzero + 3];
number[numzero + 3] = exchanged;
socer += 1;
tv2.setText("当前移动了 " + String.valueOf(socer) + " 步");
}
}
向下
/**
* 向下滑动一个ImageView
*/
protected void down() {
int numzero = FindZero();
int exchanged;
// 如果空白ImageView的下标不是0,1,2,它上边的ImageView 与它互换位置
if (!(numzero < 3)) {
exchanged = number[numzero];
number[numzero] = number[numzero - 3];
number[numzero - 3] = exchanged;
socer += 1;
tv2.setText("当前移动了 " + String.valueOf(socer) + " 步");
}
}
然后就可以使用onTouch事件来判定手指滑动的方向了,从而来控制图片的移动的方向了
/**
* 触摸监听,确定移动方向
*/
private void touchEvent() {
// TODO Auto-generated method stub
// 设置触摸监听
ll.setOnTouchListener(new OnTouchListener() {
private int x1, x2;
private int y1, y2;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
// 单点触摸按下时,即点击 获取坐标(x1,y1)
case MotionEvent.ACTION_DOWN:
x1 = (int) event.getX();
y1 = (int) event.getY();
break;
// 单点触摸抬起时,即点击 获取坐标(x2,y2)
case MotionEvent.ACTION_UP:
x2 = (int) event.getX();
y2 = (int) event.getY();
// 根据按下和抬起触摸屏幕的坐标判定图片滑动方向
// Y坐标差大于X坐标,上下运动
if (y2 - y1 > Math.abs(x2 - x1) && y2 - y1 > 20) {
System.out.println("下");
down();
GameOver();
initGame();
} else if (y1 - y2 > Math.abs(x2 - x1) && y1 - y2 > 20) {
System.out.println("上");
up();
GameOver();
initGame();
// X坐标差大于Y坐标,上下运动
} else if (x2 - x1 > Math.abs(y2 - y1) && x2 - x1 > 20) {
System.out.println("左");
left();
GameOver();
initGame();
} else if (x1 - x2 > Math.abs(y2 - y1) && x1 - x2 > 20) {
System.out.println("右");
right();
GameOver();
initGame();
}
break;
}
return true;
}
});
}
现在,图片就可以跟随手指的滑动方向进行滑动了,接下来便是游戏的过关判定
之前也提到过,我在获取数组的时候,我获取可两个,一个是number[],一个是ganeover[]。这里我们便需要用到gameover[]了,因为在上面的操作中,我只操作了number[]数组,而当滑动图片让图片排列,最后恢复number[]数组的初始状态,即与gameover[]数组相同,则这时,游戏便过关了。按照这个思路,我们就要开始判定了
/**
*
* 过关判定
*/
public void GameOver() {
int total = 0;
for (int i = 0; i < 8; i++) {
// 判断number[i]是否跟初始定义的game[i]相等,记录相等的个数
if (number[i] == gameover[i]) {
total += 1;
}
// 如果有8个都相等,那么拼图完成
if (total == 8) {
// Toast.makeText(EasyActivity.this, "过关", 0).show();
Dialog();
// 在子线程中更新UI布局
new Thread() {
public void run() {
Message msg = Message.obtain();
msg.what = 8;// 标记
handler.sendMessage(msg);
};
}.start();
}
System.out.println("GameOver");
}
}
我使用for循环进行遍历,跟gameover[]数组的前八个元素进行比较,因为后面的几个没有操作,所以也没有必要进行比较,如果number[i]==gameover[i]那个初始值为零的total+1,当total=8的时候,那么此时gameover[]跟number[]的值便相等了,此时拼图也就完成,即游戏过关了
判定过关中开的线程,是将拼图中的第九块由空白变成真正的第九块,使拼图完整,给用户一个较好的体验,因为我不指这里一次用到线程,很多操作都是在线程中完成的,所以这里暂时不详细描述线程,大家可以记住这里handler发送的what值是8,方便以后遇到handler的时候做区分
过关判定就这么完成,但是,仅仅只是简单的过关判定并不能给用户较好的体验,开发游戏的宗旨是什么,就是为了让用户有较好的体验。所以,我们在用户过关之后,我们便需要另外的一些操作了
首先,我们开始时用到了sharepreferences来存储用户的最好成绩,那么,当用户完成过关操作的时候,我们就需要从shareferencces中取出之前存储的数据,跟现在的成绩进行比较。大家知道,拼图这一类的游戏游戏的步数越少,那么成绩就是越好,所以说,如果之前存储的数据小于等于现在的数据,那么sharepreferences中存储的值不变,否则,shareperferences里的值就要变成存储那个较小的值了,这些都是结合着Dialog对话框完成的
代码如下
/**
* 弹出过关对话框
*/
public void Dialog() {
// 先从SharePreference中获取之前的最好成绩
SharedPreferences sharedPreferences = getSharedPreferences("info_easy",
MODE_PRIVATE);
int socer_db = sharedPreferences.getInt("socer_db", 0);
// 将此次成绩和最好成绩比较,如果此次成绩比最好成绩好或者最好成绩是0,更新SharePreference的socer_db
if (socer_db == 0 || socer_db > socer) {
SharedPreferences preferences = getSharedPreferences("info_easy",
Context.MODE_PRIVATE);
// 获取编辑者对象
Editor editor = preferences.edit();
editor.putInt("socer_db", socer);
editor.commit();
// 弹出刷新纪录对话框的设置
AlertDialog.Builder builder = new AlertDialog.Builder(
EasyActivity.this);
builder.setTitle("系统提示");
builder.setMessage("恭喜你刷新了记录!!");
builder.setIcon(R.drawable.shuaxin);
// 取消按钮,留在此完成界面
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
// 确定按钮,重置游戏,重新开始
builder.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
new Thread() {
public void run() {
Message msg = Message.obtain();
msg.what = 24;
handler.sendMessage(msg);
};
}.start();
}
});
builder.create().show();
tv1.setText("您的最好成绩是" + socer + "步");
} else {
// 过关对话框
AlertDialog.Builder builder = new AlertDialog.Builder(
EasyActivity.this);
builder.setTitle("系统提示");
builder.setMessage("恭喜过关!要不要再来一局");
builder.setIcon(R.drawable.guoguan);
builder.setNegativeButton("取消", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.setPositiveButton("确定", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
new Thread() {
public void run() {
Message msg = Message.obtain();
msg.what = 24;
handler.sendMessage(msg);
};
}.start();
}
});
builder.create().show();
tv1.setText("您的最好成绩是" + socer_db + "步");
}
}
当然,重新“开始功能”也是必不可少的
其实重新开始也很容易实现,就是重新初始化一下布局,将步数清零,但是注意一点,这里只是重新开始,并不重置sharepreferences的值
代码如下
/**
* 重新开始按钮,步数置零,图片随机
*
* @param v
*/
public void onclick(View v) {
switch (v.getId()) {
case R.id.easy_bt1:
new Thread() {
public void run() {
Message msg = Message.obtain();
msg.what = 24;
handler.sendMessage(msg);
};
}.start();
System.out.println("AAA");
// initGame();
break;
default:
break;
}
}
到此为止,游戏的基本操作功能就全部实现了,其余的便是优化配置等操作了