在网上找到,某人在基于Linux终端,用curses库实现的弹球游戏。本人曾经也做过五子棋游戏,分在其它文章中分享。
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
/*
* 基于curses库弹球游戏,编译gcc xxx.c -lcurses
*/
#include <curses.h>
#include <sys/time.h>
#include <signal.h>
#define RIGHT COLS-1 /*球所能到达的当前屏幕最大水平范围*/
#define BOTTOM LINES-1 /*球所能到达的当前屏幕最大垂直范围*/
#define BOARD_LENGTH 10 /*挡板长度*/
#define LEFT 0 /*当前屏幕的最左边*/
#define TOP 0 /*当前屏幕的最上边*/
char BALL= 'O' ; /*球的形状*/
char BLANK= ' ' ; /*覆盖球走过的轨迹*/
int left_board; /*挡板左侧坐标*/
int right_board; /*挡板右侧坐标*/
int is_lose=0;
int hdir; /*控制球水平运动的变量*/
int vdir; /*控制球垂直运动的变量*/
int pos_X; /*球的横坐标*/
int pos_Y; /*球的纵坐标*/
int delay=100;
void moveBall();
void init();
void control();
int main()
{
//初始化 curses
initscr();
crmode(); /*中断模式*/
noecho(); /*关闭回显*/
move(6,28);
attron(A_BOLD);
addstr( "Welcome to the BallGame!" );
move(8,20);
attroff(A_BOLD);
addstr( "Help:" );
move(9,23);
addstr( "'N':Start a new game." );
move(10,23);
addstr( "'Q':Quit game." );
move(11,23);
addstr( "'KEY_LEFT' :Control baffle left shift." );
move(12,23);
addstr( "'KEY_RIGHT':Control baffle right shift." );
move(13,23);
addstr( "'KEY_UP' :Control of the ball speed." );
move(14,23);
addstr( "'KEY_DOWN' :Control of the ball reducer." );
int flag=1;
char choice;
move(16,24);
addstr( "Please choose your choice!(n/q):" );
refresh();
choice=getch();
while (flag){
if (choice== 'q' ||choice== 'Q' ||choice== 'n' ||choice== 'N' )
flag=0;
else choice=getch();
}
if (choice== 'n' ||choice== 'N' ){ /*开始游戏*/
clear();
move(10,25);
addstr( "BallGame will start! Are you read?" );
refresh();
sleep(3);
control();
}
else if (choice== 'q' ||choice== 'Q' ){ /*退出游戏*/
clear();
move(10,25);
addstr( "You quit the game successfully!" );
refresh();
sleep(3);
endwin();
}
endwin(); /*结束 curses*/
return 0;
}
void init(){
int i,j;
clear();
if (start_color()==OK){ /*改变球和挡板的颜色*/
attron(A_BOLD); /*打开粗体*/
init_pair(1,COLOR_YELLOW,COLOR_BLACK);
attron(COLOR_PAIR(1));
}
//初始球
pos_X =22; /*球初始的横坐标*/
pos_Y = BOTTOM-1; /*球初始的纵坐标*/
//初始化球的运动方向,朝右上方运动
hdir=1;
vdir=-1;
//初始挡板
left_board=20;
right_board=left_board+BOARD_LENGTH;
for (i=left_board;i<=right_board;i++){ /*显示挡板*/
move(BOTTOM,i);
addch( '-' );
}
//初始刷新时间
signal (SIGALRM,moveBall);
set_ticker(delay);
keypad(stdscr,TRUE); /*打开 keypad 键盘响应*/
attroff(A_BLINK); /*关闭 A_BLINK 属性*/
is_lose=0;
move(pos_Y,pos_X);
addch(BALL);
move(LINES-1, COLS-1);
refresh();
usleep(100000); /*睡眠*/
move(LINES-1,COLS-1);
refresh();
}
void moveBall(){
if (is_lose) return ;
signal (SIGALRM,moveBall);
move(pos_Y,pos_X);
addch(BLANK);
pos_X += hdir;
pos_Y += vdir;
//改变球的方向时
if (pos_X >= RIGHT) { /*当球横坐标大于右边边缘时,球反弹朝左运动*/
hdir = -1;
beep(); /*球撞墙时,发出声音*/
}
if (pos_X <= LEFT) { /*当球横坐标大于左边边缘时,球反弹朝右运动*/
hdir = 1;
beep(); /*球撞墙时,发出声音*/
}
if (pos_Y <= TOP) { /*当球纵坐标大于顶部边缘时,球反弹朝下运动*/
vdir = 1;
beep(); /*球撞墙时,发出声音*/
}
//当球在底部的时候进行额外的处理
if (pos_Y >= BOTTOM-1){
if (pos_X>=left_board&&pos_X<=right_board) /*球在挡板处*/
vdir=-1;
else { /*球不在挡板处*/
is_lose=1;
move(pos_Y,pos_X);
addch(BALL);
move(LINES-1, COLS-1);
refresh();
usleep(delay*1000); /*睡眠*/
move(pos_Y,pos_X);
addch(BLANK);
pos_X += hdir;
pos_Y += vdir;
move(pos_Y,pos_X);
addch(BALL);
move(LINES-1, COLS-1);
refresh();
}
}
//不改变球的方向时
move(pos_Y,pos_X);
addch(BALL);
move(LINES-1, COLS-1);
refresh();
}
void control(){
init();
int cmd;
while (1)
{
if (!is_lose){
cmd=getch();
if (cmd== 'q' ||cmd== 'Q' ||cmd==27) break ; //强制退出游戏
//挡板左移
if (cmd==KEY_LEFT){
if (left_board>0){
move(BOTTOM,right_board);
addch( ' ' );
right_board--;
left_board--;
move(BOTTOM,left_board);
addch( '-' );
move(BOTTOM,RIGHT);
refresh();
}
}
//挡板右移
else if (cmd==KEY_RIGHT){
if (right_board<RIGHT){
move(BOTTOM,left_board);
addch( ' ' );
right_board++;
left_board++;
move(BOTTOM,right_board);
addch( '-' );
move(BOTTOM,RIGHT);
refresh();
}
}
//给球加速
else if (cmd==KEY_UP){
delay/=2;
set_ticker(delay);
}
//给球减速
else if (cmd==KEY_DOWN){
delay*=2;
set_ticker(delay);
}
}
else {
//输掉球后的处理
int flag=1;
char choice;
move(8,15);
addstr( "Game Over!try again?(y/n):" );
refresh();
choice=getch();
while (flag){
if (choice== 'y' ||choice== 'Y' ||choice== 'n' ||choice== 'N' )
flag=0;
else choice=getch();
}
if (choice== 'y' ||choice== 'Y' ){ /*游戏重新开始*/
delay=100; /*恢复球的初始速度*/
init();
continue ;
}
else if (choice== 'n' ||choice== 'N' ){ /*结束游戏*/
break ;
}
}
}
}
//设置定时器
int set_ticker( int n_msecs){
struct itimerval new_timeset;
long n_sec,n_usecs;
n_sec=n_msecs/1000;
n_usecs=(n_msecs%1000)*1000L;
new_timeset.it_interval.tv_sec=n_sec;
new_timeset.it_interval.tv_usec=n_usecs;
new_timeset.it_value.tv_sec=n_sec;
new_timeset.it_value.tv_usec=n_usecs;
return setitimer(ITIMER_REAL,&new_timeset,NULL);
}
|
用gcc BounceBall.c -lcurses编译后,生成BounceBall.out , 运行 ./BounceBall.out , 游戏截图如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/psc0606/article/details/9990981