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

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

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

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

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

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

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

  1 package YYj.llk;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.Vector;
6
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.DialogInterface;
10 import android.content.DialogInterface.OnClickListener;
11 import android.content.Intent;
12 import android.os.Bundle;
13 import android.view.View;
14 import android.widget.AdapterView;
15 import android.widget.AdapterView.OnItemClickListener;
16 import android.widget.GridView;
17 import android.widget.SimpleAdapter;
18
19 public class main extends Activity {
20 /** Called when the activity is first created. */
21 GridView gv1;
22 int temp=0;
23 int lastClicked;
24 int numcolum;
25 ArrayList<HashMap<String, Integer>> aList;
26 @Override
27 public void onCreate(Bundle savedInstanceState) {
28 super.onCreate(savedInstanceState);
29 setContentView(R.layout.main);
30 gv1=(GridView)findViewById(R.id.gridView1);
31 aList=new ArrayList<HashMap<String,Integer>>();
32 //生成数据
33 CreateStones();
34 //打乱ArrayList的顺序
35 MixIt(aList);
36 //绑定数据
37 DataBind();
38
39 gv1.setOnItemClickListener(new OnItemClickListener() {
40
41 @Override
42 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
43 long arg3) {
44 int temp2=(int)(aList.get(arg2).get("whichStone"));
45 //第一个条件是判断点击的不是空的,第二个确认两次点击的不是同一个
46 if (temp2!=R.drawable.ull&lastClicked!=arg2) {
47 if (temp==0) {
48 temp=temp2;
49 }else {
50 //两个点击的是相同的
51 if (temp2==temp) {
52 Point thispoint=arg2topoint(arg2);
53 Point lastpoint=arg2topoint(lastClicked);
54 //用下面方法判断是否可以删除
55 if (CheckIsItCanBeDestoryed(thispoint, lastpoint)) {
56 Clear(arg2);
57 Clear(lastClicked);
58 DataBind();
59 checkIsSuccess();
60 }
61 }
62 temp=0;
63 }
64 lastClicked=arg2;
65 }
66 }
67 });
68 }
69 //是否已经全部消除
70 private void checkIsSuccess() {
71 for (HashMap<String, Integer> amap : aList) {
72 if ((int)amap.get("whichStone")!=R.drawable.ull) {
73 return;
74 }
75 }
76 new AlertDialog.Builder(main.this).setTitle("胜利了!").setIcon(android.R.drawable.ic_dialog_alert)
77 .setMessage("你赢了,是不是特别有成就感呢!!!").setPositiveButton("OK", new OnClickListener() {
78
79 @Override
80 public void onClick(DialogInterface arg0, int arg1) {
81 Intent intent=new Intent();
82 intent.setClass(main.this, startActivity.class);
83 startActivity(intent);
84 main.this.finish();
85 }
86 }).setCancelable(false).show();
87 }
88 //判断是否可以消除
89 private boolean CheckIsItCanBeDestoryed(Point p1,Point p2){
90 /*判断一条线可以连接的情况*/
91 if (testVertical(new Point(p1), new Point(p2))) {
92 return true;
93 }
94 if (testHorizontal(new Point(p1), new Point(p2))) {
95 return true;
96 }
97 /*判断两条线可以连接的情况*/
98 Point newPoint1=new Point(p2.x, p1.y);
99 int tmp1=pointtoarg2(newPoint1);
100 if ((int)aList.get(tmp1).get("whichStone")==R.drawable.ull) {
101 if (testVertical(p2, new Point(newPoint1))&&testHorizontal(p1, new Point(newPoint1))) {
102 return true;
103 }
104 }
105 Point newPoint2=new Point(p1.x, p2.y);
106 tmp1=pointtoarg2(newPoint2);
107 if ((int)aList.get(tmp1).get("whichStone")==R.drawable.ull) {
108 if (testVertical(p1, new Point(newPoint2))&&testHorizontal(p2, new Point(newPoint2))) {
109 return true;
110 }
111 }
112 /*判断三条线可以连接的情况*/
113 Vector<Line> vector=new Vector<main.Line>();
114 vector=Scan(new Point(p1), new Point(p2));
115 if (!vector.isEmpty()) {
116 for (int i = 0; i < vector.size(); i++) {
117 Line line=vector.elementAt(i);
118 //横线
119 if (line.dirct==0) {
120 if (testVertical(new Point(p1), new Point(line.a))&&testVertical(new Point(p2), new Point(line.b))) {
121 return true;
122 }
123 }else {
124 if (testHorizontal(new Point(p1), new Point(line.a))&&testHorizontal(new Point(p2), new Point(line.b))) {
125 return true;
126 }
127 }
128 }
129 }
130
131 return false;
132 }
133 private Vector<Line> Scan(Point p1,Point p2) {
134 Vector<Line> v=new Vector<main.Line>();
135 //查找A左边的线
136 for (int y = p1.y; y >=0; y--) {
137 if ((int)aList.get(pointtoarg2(new Point(p1.x, y))).get("whichStone")==R.drawable.ull&&
138 (int)aList.get(pointtoarg2(new Point(p2.x, y))).get("whichStone")==R.drawable.ull&&
139 testHorizontal(new Point(p1.x,y), new Point(p2.x,y))) {
140 v.add(new Line(0, new Point(p1.x,y), new Point(p2.x,y)));
141 }
142 }
143 //查找A右边边的线
144 for (int y = p1.y; y <6; y++) {
145 if ((int)aList.get(pointtoarg2(new Point(p1.x, y))).get("whichStone")==R.drawable.ull&&
146 (int)aList.get(pointtoarg2(new Point(p2.x, y))).get("whichStone")==R.drawable.ull&&
147 testHorizontal(new Point(p1.x,y), new Point(p2.x,y))) {
148 v.add(new Line(0, new Point(p1.x,y), new Point(p2.x,y)));
149 }
150 }
151 //查找A上面的线
152 for (int x = p1.x; x >=0; x--) {
153 if ((int)aList.get(pointtoarg2(new Point(x,p1.y))).get("whichStone")==R.drawable.ull&&
154 (int)aList.get(pointtoarg2(new Point(x, p2.y))).get("whichStone")==R.drawable.ull&&
155 testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
156 v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
157 }
158 }
159 //查找A下面的线
160 for (int x = p1.x; x <6; x++) {
161 if ((int)aList.get(pointtoarg2(new Point(x,p1.y))).get("whichStone")==R.drawable.ull&&
162 (int)aList.get(pointtoarg2(new Point(x, p2.y))).get("whichStone")==R.drawable.ull&&
163 testVertical(new Point(x,p1.y), new Point(x,p2.y))) {
164 v.add(new Line(1, new Point(x,p1.y), new Point(x,p2.y)));
165 }
166 }
167 return v;
168 }
169 //判断是否可以用竖线链接两个点
170 private boolean testVertical(Point p1,Point p2) {
171 //定义一个bool值,表示循环过程中是否碰到不为空的
172 boolean b=true;
173 if (p1.x==p2.x) {
174 //差值,循环时用到
175 int temp=(p1.y-p2.y)/Math.abs(p1.y-p2.y);
176 while(p1.y!=p2.y){
177 p2.y+=temp;
178 int arg2=pointtoarg2(p2);
179 //如果对应坐标点不为空
180 if((int)aList.get(arg2).get("whichStone")!=R.drawable.ull&p1.y!=p2.y){
181 b=false;
182 break;
183 }
184 }
185 }else {
186 b=false;
187 }
188 return b;
189 }
190 //判断是否可以用横线链接两个点
191 private boolean testHorizontal(Point p1,Point p2) {
192 //定义一个bool值,表示循环过程中是否碰到不为空的
193 boolean b=true;
194 if (p1.y==p2.y) {
195 //差值,循环时用到
196 int temp=(p1.x-p2.x)/Math.abs(p1.x-p2.x);
197 while(p1.x!=p2.x){
198 p2.x+=temp;
199 int arg2=pointtoarg2(p2);
200 //如果对应坐标点不为空
201 if((int)aList.get(arg2).get("whichStone")!=R.drawable.ull&p1.x!=p2.x){
202 b=false;
203 break;
204 }
205 }
206 }else {
207 b=false;
208 }
209 return b;
210 }
211 //把数字转换为坐标点
212 private Point arg2topoint(int a){
213 int px=a%6;
214 int py=a/6;
215 return new Point(px, py);
216 }
217 //把点转换为数字
218 private int pointtoarg2(Point a){
219 return a.y*6+a.x;
220 }
221 //生成数据,保证每种图片出现六次
222 private void CreateStones() {
223 for (int i = 1; i < 7; i++) {
224 HashMap<String, Integer> hMap=new HashMap<String, Integer>();
225 switch (i) {//这里的判断用到了后面定义的类
226 case Stones.Blue:
227 hMap.put("whichStone", R.drawable.blue);
228 break;
229 case Stones.Gold:
230 hMap.put("whichStone", R.drawable.gold);
231 break;
232 case Stones.Green:
233 hMap.put("whichStone", R.drawable.green);
234 break;
235 case Stones.Orange:
236 hMap.put("whichStone", R.drawable.orange);
237 break;
238 case Stones.Purple:
239 hMap.put("whichStone", R.drawable.purple);
240 break;
241 case Stones.Red:
242 hMap.put("whichStone", R.drawable.red);
243 break;
244 }
245 aList.add(hMap);
246 aList.add(hMap);
247 aList.add(hMap);
248 aList.add(hMap);
249 aList.add(hMap);
250 aList.add(hMap);
251 }
252 }
253 //消去某个,即为替换为空图像R.drawable.ull
254 private void Clear(int x) {
255 HashMap<String, Integer> hMap=new HashMap<String, Integer>();
256 hMap.put("whichStone", R.drawable.ull);
257 aList.set(x, hMap);
258 }
259 //绑定数据或者alist改变后重新绑定
260 private void DataBind() {
261 SimpleAdapter adapter=new SimpleAdapter(main.this, aList, R.layout.star, new String[]{"whichStone"}, new int[]{R.id.imageView1});
262 gv1.setAdapter(adapter);
263 }
264 //打乱alist中的数据的次序,相当于随机生成
265 private void MixIt(ArrayList<HashMap<String, Integer>> aList) {
266 for (int i = 0; i < 200; i++) {
267 int rd=(int)(Math.random()*aList.size());
268 HashMap<String, Integer> tMap=aList.get(rd);
269 aList.remove(rd);
270 aList.add(tMap);
271 }
272 }
273 //内部枚举类
274 class Stones{
275 public static final int Ull=0;//这个图片是空白的
276 public static final int Blue=1;
277 public static final int Gold=2;
278 public static final int Green=3;
279 public static final int Orange=4;
280 public static final int Purple=5;
281 public static final int Red=6;
282 }
283 //存储坐标点的类,这里用自己写的,没有用原生的
284 class Point{
285 int x;
286 int y;
287 Point(int px,int py){
288 x=px;
289 y=py;
290 }
291 Point(Point p){
292 x=p.x;
293 y=p.y;
294 }
295 }
296 //这个用来判断三条直线链接的时候用到
297 class Line{
298 Point a,b;
299 int dirct;//1表示竖线,0表示横线
300 public Line(int dirce,Point a,Point b) {
301 this.a=a;
302 this.b=b;
303 this.dirct=dirce;
304 }
305 }
306 }

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

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

附上截图,

源代码,llk.zip

安装包,llk.apk

posted @ 2012-03-02 16:23  天意人间  阅读(2222)  评论(3编辑  收藏  举报