废话不多说了。
二,推箱子
首先,仍然需要明确自己要做什么?做到什么程度?
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