ReadMe:
弹球游戏按键说明(注意大小写):
Q End Up Game 游戏停止
P Play Again 再玩一次
f 速度x轴方向减速
s 速度x轴方向加速
F 速度y轴方向减速
S 速度y轴方向加速
J 移动挡板变短
L 移动挡板变长
4 移动挡板向左移动
6 移动挡板向右移动
补充说明:
游戏屏幕左上角显示当前得分和游戏状态( GameOn or GameOver )
游戏过程中忽略ctrl+c和ctrl+\信号,游戏结束后恢复信号
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
分。。。。割。。。。线
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <curses.h> #include <signal.h> #include "bounce.h" #include <sys/time.h> bool set_up( bool ); void wrap_up(); void ball_move(); void show_baffle(); void in_bound( struct BallInfo * ); int set_ticker( int ); bool judge_in_bound( int ,int ); void show_baffle(); void try_move_my_moving_baffle( char ); void show_my_moving_baffle(); void cover_my_moving_baffle(); void show_score_gameon(); void show_score_gameoff(); void clear_up(); void solve_sigint(); void solve_sigquit(); bool ball_crash_brick(); void show_my_moving_brick( int ,int ); void cover_my_moving_brick( int ,int ); struct BallInfo my_moving_ball; struct BaffleInfo my_moving_Baffle; struct Brick my_moving_brick[2]; int score; void clear_up(){ int i,j; for( i=0;i<24;i++ ){ for( j=0;j<80;j++ ){ mvaddch( i,j,BLANK ); } } return ; } /******************************************************** clear up the whole screen *********************************************************/ bool set_up( bool flag ){ char od; my_moving_ball.x_pos = startX; my_moving_ball.y_pos = startY; my_moving_ball.x_Time1 = my_moving_ball.x_Time2 = X_Time; my_moving_ball.y_Time1 = my_moving_ball.y_Time2 = Y_Time; my_moving_ball.x_dir = 1; my_moving_ball.y_dir = 1; my_moving_ball.ball_symbol = BALL; my_moving_Baffle.len = BaffleLen; my_moving_Baffle.baffle_symbol = BaffleSymbol; my_moving_Baffle.x = startX_; my_moving_Baffle.y = startY_; my_moving_brick[0].x = TopRow+DELTA; my_moving_brick[0].y = LeftCol+1; my_moving_brick[0].speed = speed1; my_moving_brick[0].dir = 1; my_moving_brick[0].flag = true; score = 0; initscr(); noecho(); crmode(); keypad( stdscr,true ); //attroff( A_BLINK ); if( flag==true ){ mvaddstr( startX-3,startY,"Do you want play game (y/n)?" ); mvaddstr( startX-2,startY,"Press 's' to slow (x-axis)"); mvaddstr( startX-1,startY,"Press 'f' to fast (x-axis)"); mvaddstr( startX,startY,"Press 'S' to slow (y-axis)"); mvaddstr( startX+1,startY,"Press 'F' to slow (y-axis)"); mvaddstr( startX+2,startY,"Press '4' to the left"); mvaddstr( startX+3,startY,"Press '6' to the right"); mvaddstr( startX+4,startY,"(Please refer to the ReadMe.)"); move( LINES-1,COLS-1 ); refresh(); od = getch(); if( od=='y'||od=='Y' ){ clear_up(); } else { wrap_up(); return false; } } /* 游戏最开始进入界面 */ show_score_gameon(); signal( SIGINT,solve_sigint ); signal( SIGQUIT,solve_sigquit ); mvaddch( my_moving_ball.y_pos, my_moving_ball.x_pos, my_moving_ball.ball_symbol ); show_baffle(); show_my_moving_baffle(); show_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); refresh(); signal( SIGALRM, ball_move ); //signal( SIGALRM, brick_move ); set_ticker( 1000 / TICKS_PER_SEC ); return true; } /******************************************************** 启动二维弹球 set up the game *********************************************************/ void wrap_up(){ set_ticker( 0 ); beep(); endwin(); } /******************************************************** 终止二维弹球 end up the game *********************************************************/ void solve_sigint(){ mvaddstr( 2,0,"You enter ctrl+C"); return ; } /******************************************************** solve the signal :ctrl + C *********************************************************/ void show_my_moving_brick( int x,int y ){ if( my_moving_brick[0].flag==true ){ mvaddstr( x,y,BRICK ); move( LINES-1,COLS-1 ); } return ; } void cover_my_moving_brick( int x,int y ){ mvaddstr( x,y," " ); move( LINES-1,COLS-1 ); return ; } /******************************************************** show my moving brick *********************************************************/ void solve_sigquit(){ mvaddstr( 2,0,"You enter ctrl+\\"); return ; } /******************************************************** solve the signal :ctrl + \ *********************************************************/ void show_score_gameon(){ move( 0,0 ); addstr( Tip1 ); char str1[ 105 ],str2[ 105 ]; int cnt1 = 0,cnt2 = 0; int tp = score/2; int i; while( tp ){ str1[ cnt1++ ] = tp%10 + '0'; tp /= 10; } for( i=cnt1-1;i>=0;i-- ){ str2[ cnt2++ ] = str1[ i ]; } if( cnt2==0 ) str2[ cnt2++ ] = '0'; str2[ cnt2 ] = '\0'; addstr( "\nYour Score:" ); addstr( str2 ); move( LINES-1,COLS-1 ); } /******************************************************** 显示得分 show the score *********************************************************/ void show_score_gameoff(){ move( 0,0 ); addstr( Tip2 ); char str1[ 105 ],str2[ 105 ]; int cnt1 = 0,cnt2 = 0; int tp = score; int i; while( tp ){ str1[ cnt1++ ] = tp%10 + '0'; tp /= 10; } for( i=cnt1-1;i>=0;i-- ){ str2[ cnt2++ ] = str1[ i ]; } if( cnt2==0 ) str2[ cnt2++ ] = '0'; str2[ cnt2 ] = '\0'; move( LINES/2,COLS/3 ); addstr( Tip2 ); mvaddstr( LINES/2+1,COLS/3,"You can input 'P' to play again." ); move( LINES-1,COLS-1 ); } /******************************************************** show game over *********************************************************/ void ball_move(){ signal( SIGALRM,SIG_IGN ); bool moved = false; int x_cur = my_moving_ball.x_pos; int y_cur = my_moving_ball.y_pos; bool crash_ed ; int yy_cur = my_moving_brick[0].y; if( (my_moving_brick[0].speed--)==1 ){ my_moving_brick[0].y +=my_moving_brick[0].dir; if( my_moving_brick[0].y+5==RightCol||my_moving_brick[0].y==LeftCol ) my_moving_brick[0].dir *= (-1); my_moving_brick[0].speed = speed1; } cover_my_moving_brick( my_moving_brick[0].x,yy_cur ); show_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); move( LINES-1,COLS-1 ); refresh(); //my_moving_brick if( my_moving_ball.x_Time1>0 && ((my_moving_ball.x_Time2--) == 1) ){ moved = true; my_moving_ball.x_pos += my_moving_ball.x_dir; my_moving_ball.x_Time2 = my_moving_ball.x_Time1; } if( my_moving_ball.y_Time1>0 && ((my_moving_ball.y_Time2--) == 1) ){ moved = true; my_moving_ball.y_pos += my_moving_ball.y_dir; my_moving_ball.y_Time2 = my_moving_ball.y_Time1; } if( moved == true ){ crash_ed = ball_crash_brick(); mvaddch( y_cur,x_cur,BLANK ); mvaddch( my_moving_ball.y_pos,my_moving_ball.x_pos,my_moving_ball.ball_symbol ); in_bound( &my_moving_ball ); move( LINES-1,COLS-1 ); refresh(); } signal( SIGALRM,ball_move ); return ; } /******************************************************** try move the ball *********************************************************/ bool ball_crash_brick(){ if( my_moving_ball.y_pos==my_moving_brick[0].x ){ if( my_moving_ball.x_pos>=my_moving_brick[0].y&&my_moving_ball.x_pos<=my_moving_brick[0].y+5 ){ cover_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); my_moving_brick[0].flag = false; return true; } } else return false; } /******************************************************** when the ball crash with the brick *********************************************************/ void in_bound( struct BallInfo *myballPoint ){ bool return_dir = false; if( myballPoint->x_pos==LeftCol ){ myballPoint->x_dir = 1; return_dir = true; }//left else if( myballPoint->x_pos==RightCol ){ myballPoint->x_dir = -1; return_dir = true; }//right if( myballPoint->y_pos==TopRow ){ myballPoint->y_dir = 1; return_dir = true; }//up else if( myballPoint->y_pos==BotRow ){ if( ((myballPoint->x_pos)>=my_moving_Baffle.y) && ((myballPoint->x_pos)<=my_moving_Baffle.y+my_moving_Baffle.len) ){ myballPoint->y_dir = -1; score ++; show_score_gameon(); return_dir = true; } else{ show_score_gameoff(); wrap_up(); } }//down } /******************************************************** rebound the ball *********************************************************/ 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 ); } /******************************************************** set the timer *********************************************************/ bool judge_in_bound( int x,int y ){ if( x>=BotRow && x<=TopRow && y>=LeftCol && y<=RightCol ) return true; else return false; } void show_baffle(){ int i; for( i=TopRow-1;i<=BotRow+1;i++ ){ mvaddch( i,LeftCol-1,Baffle ); mvaddch( i,RightCol+1,Baffle ); } for( i=LeftCol-1;i<=RightCol+1;i++ ){ mvaddch( TopRow-1,i,Baffle ); } return ; } /******************************************************** show the baffle *********************************************************/ void try_move_my_moving_baffle( char od ){ if( od==LEFT ){ if( my_moving_Baffle.y-1 >= LeftCol ){ cover_my_moving_baffle(); my_moving_Baffle.y --; show_my_moving_baffle(); } } /* left */ if( od==RIGHT ){ if( my_moving_Baffle.y+my_moving_Baffle.len<=RightCol ){ cover_my_moving_baffle(); my_moving_Baffle.y ++; show_my_moving_baffle(); } } /* right */ } /******************************************************** solve my moving baffle's direction *********************************************************/ void cover_my_moving_baffle(){ int i; for( i=0;i<my_moving_Baffle.len;i++ ) mvaddch( my_moving_Baffle.x,my_moving_Baffle.y+i,BLANK ); return ; } void show_my_moving_baffle(){ int i; for( i=0;i<my_moving_Baffle.len;i++ ) mvaddch( my_moving_Baffle.x,my_moving_Baffle.y+i,my_moving_Baffle.baffle_symbol ); return ; } /******************************************************** show my moving baffle *********************************************************/ int main(){ char od; bool flag = set_up( true ); /* start the game */ if( flag==false ) return 0; /* the user dont want to play the game */ while( ( od=getch() )!='Q' ){ if( od=='f'&&my_moving_ball.x_Time1>Min ) my_moving_ball.x_Time1 --; else if( od=='s'&&my_moving_ball.x_Time1<Max ) my_moving_ball.x_Time1 ++; else if( od=='F'&&my_moving_ball.y_Time1>Min ) my_moving_ball.y_Time1 --; else if( od=='S'&&my_moving_ball.y_Time1<Max ) my_moving_ball.y_Time1 ++; /* change the ball's speed */ if( od=='J'&&my_moving_Baffle.len>=2 ) { cover_my_moving_baffle(); my_moving_Baffle.len --; show_my_moving_baffle(); } else if( od=='L'&&my_moving_Baffle.y+my_moving_Baffle.len<RightCol ){ cover_my_moving_baffle(); my_moving_Baffle.len ++; show_my_moving_baffle(); } /* change my moving baffle's len */ if( od=='P' ) { clear_up(); set_up( false ); } /* play again the game */ if( od==LEFT||od==RIGHT ){ try_move_my_moving_baffle( od ); } /* move my moving baffle */ } wrap_up(); /* end up the game */ return 0; }
bounce.h
#include<stdio.h> #include<curses.h> #include<stdlib.h> #define BLANK ' ' #define BALL 'o' #define Baffle '#' #define BaffleSymbol '_' #define TopRow 5 #define BotRow 20 #define LeftCol 10 #define RightCol 70 #define startX 10 #define startY 10 /* ball start position */ #define startX_ 21 #define startY_ 10 #define BaffleLen 7 /* baffle start position */ #define scorePosx 1 #define scorePosy 1 #define Tip1 "GameOn:" #define Tip2 "GameOver" #define Tip3 "YourScore:" #define TICKS_PER_SEC 25 #define X_Time 5 #define Y_Time 8 #define LEFT '4' #define RIGHT '6' #define Min 1 #define Max 12 #define foreground 34 #define background 0 #define colormode 0 #define speed1 3 #define speed2 3 #define BRICK "BRICK" #define DELTA 5 struct BallInfo{ int x_pos,y_pos; int x_Time1,y_Time1; int x_Time2,y_Time2; int x_dir,y_dir; char ball_symbol; }; struct BaffleInfo{ int x,y,len; char baffle_symbol; }; struct Brick{ int x,y; int speed; int dir; bool flag; };