废话不多说了。
二,推箱子
首先,仍然需要明确自己要做什么?做到什么程度?
1、扫雷的重要元素:有雷的格子,没雷的格子,小红旗(用于确认雷,但是手机没有右键一说,懒得整得很复杂,抛弃小红旗)
2、成功条件:除有雷的格子外,其他格子全部被翻开
3、失败条件:翻开有雷的格子
4、其他细节:地图的大小(同上个游戏),点击无雷格子的事件(若周围有雷,显示周围雷数;若周围没累,自动翻开周围格子,直至有雷),点击有雷格子事件(亮出所有雷的位置,报告失败,如果是第一次就点击到了有雷的格子,则重新埋雷后自动翻开格子,直至第一次非雷)等
开始。(笔者再次声明:本人没做过游戏,这个只是写来自己玩的,如有误导,纯属坑爹)
惯例先贴出笔者自定义的常量和枚举类型,看面看不懂的可以回过头看看
1
2
3
4 |
#define kCount_Grid 9 //地图大小-小于10 #define kColor_Mine [UIColor clearColor] #define kColor_Safe [UIColor grayColor] #define kColor_Normal [UIColor brownColor] |
笔者的习惯是首先把地图绘制出來:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
-( void )initMap { if
(vMap) { [vMap removeFromSuperview]; } CGRect frame = self .view.frame; CGFloat width_Grid = frame.size.width/kCount_Grid; vMap = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.width)]; [vMap setCenter:CGPointMake(frame.size.width/2, frame.size.height/2)]; [ self .view addSubview:vMap]; for
( int i=1; i<kCount_Grid+1; i++) { for
( int j=1; j<kCount_Grid+1; j++) { UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake((i-1)*width_Grid, (j-1)*width_Grid, width_Grid, width_Grid)]; btn.layer.borderWidth = 1; btn.layer.borderColor = [[UIColor lightGrayColor]CGColor]; [btn setBackgroundColor:kColor_Normal]; [btn setTag:i+j*10]; [btn addTarget: self
action: @selector (findSafe:) forControlEvents:UIControlEventTouchUpInside]; [vMap addSubview:btn]; } } } |
由于都是方格游戏,所以笔者采用了上一个游戏的绘制方法,不多说。
然后我们来是埋雷
1
2
3
4
5
6
7
8
9
10 |
-( void )initMine { for
( int i=0; i<countMine; i++) { UIButton *btn = [ self
randomPoint]; btn = [ self
checkRepeat:btn]; [btn removeTarget: self
action: @selector (findSafe:) forControlEvents:UIControlEventTouchUpInside]; [btn addTarget: self
action: @selector (findMine:) forControlEvents:UIControlEventTouchUpInside]; [arrMine addObject:btn]; } } |
由于雷的位置是随机的,所以必须的一件事仍然是查重
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
-(UIButton *)checkRepeat:(UIButton*)btn { if
([arrMine containsObject:btn]) { btn = [ self
randomPoint]; return
[ self checkRepeat:btn]; } else { return
btn; } } -(UIButton *)randomPoint { int
x = arc4random()%kCount_Grid; int
y = arc4random()%kCount_Grid; x++; y++; return
(UIButton *)[vMap viewWithTag:(x+y*10)]; } |
埋完雷游戏就算初始化完了,接下来是游戏过程。
当我们点击一个格子的时候,如果是安全的,那么
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 |
-( void )isSafe:(UIButton *)btn { if
([btn isKindOfClass:[UIButton class ]] == NO
|| [btn isSelected] == YES ) { return ; } [btn setSelected: YES ]; countSafe++; if
(countMine+countSafe == kCount_Grid*kCount_Grid) { NSLog (@ "Success" ); [ self
alertSetSucceed]; } [btn setBackgroundColor:kColor_Safe]; int
tag = btn.tag; int
x = tag%10; int
y = tag/10; NSMutableArray
*nearGrid = [ NSMutableArray
new ]; UIButton *btn1 = (UIButton *)[vMap viewWithTag:(x-1)+(y-1)*10]; UIButton *btn2 = (UIButton *)[vMap viewWithTag:x+(y-1)*10]; UIButton *btn3 = (UIButton *)[vMap viewWithTag:(x+1)+(y-1)*10]; UIButton *btn4 = (UIButton *)[vMap viewWithTag:(x-1)+y*10]; UIButton *btn5 = (UIButton *)[vMap viewWithTag:(x+1)+y*10]; UIButton *btn6 = (UIButton *)[vMap viewWithTag:(x-1)+(y+1)*10]; UIButton *btn7 = (UIButton *)[vMap viewWithTag:x+(y+1)*10]; UIButton *btn8 = (UIButton *)[vMap viewWithTag:(x+1)+(y+1)*10]; (btn1) ? ([nearGrid addObject:btn1]):( nil ); (btn2) ? ([nearGrid addObject:btn2]):( nil ); (btn3) ? ([nearGrid addObject:btn3]):( nil ); (btn4) ? ([nearGrid addObject:btn4]):( nil ); (btn5) ? ([nearGrid addObject:btn5]):( nil ); (btn6) ? ([nearGrid addObject:btn6]):( nil ); (btn7) ? ([nearGrid addObject:btn7]):( nil ); (btn8) ? ([nearGrid addObject:btn8]):( nil ); int
i = [ self
getNearMineCount:nearGrid]; if
(i != 0) { NSString
*count = [ NSString
stringWithFormat:@ "%d" ,i]; [btn setTitle:count forState:UIControlStateNormal]; } else { [ self
isSafe:btn1]; [ self
isSafe:btn2]; [ self
isSafe:btn3]; [ self
isSafe:btn4]; [ self
isSafe:btn5]; [ self
isSafe:btn6]; [ self
isSafe:btn7]; [ self
isSafe:btn8]; } } |
Selected是一个标识,表明这个格子被检查过了没。如果安全,再检查周围8个格子,如果有雷,则注明雷数。如果无雷,就依次检查周围的8个按钮是否有雷。注意边界检查。
检查雷数的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
-( int )getNearMineCount:( NSMutableArray
*)nearGrid { int
count = 0; for
( int i=0; i<[nearGrid count]; i++) { UIButton *btn = nearGrid[i]; if
(!btn) { break ; } if
([arrMine containsObject:btn]) { count++; } } return
count; } |
如果点击的格子是雷,那直接把所有的雷区都标明出来,再提示一个失败就好了。
理论上是,但是:
有例外,按照和谐的、友好的、通常的玩法,点击的第一个格子无论如何不能是雷的。如果第一次就踩shit点到雷了呢?笔者的做法是把雷重埋一次,再自动去翻点击的格子,还是雷就再埋,直至不是雷为止。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
-( void )findMine:(UIButton *)btn { if
(countSafe == 0) { [ self
reStart]; btn = (UIButton *)[vMap viewWithTag:btn.tag]; if
([arrMine containsObject:btn]) { [ self
findMine:btn]; } else { [ self
findSafe:btn]; } return ; } for
( int i=0; i<[arrMine count]; i++) { UIButton *mine = arrMine[i]; [ self
isMine:mine]; } [ self
alertSetFailed]; } |
1
2
3
4
5 |
-( void )isMine:(UIButton *)btn { [btn setBackgroundColor:kColor_Mine]; [btn setTitle:@ "??"
forState:UIControlStateNormal]; } |
再然后呢、扫雷基本上也没啥可做的了。当然还有一些细节我没说,比如成功或者失败后格子就不能再翻啦,比如雷设置时的数量啦等等,虽没说,但都做了。有兴趣的可以自己下载来看看。
ok,扫雷,竣工。
完整代码下载:Demo
啊
原文:http://www.cnblogs.com/anjohnlv/p/3668808.html