[转载]Android开发八:插曲2--做一个安卓连连看

[转载]Android开发八:插曲2–做一个安卓连连看 – 天意人间 – 博客园.

好几天没有写博客了,这几天有点忙,在家里干活阻碍我的学习了,嘿嘿

上次学习的是ListView控件,这一次的小插曲是一个连连看,学了好几天了也该实践一下了,这次用的是一个GridView控件,把从ListView上面学到的数据绑定搬到GridView控件上直接就可以用了。

因为我用的是GridView控件做连连看,网上还是没有这样的例子的,大部分是用的Jbutton和二维数组,因为要把数据绑定到GridView上面,所以我用的是ArrayList。

本程序用了三个晚上的时间,白天没有时间啊,简单的点击消除是实现了,复杂的功能没有,而且也发现Bug了,但是现阶段,我也只能做到这样了,算是个粗制版吧。(这些废话可以直接无视…)

程序用了两个界面来完成。第一个界面就是两个按钮,开始游戏和退出游戏,第二个界面就是游戏界面,代码最后会提供下载,不仔细说了

直接贴上代码吧,已经注释上了

package YYj.llk;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.SimpleAdapter;

public class main extends Activity {
/** Called when the activity is first created. */
GridView gv1;
int temp=0;
int lastClicked;
int numcolum;
ArrayList> aList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gv1=(GridView)findViewById(R.id.gridView1);
aList=new ArrayList>();
//生成数据
CreateStones();
//打乱ArrayList的顺序
MixIt(aList);
//绑定数据
DataBind();

gv1.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView arg0, View arg1, int arg2,
long arg3) {
int temp2=(int)(aList.get(arg2).get("whichStone"));
//第一个条件是判断点击的不是空的,第二个确认两次点击的不是同一个
if (temp2!=R.drawable.ull&lastClicked!=arg2) {
if (temp==0) {
temp=temp2;
}else {
//两个点击的是相同的
if (temp2==temp) {
Point thispoint=arg2topoint(arg2);
Point lastpoint=arg2topoint(lastClicked);
//用下面方法判断是否可以删除
if (CheckIsItCanBeDestoryed(thispoint, lastpoint)) {
Clear(arg2);
Clear(lastClicked);
DataBind();
checkIsSuccess();
}
}
temp=0;
}
lastClicked=arg2;
}
}
});
}
//是否已经全部消除
private void checkIsSuccess() {
for (HashMap amap : aList) {
if ((int)amap.get("whichStone")!=R.drawable.ull) {
return;
}
}
new AlertDialog.Builder(main.this).setTitle("胜利了!").setIcon(android.R.drawable.ic_dialog_alert)
.setMessage("你赢了,是不是特别有成就感呢!!!").setPositiveButton("OK", new OnClickListener() {

@Override
public void onClick(DialogInterface arg0, int arg1) {
Intent intent=new Intent();
intent.setClass(main.this, startActivity.class);
startActivity(intent);
main.this.finish();
}
}).setCancelable(false).show();
}
//判断是否可以消除
private boolean CheckIsItCanBeDestoryed(Point p1,Point p2){
/*判断一条线可以连接的情况*/
if (testVertical(new Point(p1), new Point(p2))) {
return true;
}
if (testHorizontal(new Point(p1), new Point(p2))) {
return true;
}
/*判断两条线可以连接的情况*/
Point newPoint1=new Point(p2.x, p1.y);
int tmp1=pointtoarg2(newPoint1);
if ((int)aList.get(tmp1).get("whichStone")==R.drawable.ull) {
if (testVertical(p2, new Point(newPoint1))&&testHorizontal(p1, new Point(newPoint1))) {
return true;
}
}
Point newPoint2=new Point(p1.x, p2.y);
tmp1=pointtoarg2(newPoint2);
if ((int)aList.get(tmp1).get("whichStone")==R.drawable.ull) {
if (testVertical(p1, new Point(newPoint2))&&testHorizontal(p2, new Point(newPoint2))) {
return true;
}
}
/*判断三条线可以连接的情况*/
Vector vector=new Vector();
vector=Scan(new Point(p1), new Point(p2));
if (!vector.isEmpty()) {
for (int i = 0; i < vector.size(); i++) {
Line line=vector.elementAt(i);
//横线
if (line.dirct==0) {
if (testVertical(new Point(p1), new Point(line.a))&&testVertical(new Point(p2), new Point(line.b))) {
return true;
}
}else {
if (testHorizontal(new Point(p1), new Point(line.a))&&testHorizontal(new Point(p2), new Point(line.b))) {
return true;
}
}
}
}

return false;
}
private Vector Scan(Point p1,Point p2) {
Vector v=new Vector();
//查找A左边的线
for (int y = p1.y; y >=0; y--) {
if ((int)aList.get(pointtoarg2(new Point(p1.x, y))).get("whichStone")==R.drawable.ull&&
(int)aList.get(pointtoarg2(new Point(p2.x, y))).get("whichStone")==R.drawable.ull&&
testHorizontal(new Point(p1.x,y), new Point(p2.x,y))) {
v.add(new Line(0, new Point(p1.x,y), new Point(p2.x,y)));
}
}
//查找A右边边的线
for (int y = p1.y; y =0; x--) {
if ((int)aList.get(pointtoarg2(new Point(x,p1.y))).get("whichStone")==R.drawable.ull&&
(int)aList.get(pointtoarg2(new Point(x, p2.y))).get("whichStone")==R.drawable.ull&&
testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
}
}
//查找A下面的线
for (int x = p1.x; x if ((int)aList.get(pointtoarg2(new Point(x,p1.y))).get("whichStone")==R.drawable.ull&&
(int)aList.get(pointtoarg2(new Point(x, p2.y))).get("whichStone")==R.drawable.ull&&
testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
}
}
return v;
}
//判断是否可以用竖线链接两个点
private boolean testVertical(Point p1,Point p2) {
//定义一个bool值,表示循环过程中是否碰到不为空的
boolean b=true;
if (p1.x==p2.x) {
//差值,循环时用到
int temp=(p1.y-p2.y)/Math.abs(p1.y-p2.y);
while(p1.y!=p2.y){
p2.y+=temp;
int arg2=pointtoarg2(p2);
//如果对应坐标点不为空
if((int)aList.get(arg2).get("whichStone")!=R.drawable.ull&p1.y!=p2.y){
b=false;
break;
}
}
}else {
b=false;
}
return b;
}
//判断是否可以用横线链接两个点
private boolean testHorizontal(Point p1,Point p2) {
//定义一个bool值,表示循环过程中是否碰到不为空的
boolean b=true;
if (p1.y==p2.y) {
//差值,循环时用到
int temp=(p1.x-p2.x)/Math.abs(p1.x-p2.x);
while(p1.x!=p2.x){
p2.x+=temp;
int arg2=pointtoarg2(p2);
//如果对应坐标点不为空
if((int)aList.get(arg2).get("whichStone")!=R.drawable.ull&p1.x!=p2.x){
b=false;
break;
}
}
}else {
b=false;
}
return b;
}
//把数字转换为坐标点
private Point arg2topoint(int a){
int px=a%6;
int py=a/6;
return new Point(px, py);
}
//把点转换为数字
private int pointtoarg2(Point a){
return a.y*6+a.x;
}
//生成数据,保证每种图片出现六次
private void CreateStones() {
for (int i = 1; i < 7; i++) {
HashMap hMap=new HashMap();
switch (i) {//这里的判断用到了后面定义的类
case Stones.Blue:
hMap.put("whichStone", R.drawable.blue);
break;
case Stones.Gold:
hMap.put("whichStone", R.drawable.gold);
break;
case Stones.Green:
hMap.put("whichStone", R.drawable.green);
break;
case Stones.Orange:
hMap.put("whichStone", R.drawable.orange);
break;
case Stones.Purple:
hMap.put("whichStone", R.drawable.purple);
break;
case Stones.Red:
hMap.put("whichStone", R.drawable.red);
break;
}
aList.add(hMap);
aList.add(hMap);
aList.add(hMap);
aList.add(hMap);
aList.add(hMap);
aList.add(hMap);
}
}
//消去某个,即为替换为空图像R.drawable.ull
private void Clear(int x) {
HashMap hMap=new HashMap();
hMap.put("whichStone", R.drawable.ull);
aList.set(x, hMap);
}
//绑定数据或者alist改变后重新绑定
private void DataBind() {
SimpleAdapter adapter=new SimpleAdapter(main.this, aList, R.layout.star, new String[]{"whichStone"}, new int[]{R.id.imageView1});
gv1.setAdapter(adapter);
}
//打乱alist中的数据的次序,相当于随机生成
private void MixIt(ArrayList> aList) {
for (int i = 0; i < 200; i++) {
int rd=(int)(Math.random()*aList.size());
HashMap tMap=aList.get(rd);
aList.remove(rd);
aList.add(tMap);
}
}
//内部枚举类
class Stones{
public static final int Ull=0;//这个图片是空白的
public static final int Blue=1;
public static final int Gold=2;
public static final int Green=3;
public static final int Orange=4;
public static final int Purple=5;
public static final int Red=6;
}
//存储坐标点的类,这里用自己写的,没有用原生的
class Point{
int x;
int y;
Point(int px,int py){
x=px;
y=py;
}
Point(Point p){
x=p.x;
y=p.y;
}
}
//这个用来判断三条直线链接的时候用到
class Line{
Point a,b;
int dirct;//1表示竖线,0表示横线
public Line(int dirce,Point a,Point b) {
this.a=a;
this.b=b;
this.dirct=dirce;
}
}
}

代码中创建了大量的Point对象,如果不这样的话在调用的方法中会改变Point的值,这个应该很耗费资源…关键是我基本没有Java基础(就学了十来天)

还有代码中的判断三条线相等的情况参考了:http://www.java3z.com/cwbwebhome/article/article2/2167.jsp?id=530,其他的基本原创吧

附上截图,

源代码,llk.zip

安装包,llk.apk

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏