#include <signal.h> #include <sys/time.h> #include <stdio.h> #include <sys/time.h> #include "header.h" void init(); void ball_move(); struct Ball ball; // 小球 struct Baffle baffle; // 挡板 int matrix[5][15]; // 记录砖块区域信息的矩阵 int is_lose = 0; // 是否输掉比赛 int num_bricks = 0; // 砖块的数量 int main() { int ch; init(); while(1) { if( !is_lose && num_bricks > 0) // 如果没赢也没输,游戏继续 { ch = getch(); if(ch == 'q') break; if(ch == 'j') // 挡板左移 { if(baffle.x_left > LEFT) { move(BOTTOM, baffle.x_right); addch(' '); baffle.x_left--; baffle.x_right--; move(BOTTOM, baffle.x_left); addch('='); move(LINES - 1, 0); refresh(); } } else if(ch == 'k') // 挡板右移 { if(baffle.x_right < RIGHT) { move(BOTTOM, baffle.x_left); addch(' '); baffle.x_left++; baffle.x_right++; move(BOTTOM, baffle.x_right); addch('='); move(LINES - 1, 0); refresh(); } } } else { int flag = 1; char choice; move(6, 10); clear(); if(is_lose) addstr("You lose.Try again?(y/n):"); else addstr("You win,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'){ init(); continue; } else if(choice=='n'||choice=='N'){ break; } } } endwin(); return 0; } void init() { /* 该函数主要完成初始化的工作 */ int i,j,k; initscr(); box(stdscr, ACS_VLINE, ACS_HLINE); crmode(); noecho(); // 初始小球信息 ball.x_poi = X_INIT_BALL; ball.y_poi = Y_INIT_BALL; ball.x_speed = X_INIT_SPEED; ball.y_speed = Y_INIT_SPEED; ball.symbol = 'O'; // 初始挡板信息 baffle.x_left = X_INIT_LEFT; baffle.x_right = X_INIT_RIGHT; baffle.speed = SPEED_INIT_BAFFLE; // 绘制砖块,并修改矩阵的值(左上到右下的部分) attron(A_REVERSE); for(i = BRICK_TOP, j = BRICK_LEFT; i <= BRICK_BOTTOM; i++, j += 3) { move(i, j); addstr(BRICK_SYMBOL); move(LINES - 1, 0); refresh(); for(k = 0; k < 3; k++) matrix[i - BRICK_TOP][j - BRICK_LEFT + k] = 1; num_bricks++; } // 左下到右上的部分 for(i = BRICK_BOTTOM, j = BRICK_LEFT; i >= BRICK_TOP; i--, j += 3) { move(i, j); addstr(BRICK_SYMBOL); move(LINES - 1, 0); refresh(); for(k = 0; k < 3; k++) matrix[i - BRICK_TOP][j - BRICK_LEFT + k] = 1; num_bricks++; } // 中间横向的部分 for(i = (BRICK_TOP + BRICK_BOTTOM) / 2, j = BRICK_LEFT; j <= BRICK_RIGHT; j += 6) { move(i, j); addstr(BRICK_SYMBOL); move(LINES - 1, 0); refresh(); for(k = 0; k < 3; k++) matrix[i - BRICK_TOP][j - BRICK_LEFT + k] = 1; num_bricks++; } attroff(A_REVERSE); move(LINES - 1, 0); refresh(); // 绘制小球和挡板 move(ball.y_poi, ball.x_poi); addch(SYMBOL_BALL); move(BOTTOM, baffle.x_left); addstr(SYMBOL_BAFFLE); move(LINES - 1, 0); refresh(); signal(SIGALRM, ball_move); set_ticker(100); } void ball_move() { /* 该函数用于实现小球移动的功能 */ int x_index, y_index; int differ; int i; signal(SIGALRM, ball_move); move(ball.y_poi, ball.x_poi); addch(BLANK_BALL); ball.x_poi += ball.x_speed; ball.y_poi += ball.y_speed; if(ball.x_poi >= RIGHT || ball.x_poi <= LEFT) ball.x_speed = -ball.x_speed; if(ball.y_poi <= TOP) ball.y_speed = -ball.y_speed; if(ball.y_poi >= BOTTOM - 1) { if(ball.x_poi >= baffle.x_left && ball.x_poi <= baffle.x_right) ball.y_speed = -ball.y_speed; else { // 输掉游戏 is_lose=1; } } // 假如小球落入砖块区域内 if(ball.x_poi >= BRICK_LEFT && ball.x_poi <= BRICK_RIGHT && ball.y_poi >= BRICK_TOP && ball.y_poi <= BRICK_BOTTOM) { x_index = ball.x_poi - BRICK_LEFT; y_index = ball.y_poi - BRICK_TOP; if(matrix[y_index][x_index] == 1) { differ = x_index % 3; for(i = 0; i < 3; i++) matrix[y_index][x_index - differ + i] = 0; move(ball.y_poi, ball.x_poi - differ); addstr(" "); move(LINES - 1, 0); refresh(); num_bricks--; ball.y_speed = -ball.y_speed; } } move(ball.y_poi, ball.x_poi); addch(SYMBOL_BALL); move(LINES - 1, 0); refresh(); } 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); }
头文件
#include <curses.h> /* 关于游戏区域的常量定义 */ #define TOP 1 // 游戏区域的上边界 #define BOTTOM LINES - 2 // 游戏区域的下边界 #define LEFT 1 // 游戏区域的左边界 #define RIGHT COLS - 2 // 游戏区域的右边界 /* * 关于挡板的常量定义 */ #define BLANK_BAFFLE " " // 用于擦除使用 #define SYMBOL_BAFFLE "========" // 挡板的字符化表示 #define X_INIT_LEFT COLS / 2 - 4 // 挡板左部 X 坐标的初始值 #define X_INIT_RIGHT COLS / 2 + 3 // 挡板右部 X 坐标的初始值 #define SPEED_INIT_BAFFLE 1 /* 关于球的常量定义 */ #define BLANK_BALL ' ' // 用于擦除使用 #define SYMBOL_BALL 'O' // 球的字符化表示 #define X_INIT_BALL COLS / 2 // 球 X 坐标的初始值 #define Y_INIT_BALL LINES - 3 // 球 Y 坐标的初始值 #define X_INIT_SPEED 1 // 球 X 坐标上的速度初始值 #define Y_INIT_SPEED -1 // 球 Y 坐标上的速度初始值 /* 关于砖块区域的常量定义 */ #define BRICK_LEFT 30 #define BRICK_RIGHT 44 #define BRICK_TOP 2 #define BRICK_BOTTOM 6 #define BRICK_SYMBOL " " struct Ball { int x_poi, y_poi; // 球的 X,Y 坐标 int x_speed, y_speed; // 球在 X,Y 方向的速度 char symbol; // 球的字符化表示 }; struct Baffle { int x_left, x_right; // 挡板的 X,Y 坐标 int length; // 挡板的长度 int speed; // 挡板的速度(仅在 X 方向上) char *symbol; // 挡板的字符化表示 };