[转载]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