1、建立遊戲地圖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#define ROWS 11
#define COLS 12
char
map
[
ROWS
]
[
COLS
]
=
{
"###########"
,
"# #"
,
"#O #"
,
"# X# # @#"
,
"# # # #"
,
"# # # #"
,
"# # # #"
,
"# #"
,
"# #"
,
"###########"
}
;
|
由於推箱子游戲地圖是由多個格子組成的,因此咱們可使用二維字符數組或字符串數組建立地圖。咱們能夠改變數組中的元素來對遊戲功能進行實現。例如:小人移動方向無障礙物,就是小人原來位置的數組元素設置爲路,移動後的元素設置爲小人。這樣就實現了小人移動功能,箱子也是同理。數組
2、初始化位置和遊戲開關
1
2
3
4
5
6
7
8
9
10
|
//遊戲開關
int
flag
=
1
;
//人的座標
int
renRows
=
2
;
int
renCols
=
1
;
//箱子的座標
int
xiangRows
=
3
;
int
xiangCols
=
2
;
|
由於整個遊戲操做都是放在循環裏的,因此咱們先定義一個全局開關,而後用while(開關)來控制遊戲的結束。而且在判斷用戶輸入方向前,咱們須要先肯定小人和箱子的初始位置,再根據用戶輸入進行判斷。ide
3、接收用戶輸入方向
1
2
3
4
5
|
printf
(
"W.前 S.後 A.左 D.右 Q.退出\n"
)
;
char
enterInput
=
'a'
;
rewind
(
stdin
)
;
//接收鍵盤方向
scanf
(
"%c"
,
&
enterInput
)
;
|
接收用戶從鍵盤輸入的字符,因爲方向4個,加上退出功能就5個分支。因此咱們使用switch case結構來實現判斷用戶輸入字符,並執行一些操做。函數
4、判斷用戶輸入方向
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
49
50
51
52
53
54
|
//初始化人和箱子的下一個座標
int
nextRows
=
0
,
nextCols
=
0
,
nextXiangRows
=
0
,
nextXiangCols
=
0
;
//判斷方向並操做
switch
(
enterInput
)
{
case
'w'
:
case
'W'
:
{
nextRows
=
renRows
-
1
;
nextCols
=
renCols
;
nextXiangRows
=
xiangRows
-
1
;
nextXiangCols
=
xiangCols
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
's'
:
case
'S'
:
{
nextRows
=
renRows
+
1
;
nextCols
=
renCols
;
nextXiangRows
=
xiangRows
+
1
;
nextXiangCols
=
xiangCols
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'a'
:
case
'A'
:
{
nextRows
=
renRows
;
nextCols
=
renCols
-
1
;
nextXiangRows
=
xiangRows
;
nextXiangCols
=
xiangCols
-
1
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'd'
:
case
'D'
:
{
nextRows
=
renRows
;
nextCols
=
renCols
+
1
;
nextXiangRows
=
xiangRows
;
nextXiangCols
=
xiangCols
+
1
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'q'
:
case
'Q'
:
//若是輸入Q則關閉遊戲
flag
=
0
;
break
;
default
:
printf
(
"輸入錯誤\n"
)
;
break
;
}
|
人下一個位置的行下標 nextRowsspa
人下一個位置的列下標 nextColscode
箱子下一個位置的行下標 nextXiangRowsblog
箱子下一個位置的列下標 nextXiangCols遊戲
這裏說的下一個位置就比如,我輸入w後向上移動了一個位置,這個新的位置我稱他爲下一個位置。ci
若是向上移動,人和箱子的行下標-1,列下標不變。rem
若是向下移動,人和箱子的行下標+1,列下標不變。字符串
若是向左移動,人和箱子的行下標不變,列下標-1。
若是向右移動,人和箱子的行下標不變,列下標+1。
我這裏是先根據方向判斷出人和箱子位置會發生的移動變化,並使用局部變量臨時存儲,因此不用擔憂人沒有頂着箱子的時候,箱子也會跟着移動的問題。由於最終移動後的新位置座標仍是由全局變量來存儲的,我只是根據用戶輸入方向計算出人和箱子下一個位置的新座標,而後再根據實際狀況(實際狀況就是人前進方向是不是障礙物,仍是箱子來肯定的。若是是障礙物,就只有人移動,並只有人刷新位置。若是是箱子,則判斷箱子下一個位置是不是障礙物,來刷新人和箱子的新位置)賦值給全局變量。
5、移動控制實現
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
|
void
moveRen
(
int
nextRows
,
int
nextCols
,
int
nextXiangRows
,
int
nextXiangCols
)
{
if
(
map
[
nextRows
]
[
nextCols
]
==
' '
)
{
//若是人下一個位置是路
map
[
nextRows
]
[
nextCols
]
=
'O'
;
//下一個位置設置爲人
map
[
renRows
]
[
renCols
]
=
' '
;
//人原來的位置設置爲路
//刷新人的位置
renRows
=
nextRows
;
renCols
=
nextCols
;
}
else
if
(
map
[
nextRows
]
[
nextCols
]
==
'X'
&&
map
[
nextXiangRows
]
[
nextXiangCols
]
!=
'#'
&&
map
[
nextXiangRows
]
[
nextXiangCols
]
!=
'@'
)
{
//若是人下一個位置是箱子,而且箱子下一個位置不是牆也不是關卡
map
[
nextRows
]
[
nextCols
]
=
'O'
;
//下一個位置設置爲人
map
[
renRows
]
[
renCols
]
=
' '
;
//人原來的位置設置爲路
map
[
nextXiangRows
]
[
nextXiangCols
]
=
'X'
;
//箱子下一個位置設置爲箱子
//刷新人和箱子的位置
renRows
=
nextRows
;
renCols
=
nextCols
;
xiangRows
=
nextXiangRows
;
xiangCols
=
nextXiangCols
;
}
else
if
(
map
[
nextXiangRows
]
[
nextXiangCols
]
==
'@'
)
{
//若是箱子下一個位置是關卡,就過關
printf
(
"您已通過關!\n"
)
;
flag
=
0
;
}
}
|
最終程序代碼爲
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include <stdio.h>
#include <stdlib.h>
#define ROWS 11
#define COLS 12
char
map
[
ROWS
]
[
COLS
]
=
{
"###########"
,
"# #"
,
"#O #"
,
"# X# # @#"
,
"# # # #"
,
"# # # #"
,
"# # # #"
,
"# #"
,
"# #"
,
"###########"
}
;
//遊戲開關
int
flag
=
1
;
//人的座標
int
renRows
=
2
;
int
renCols
=
1
;
//箱子的座標
int
xiangRows
=
3
;
int
xiangCols
=
2
;
//移動小人
void
moveRen
(
int
nextRows
,
int
nextCols
,
int
nextXiangRows
,
int
nextXiangCols
)
;
int
main
(
int
argc
,
const
char
*
argv
[
]
)
{
while
(
flag
)
{
system
(
"clear"
)
;
//刷新地圖
for
(
int
i
=
0
;
i
<
ROWS
;
i
++
)
{
printf
(
"%s\n"
,
map
[
i
]
)
;
}
printf
(
"W.前 S.後 A.左 D.右 Q.退出\n"
)
;
char
enterInput
=
'a'
;
rewind
(
stdin
)
;
//接收鍵盤方向
scanf
(
"%c"
,
&
enterInput
)
;
//初始化人和箱子的下一個座標
int
nextRows
=
0
,
nextCols
=
0
,
nextXiangRows
=
0
,
nextXiangCols
=
0
;
//判斷方向並操做
switch
(
enterInput
)
{
case
'w'
:
case
'W'
:
{
nextRows
=
renRows
-
1
;
nextCols
=
renCols
;
nextXiangRows
=
xiangRows
-
1
;
nextXiangCols
=
xiangCols
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
's'
:
case
'S'
:
{
nextRows
=
renRows
+
1
;
nextCols
=
renCols
;
nextXiangRows
=
xiangRows
+
1
;
nextXiangCols
=
xiangCols
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'a'
:
case
'A'
:
{
nextRows
=
renRows
;
nextCols
=
renCols
-
1
;
nextXiangRows
=
xiangRows
;
nextXiangCols
=
xiangCols
-
1
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'd'
:
case
'D'
:
{
nextRows
=
renRows
;
nextCols
=
renCols
+
1
;
nextXiangRows
=
xiangRows
;
nextXiangCols
=
xiangCols
+
1
;
//調用移動函數
moveRen
(
nextRows
,
nextCols
,
nextXiangRows
,
nextXiangCols
)
;
}
break
;
case
'q'
:
case
'Q'
:
//若是輸入Q則關閉遊戲
flag
=
0
;
break
;
default
:
printf
(
"輸入錯誤\n"
)
;
break
;
}
}
return
0
;
}
//移動小人
void
moveRen
(
int
nextRows
,
int
nextCols
,
int
nextXiangRows
,
int
nextXiangCols
)
{
if
(
map
[
nextRows
]
[
nextCols
]
==
' '
)
{
//若是人下一個位置是路
map
[
nextRows
]
[
nextCols
]
=
'O'
;
//下一個位置設置爲人
map
[
renRows
]
[
renCols
]
=
' '
;
//人原來的位置設置爲路
//刷新人的位置
renRows
=
nextRows
;
renCols
=
nextCols
;
}
else
if
(
map
[
nextRows
]
[
nextCols
]
==
'X'
&&
map
[
nextXiangRows
]
[
nextXiangCols
]
!=
'#'
&&
map
[
nextXiangRows
]
[
nextXiangCols
]
!=
'@'
)
{
//若是人下一個位置是箱子,而且箱子下一個位置不是牆也不是關卡
map
[
nextRows
]
[
nextCols
]
=
'O'
;
//下一個位置設置爲人
map
[
renRows
]
[
renCols
]
=
' '
;
//人原來的位置設置爲路
map
[
nextXiangRows
]
[
nextXiangCols
]
=
'X'
;
//箱子下一個位置設置爲箱子
//刷新人和箱子的位置
renRows
=
nextRows
;
renCols
=
nextCols
;
xiangRows
=
nextXiangRows
;
xiangCols
=
nextXiangCols
;
}
else
if
(
map
[
nextXiangRows
]
[
nextXiangCols
]
==
'@'
)
{
//若是箱子下一個位置是關卡,就過關
printf
(
"您已通過關!\n"
)
;
flag
=
0
;
}
}
|