一个游戏代码问题
/** Brick & Ball
* by Jerry Fleming <jerryfleming2006@
*
* This is a small game inspired from similar one in Motorola Mobile C289,
* and my first REAL program in C :) Please tell me if you have a better
* implementation or any suggestions.
*
* HISTORY:
* 2006-10-25: third (current) version with c language
* 2006-10-01: second version with tkinter
* 2006-04-19: first version with curses
*
* TODO:
* Nothing to do right now. :) If you have any ideas to improve or enhance it,
* please contact me.
*/
#include <stdio.h>
#include <string.h>
#include <ncurses.h>
#include <stdlib.h> /* for exit(), rand(), abs() */
#include <stddef.h> /* for NULL */
#include <time.h> /* for sleep() */
#include <signal.h> /* for SIGWINCH */
#define NORMAL 1 /* status of game */
#define PAUSE 2
#define OVER 3
#define QUIT 4
#define BLOCK 1 /* color pairs */
#define TXT 2
#define BAR 3
#define BALL 4
#define CLEAR 5
extern unsigned int sleep(unsigned int seconds);
/*
* globals
*/
int speed = 10;
int cnt = 0; /* bricks yet remain on board */
int score = 0;
int level = 0;
int width = 40;
int height = 50; /* for the board */
short state = NORMAL; /* see define */
char *statestr = "Normal"; /* additional str to explain the game status */
const int bw = 7; /* brick width */
const char brick[] = " ";
int bricks[100][3];
int pad;
int ball[2];
int dir[2] = { 1, -1 };
int ch = 0; /* user command */
/*
+-- 62 lines: * text strings -------------------------------------------------------------------------------------------------------------
*/
/*
* change sceen size, exit if too small
*/
void resizescr(int sig)
{
statestr = "Screen resized.";
getmaxyx(stdscr, height, width);
} /* resizescr() */
/*
* print msg on center of screen, exit on pressing Y or N (key is true) or any
* char (key false)
*/
bool print_msg(char *msg, bool y_n_key, bool clearmsg)
{
char *rest;
char *str[30];
char emptystr[width];
int line = 0;
int i;
int length;
int left;
int top;
char delimiters[] = "\n";
length = strlen(str[line] = strtok(msg, delimiters));
while ((rest = strtok(NULL, delimiters)) != NULL) {
line++;
if (length < strlen(rest))
length = strlen(rest);
str[line] = rest;
}
top = (height - line) / 2;
left = (width - length) / 2;
attrset(COLOR_PAIR(TXT));
for (i = 0; i <= line; i++) {
mvprintw(top++, left, "%s", str[i]);
}
refresh();
timeout(3000);
for (;;) {
ch = getch();
if (y_n_key)
break;
else {
if (ch == ERR || ch == 'y' || ch == 'Y') {
ch = 'Y';
break;
}
if (ch == 'n' || ch == 'N') {
ch = 'N';
break;
}
}
}
if (clearmsg) {
top = (height - line) / 2;
attrset(COLOR_PAIR(CLEAR));
for (i = 0; i < width; i++)
emptystr[i] = ' ';
for (i = 0; i <= line; i++) {
mvaddstr(top++, 0, emptystr);
}
refresh();
}
i = ch, ch = 0; /* clear input for later use */
timeout(100);
if (i == 'N')
return FALSE;
return TRUE;
} /* print_msg() */
/*
* draw pad, ball, bricks, and bar together
*/
void draw_board(void)
{
int i, j;
char barstr[width];
level++;
cnt = 0;
dir[0] = 1, dir[1] = -1;
/* brick */
i = width % (bw + 1) / 2; /* width -1 + gap */
j = 1;
attrset(COLOR_PAIR(BLOCK));
for (;;) {
mvaddstr(j, i, brick);
bricks[cnt][0] = i;
bricks[cnt][1] = j;
bricks[cnt][2] = 1;
i = i + bw + 1;
cnt++;
if (i >= width - bw) {
if (cnt > 50)
break;
i = width % (bw + 1) / 2;
j += 2;
}
}
bricks[cnt][2] = -1; /* mark the end or all bricks */
if (level == 1) {
/* pad */
attrset(COLOR_PAIR(BLOCK));
pad = rand() % (width - bw - 1);
mvaddstr(height - 2, pad, brick);
/* bar */
for (i = 0; i < width; i++)
barstr[i] = ' ';
attrset(COLOR_PAIR(BAR));
mvaddstr(height - 1, 0, barstr);
mvprintw(height - 1, 0, "SCORE: %03d LEVEL: %d STATE: %-9s", score,
level, statestr);
}
/* ball */
attrset(COLOR_PAIR(BALL));
ball[0] = pad, ball[1] = height - 3;
while (abs(ball[0] - pad) < 15)
ball[0] = rand() % (width - bw - 1);
mvaddstr(ball[1], ball[0], " ");
refresh();
} /* draw_board() */
/*
* try to stop game
*/
void quit_game(const int ch)
{
if (ch == 'q') {
if (cnt < 0 /* do not want another level */
|| (cnt > 0 && print_msg(tExit, FALSE, TRUE)) /* really meant to
* exit */
) {
state = QUIT;
statestr = "Quit game";
}
} else if (ch == 'o') {
state = OVER;
statestr = "Game over";
print_msg(tOver, TRUE, FALSE);
} else if (state == PAUSE) {
state = NORMAL;
statestr = "Normal";
} else {
state = PAUSE;
statestr = "Pause";
}
/* bar */
attrset(A_NORMAL | COLOR_PAIR(BAR));
mvprintw(height - 1, 0, "SCORE: %03d LEVEL: %d STATE: %-9s", score, level,
statestr);
refresh();
} /* quit_game() */
/*
2 * move the ball forward, turn if necessary, add scores, and quite if hit ground
*/
void move_ball()
{
int i;
if (state != NORMAL)
return;
/* ball */
attrset(A_REVERSE | COLOR_PAIR(BALL));
mvaddstr(ball[1], ball[0], " ");
/* restore pad after hit */
attrset(A_NORMAL | COLOR_PAIR(BLOCK));
mvaddstr(height - 2, pad, brick);
ball[0] += dir[0], ball[1] += dir[1];
attrset(A_NORMAL | COLOR_PAIR(BALL));
mvaddstr(ball[1], ball[0], " ");
/* change direction */
if (ball[1] < 0)
dir[1] = -dir[1];
if (ball[0] < 0 || ball[0] > width)
dir[0] = -dir[0];
/* hit bricks */
attrset(A_REVERSE | COLOR_PAIR(BLOCK));
for (i = 0;; i++) {
if (bricks[i][2] == -1)
break;
if (bricks[i][2] == 0)
continue;
if (bricks[i][0] <= ball[0]
&& bricks[i][0] + bw >= ball[0]
&& bricks[i][1] == ball[1]
) {
bricks[i][2] = 0;
/*
* tricky: make sure the direction is top-down
*/
dir[1] = abs(dir[1]);
score += 10;
cnt--;
refresh();
mvaddstr(bricks[i][1], bricks[i][0], brick);
if (cnt <= 0) { /* another level */
if (print_msg(tGoon, FALSE, TRUE)) {
draw_board();
} else {
quit_game('q');
}
}
}
}
/* hit pad */
if (ball[1] == height - 2) {
if (ball[0] < pad || ball[0] > pad + bw)
quit_game('o');
/*
* for some reason, the ball may enter the pad, and change dir will not
* get it out, so use abs() to turn back
*/
dir[1] = -abs(dir[1]);
if (ball[0] == pad || ball[0] == pad + bw) { /* on both ends */
dir[0] = -dir[0];
}
}
/* bar */
attrset(A_NORMAL | COLOR_PAIR(BAR));
mvprintw(height - 1, 0, "SCORE: %03d LEVEL: %d STATE: %-9s", score, level,
statestr);
refresh();
} /* move_ball() */
/*
* move pad to left or right according to command
*/
int move_pad(const int ch)
{
int move;
switch (ch) {
case KEY_LEFT:
move = -2;
break;
case KEY_RIGHT:
move = 2;
break;
case 'q':
quit_game(ch);
break;
case 'p':
quit_game(ch);
break;
default:
return 0;
}
attrset(A_REVERSE | COLOR_PAIR(BLOCK));
mvaddstr(height - 2, pad, brick);
pad = pad + move;
if (pad < 0)
pad = 0;
if (pad > width - bw)
pad = width - bw;
attrset(A_NORMAL | COLOR_PAIR(BLOCK));
mvaddstr(height - 2, pad, brick);
refresh();
return 0;
} /* move_pad() */
/*
* main
*/
int main(void)
{
initscr();
start_color();
init_pair(BLOCK, COLOR_BLACK, COLOR_RED); /* for bricks and pad */
init_pair(TXT, COLOR_CYAN, COLOR_BLACK); /* for text strings */
init_pair(BAR, COLOR_WHITE, COLOR_BLUE); /* for bar */
init_pair(BALL, COLOR_BLACK, COLOR_WHITE); /* for ball */
init_pair(CLEAR, COLOR_BLACK, COLOR_BLACK); /* to clear objects */
noecho();
raw(); /* disable line buffering */
timeout(100);
cbreak();
keypad(stdscr, TRUE);
curs_set(0);
getmaxyx(stdscr, height, width);
signal(SIGWINCH, resizescr);
if (height >= 20 && width >= 80) {
print_msg(tStart, TRUE, TRUE);
clear();
draw_board();
for (;;) {
ch = getch();
move_ball();
if (ch != ERR)
move_pad(ch);
if (state == OVER || state == QUIT)
break;
}
} else { /* screen too small, exit with complaint */
state = QUIT;
statestr = "Screen too small. Game aborted.";
}
sleep(1), flash();
sleep(1), flash();
sleep(1), flash();
curs_set(1);
keypad(stdscr, FALSE);
nocbreak();
notimeout(stdscr, TRUE);
noraw();
echo();
endwin();
puts(statestr);
exit(0);
} /* main() */
/*
* Local variables:
* tab-width: 4
* indent-tabs-mode: nil
* c-basic-offset: 4
* End:
* VIM: tw=80:sw=4:sts=4:fdm=marker
*/
错误提示[Error] D:\Program Files\C-Free 4\temp\未命名1.cpp:21: ncurses.h: No such file or directory
要怎么改呀?请高手回答下,谢谢啦。