c语言小游戏推箱子教程,012-C语言小游戏之推箱子

77c225243e8e73fb9421e57a3f2b4f22.png

一、创建游戏地图

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#define ROWS 11

#define COLS 12

charmap[ROWS][COLS]={

"###########",

"#         #",

"#O        #",

"# X#  #  @#",

"#  #  #   #",

"#  #  #   #",

"#  #  #   #",

"#         #",

"#         #",

"###########"

};

因为推箱子游戏地图是由多个格子组成的,所以我们可以使用二维字符数组或字符串数组创建地图。我们可以改变数组中的元素来对游戏功能进行实现。例如:小人移动方向无障碍物,就是小人原来位置的数组元素设置为路,移动后的元素设置为小人。这样就实现了小人移动功能,箱子也是同理。

二、初始化位置和游戏开关

1

2

3

4

5

6

7

8

9

10

//游戏开关

intflag=1;

//人的坐标

intrenRows=2;

intrenCols=1;

//箱子的坐标

intxiangRows=3;

intxiangCols=2;

因为整个游戏操作都是放在循环里的,所以我们先定义一个全局开关,然后用while(开关)来控制游戏的结束。并且在判断用户输入方向前,我们需要先确定小人和箱子的初始位置,再根据用户输入进行判断。

三、接收用户输入方向

1

2

3

4

5

printf("W.前  S.后  A.左  D.右  Q.退出\n");

charenterInput='a';

rewind(stdin);

//接收键盘方向

scanf("%c",&enterInput);

接收用户从键盘输入的字符,由于方向4个,加上退出功能就5个分支。所以我们使用switch case结构来实现判断用户输入字符,并执行一些操作。

四、判断用户输入方向

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

//初始化人和箱子的下一个坐标

intnextRows=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;

}

人下一个位置的行下标 nextRows

人下一个位置的列下标 nextCols

箱子下一个位置的行下标 nextXiangRows

箱子下一个位置的列下标 nextXiangCols

这里说的下一个位置就好比,我输入w后向上移动了一个位置,这个新的位置我称他为下一个位置。

如果向上移动,人和箱子的行下标-1,列下标不变。

如果向下移动,人和箱子的行下标+1,列下标不变。

如果向左移动,人和箱子的行下标不变,列下标-1。

如果向右移动,人和箱子的行下标不变,列下标+1。

我这里是先根据方向判断出人和箱子位置会发生的移动变化,并使用局部变量临时存储,所以不用担心人没有顶着箱子的时候,箱子也会跟着移动的问题。因为最终移动后的新位置坐标还是由全局变量来存储的,我只是根据用户输入方向计算出人和箱子下一个位置的新坐标,然后再根据实际情况(实际情况就是人前进方向是否是障碍物,还是箱子来确定的。如果是障碍物,就只有人移动,并只有人刷新位置。如果是箱子,则判断箱子下一个位置是否是障碍物,来刷新人和箱子的新位置)赋值给全局变量。

五、移动控制实现

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

voidmoveRen(intnextRows,intnextCols,intnextXiangRows,intnextXiangCols){

if(map[nextRows][nextCols]==' '){

//如果人下一个位置是路

map[nextRows][nextCols]='O';//下一个位置设置为人

map[renRows][renCols]=' ';//人原来的位置设置为路

//刷新人的位置

renRows=nextRows;

renCols=nextCols;

}elseif(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;

}elseif(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

#include

#define ROWS 11

#define COLS 12

charmap[ROWS][COLS]={

"###########",

"#         #",

"#O        #",

"# X#  #  @#",

"#  #  #   #",

"#  #  #   #",

"#  #  #   #",

"#         #",

"#         #",

"###########"

};

//游戏开关

intflag=1;

//人的坐标

intrenRows=2;

intrenCols=1;

//箱子的坐标

intxiangRows=3;

intxiangCols=2;

//移动小人

voidmoveRen(intnextRows,intnextCols,intnextXiangRows,intnextXiangCols);

intmain(intargc,constchar*argv[]){

while(flag){

system("clear");

//刷新地图

for(inti=0;i

printf("%s\n",map[i]);

}

printf("W.前  S.后  A.左  D.右  Q.退出\n");

charenterInput='a';

rewind(stdin);

//接收键盘方向

scanf("%c",&enterInput);

//初始化人和箱子的下一个坐标

intnextRows=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;

}

}

return0;

}

//移动小人

voidmoveRen(intnextRows,intnextCols,intnextXiangRows,intnextXiangCols){

if(map[nextRows][nextCols]==' '){

//如果人下一个位置是路

map[nextRows][nextCols]='O';//下一个位置设置为人

map[renRows][renCols]=' ';//人原来的位置设置为路

//刷新人的位置

renRows=nextRows;

renCols=nextCols;

}elseif(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;

}elseif(map[nextXiangRows][nextXiangCols]=='@'){

//如果箱子下一个位置是关卡,就过关

printf("您已经过关!\n");

flag=0;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值