ncurses游戏c语言,C语言之贪吃蛇(ncurses)

声明: 以下内容可能会引起某些读者不适, 请小心阅读. 有些内容并没有详细介绍, 可能简单理解也是错误的, 但是这都是为了尽量简单。

前言: 代码是很久之前写的,属于边想边写的那种,很混乱。

推荐材料:

贪吃蛇应该是我们这代人都玩过的游戏。而如果我们要写一个贪吃蛇最需要考虑的就是贪吃蛇是如何移动的。其实贪吃蛇的移动就是尾部的减少和头部的增加。

这篇文章:

介绍一些ncurses库的基础内容

贪吃蛇游戏的代码解释

介绍一些ncurses库的基础内容

ncurses

curses是一个在命令行下面的图形函数库,而ncurses的意思是 new curses。

ncurses的一些函数的简单解释

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

#include

int main()

{int ch;

initscr();/* Start curses mode */

raw();/* Line buffering disabled*/

keypad(stdscr, TRUE);/* We get F1, F2 etc..*/

noecho();/* Don't echo() while we do getch */

printw("Type any character to see it in bold\n");

ch = getch();/* If raw() hadn't been called

* we have to press enter before it

* gets to the program */

if(ch == KEY_F(1))/* Without keypad enabled this will */

printw("F1 Key pressed");/* not get to us either*/

/* Without noecho() some ugly escape

* charachters might have been printed

* on screen*/

else

{printw("The pressed key is ");

attron(A_BOLD);

printw("%c", ch);

attroff(A_BOLD);

}

refresh();/* Print it on to the real screen */

getch();/* Wait for user input */

endwin();/* End curses mode */

return 0;

}

这是我从这里拿到的一个例子。

我们应该注意到这个程序并没有导入标准输入输出库,而是导入了ncurses.h文件。在这个程序里面也没有使用printf(format printing),而是使用了printw这个函数(print window)就是打印到标准屏幕的意思

initscr:初始化屏幕,启动curses模式

raw:关闭行缓冲,一般的我们在命令行中输入数据的时候,只有当我们按下回车之后,才可以把数据提交给程序

noecho: 负责按键事务,我不太懂

noecho: 关闭回显(按下一个字符之后,屏幕并不显示。比如说在普通的情况下按下a,a会被显示在屏幕上)

getch: 获取一个字符

attron: 在后面的打印中增加打印属性,这里是粗体的意思

attroff: 移除属性

refresh:之前的printw只是打印到逻辑屏幕,而refresh函数会依据逻辑屏幕的内容,刷新到物理屏幕。

endwin:退出curses模式

其他的可以自己慢慢去学习

ncurses库的安装和使用

安装

如果你是使用debian系列的linux发行版,例如ubuntu,应该直接键入命令:

1

sudo apt-get install libncurses5-dev

就可以了。

如果是别的系列的版本,建议下载源码包,编译安装。或者百度搜索正确的答案。

使用

一般的,只需要在gcc编译命令的后面加上-lncurses就可以正确导入ncurses库了。

1

gcc -o demo demo.c -std=c99 -lncurses

-std=c99的意思是使用c99的标准来编译代码。

没有使用过命令行编译操作的同学需要自己去学习。

贪吃蛇的代码解释

从哪里得到

点击这里。这份代码是我写的,也确实写的不好。但也可以随便看看。

代码结构

1

2

3

4

5

6

7

|-- hungry_snake // 可执行文件,

|-- main.c

|-- snake.c

|-- snake.h

`-- wellcome.h

0 directories, 5 files

hungry_snake是一个可执行文件,在debian下编译的,在centos下面可能需要重新编译。

main.c是程序的主要逻辑部分。

wellcome.h包含了欢迎界面的代码实现。

snake.h

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

/*

* snake.h

*/

#ifndef SNAKE_H

#define SNAKE_H

#include

// 这个枚举类型我其实没有用

typedef enum state

{

goleft,

goright,

goup,

godown

}state;

// 这个是蛇的一节,也就是一个坐标

typedef struct body

{

int y;

int x;

struct body *prev;

struct body *next;

}Body ,*Pbody;

// 这个是蛇的结构定义,有一个虚蛇头,蛇头和蛇尾,还有蛇的长度啊,运动状态啊

typedef struct snake

{

Pbody vir_head;

Pbody head;

Pbody tail;

int length;

state movement;// 我没有用

char uping;

char downing;

char lefting;

char righting;

}Snake, *Psnake;

int FOOD[1000][1000]; // 食物坐标,标记哪个位置有食物

int food_num; // 食物数量

/*

** body part

*/

Pbody init_body(); // 初始化蛇身

void add_body(Pbody jack, Pbody bd); // 增加一节

Pbody bd(int lines,int cols);// 构造一个蛇节

void print_snake(Pbody jack);// 显示那条蛇

void print_bd(Pbody bd);// 显示蛇节

Pbody get_head(Pbody jack);// 得到蛇头部节点

Pbody add_head(Pbody oldhead,Pbody newhead); // 增加节点到头部

Pbody del_tail(Pbody jack); // 删除蛇尾

Pbody get_tail(Pbody jack); // 得到蛇尾节点指针

/*

** snake part

*/

Psnake init_snake();//初始化蛇

int snake_go_right(Psnake snake);// 蛇的移动

int snake_go_left(Psnake jack);

void show_snake(Psnake jack);// 屏幕上显示蛇

void init_show_snake(Psnake jack); // 忘了

int snake_go_down(Psnake jack);// 蛇的移动

int snake_go_up(Psnake jack);

int snake_can_move(Psnake jack, char ch); // 判断蛇能否往目标方向移动

int body_in_snake(int row, int col, Psnake jack); // 判断蛇身是否覆盖坐标

/* food part */

void putfood(Psnake jack); // 随机投放食物

int count_food(); // 食物技术

/* game_over */

void game_over(Psnake jack); // 游戏结束

#endif // SNAKE_H

这里有一些结构定义和函数声明。

main.c

下面是程序主体逻辑部分:

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

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

#include

#include

#include "snake.h"

#include

#include "wellcome.h"

#include

int ch;

int GAMEOVER;

/*

void get_command(void *i)

{

ch = getch();

}

*/

int main()

{

initscr();

start_color();

keypad(stdscr,TRUE);

curs_set(0);

noecho();

halfdelay(4);

init_pair(1,COLOR_WHITE,COLOR_BLACK);

init_pair(2,COLOR_BLACK,COLOR_WHITE);

print_snake_logo(stdscr);

mvprintw(LINES-1,COLS-20,"Producted by Jack");

mvprintw(LINES-4,(COLS-21)/2,"|-> START");

printw(" (? for help)");

refresh();

int choice;

char goout = 0;

while (!goout){

switch (choice = getch() ){

case 'q':

endwin();

return 0;

case 'e':

goout = 1;

break;

}

}

/*

pthread_t id;

pthread_create(&id,NULL,get_command,NULL);

*/

Psnake jack = init_snake();

init_show_snake(jack);

ch = mvgetch(LINES-1,0);

srand((unsigned)time(0));

for (int i = 0; i<10; i++)

putfood(jack);

refresh();

int noout = 1;

int c = 0;

while(noout){

ch = getch();

switch (ch){

case KEY_RIGHT:

c = snake_go_right(jack);

if ( c == -1){

noout = 0;

GAMEOVER = 1;

break;

}

continue;

case KEY_DOWN :

c = snake_go_down(jack);

if ( c == -1){

noout = 0;

GAMEOVER = 1;

break;

}

continue;

case KEY_LEFT:

c = snake_go_left(jack);

if ( c == -1){

noout = 0;

GAMEOVER = 1;

break;

}

continue;

case KEY_UP:

c = snake_go_up(jack);

if ( c == -1){

noout = 0;

GAMEOVER = 1;

break;

}

continue;

case 'q':

game_over(jack);

endwin();

return 0;

}

if (jack->righting){

c = snake_go_right(jack);

if (c == -1){

GAMEOVER = 1;

break;

}

}

else if (jack->lefting){

c = snake_go_left(jack);

if (c == -1){

GAMEOVER = 1;

break;

}

}

else if(jack->uping){

c = snake_go_up(jack);

if (c == -1){

GAMEOVER = 1;

break;

}

}

else if(jack->downing){

c = snake_go_down(jack);

if (c == -1){

GAMEOVER = 1;

break;

}

}

if (food_num < 30)

putfood(jack);

mvprintw(LINES-1,2,"-- socre %d --",jack->length);

refresh();

}

if(GAMEOVER)

game_over(jack);

refresh();

endwin();

return 0;

}

编译

1

gcc -o snake.out snake.h snake.c main.c wellcome.h -lncurses -std=c99

小结

这份代码写的太差劲,所以我也没有也不想过多的去说它。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值