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+\信号,游戏结束后恢复信号
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
分。。。。割。。。。线
/×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××/
1 #include <stdio.h> 2 3 #include <stdlib.h> 4 5 #include <string.h> 6 7 #include <curses.h> 8 9 #include <signal.h> 10 11 #include "bounce.h" 12 13 #include <sys/time.h> 14 15 16 17 18 19 bool set_up( bool ); 20 21 void wrap_up(); 22 23 void ball_move(); 24 25 void show_baffle(); 26 27 void in_bound( struct BallInfo * ); 28 29 int set_ticker( int ); 30 31 bool judge_in_bound( int ,int ); 32 33 void show_baffle(); 34 35 void try_move_my_moving_baffle( char ); 36 37 void show_my_moving_baffle(); 38 39 void cover_my_moving_baffle(); 40 41 void show_score_gameon(); 42 43 void show_score_gameoff(); 44 45 void clear_up(); 46 47 void solve_sigint(); 48 49 void solve_sigquit(); 50 51 bool ball_crash_brick(); 52 53 void show_my_moving_brick( int ,int ); 54 55 void cover_my_moving_brick( int ,int ); 56 57 58 59 struct BallInfo my_moving_ball; 60 61 struct BaffleInfo my_moving_Baffle; 62 63 struct Brick my_moving_brick[2]; 64 65 int score; 66 67 68 69 void clear_up(){ 70 71 int i,j; 72 73 for( i=0;i<24;i++ ){ 74 75 for( j=0;j<80;j++ ){ 76 77 mvaddch( i,j,BLANK ); 78 79 } 80 81 } 82 83 return ; 84 85 } 86 87 /******************************************************** 88 89 clear up the whole screen 90 91 *********************************************************/ 92 93 94 95 96 97 bool set_up( bool flag ){ 98 99 char od; 100 101 my_moving_ball.x_pos = startX; 102 103 my_moving_ball.y_pos = startY; 104 105 my_moving_ball.x_Time1 = my_moving_ball.x_Time2 = X_Time; 106 107 my_moving_ball.y_Time1 = my_moving_ball.y_Time2 = Y_Time; 108 109 my_moving_ball.x_dir = 1; 110 111 my_moving_ball.y_dir = 1; 112 113 my_moving_ball.ball_symbol = BALL; 114 115 116 117 my_moving_Baffle.len = BaffleLen; 118 119 my_moving_Baffle.baffle_symbol = BaffleSymbol; 120 121 my_moving_Baffle.x = startX_; 122 123 my_moving_Baffle.y = startY_; 124 125 126 127 my_moving_brick[0].x = TopRow+DELTA; 128 129 my_moving_brick[0].y = LeftCol+1; 130 131 my_moving_brick[0].speed = speed1; 132 133 my_moving_brick[0].dir = 1; 134 135 my_moving_brick[0].flag = true; 136 137 138 139 score = 0; 140 141 142 143 initscr(); 144 145 noecho(); 146 147 crmode(); 148 149 keypad( stdscr,true ); 150 151 //attroff( A_BLINK ); 152 153 154 155 if( flag==true ){ 156 157 mvaddstr( startX-3,startY,"Do you want play game (y/n)?" ); 158 159 mvaddstr( startX-2,startY,"Press 's' to slow (x-axis)"); 160 161 mvaddstr( startX-1,startY,"Press 'f' to fast (x-axis)"); 162 163 mvaddstr( startX,startY,"Press 'S' to slow (y-axis)"); 164 165 mvaddstr( startX+1,startY,"Press 'F' to slow (y-axis)"); 166 167 mvaddstr( startX+2,startY,"Press '4' to the left"); 168 169 mvaddstr( startX+3,startY,"Press '6' to the right"); 170 171 mvaddstr( startX+4,startY,"(Please refer to the ReadMe.)"); 172 173 move( LINES-1,COLS-1 ); 174 175 refresh(); 176 177 od = getch(); 178 179 if( od=='y'||od=='Y' ){ clear_up(); } 180 181 else { 182 183 wrap_up(); 184 185 return false; 186 187 } 188 189 } 190 191 /* 游戏最开始进入界面 */ 192 193 194 195 show_score_gameon(); 196 197 198 199 signal( SIGINT,solve_sigint ); 200 201 signal( SIGQUIT,solve_sigquit ); 202 203 204 205 mvaddch( my_moving_ball.y_pos, my_moving_ball.x_pos, my_moving_ball.ball_symbol ); 206 207 show_baffle(); 208 209 show_my_moving_baffle(); 210 211 show_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); 212 213 refresh(); 214 215 216 217 signal( SIGALRM, ball_move ); 218 219 //signal( SIGALRM, brick_move ); 220 221 set_ticker( 1000 / TICKS_PER_SEC ); 222 223 return true; 224 225 } 226 227 /******************************************************** 228 229 启动二维弹球 230 231 set up the game 232 233 *********************************************************/ 234 235 236 237 238 239 void wrap_up(){ 240 241 set_ticker( 0 ); 242 243 beep(); 244 245 endwin(); 246 247 } 248 249 /******************************************************** 250 251 终止二维弹球 252 253 end up the game 254 255 *********************************************************/ 256 257 258 259 260 261 void solve_sigint(){ 262 263 mvaddstr( 2,0,"You enter ctrl+C"); 264 265 return ; 266 267 } 268 269 /******************************************************** 270 271 solve the signal :ctrl + C 272 273 *********************************************************/ 274 275 276 277 278 279 void show_my_moving_brick( int x,int y ){ 280 281 if( my_moving_brick[0].flag==true ){ 282 283 mvaddstr( x,y,BRICK ); 284 285 move( LINES-1,COLS-1 ); 286 287 } 288 289 return ; 290 291 } 292 293 void cover_my_moving_brick( int x,int y ){ 294 295 mvaddstr( x,y," " ); 296 297 move( LINES-1,COLS-1 ); 298 299 return ; 300 301 } 302 303 /******************************************************** 304 305 show my moving brick 306 307 *********************************************************/ 308 309 310 311 312 313 void solve_sigquit(){ 314 315 mvaddstr( 2,0,"You enter ctrl+\\"); 316 317 return ; 318 319 } 320 321 /******************************************************** 322 323 solve the signal :ctrl + \ 324 325 *********************************************************/ 326 327 328 329 330 331 void show_score_gameon(){ 332 333 move( 0,0 ); 334 335 addstr( Tip1 ); 336 337 char str1[ 105 ],str2[ 105 ]; 338 339 int cnt1 = 0,cnt2 = 0; 340 341 int tp = score/2; 342 343 int i; 344 345 while( tp ){ 346 347 str1[ cnt1++ ] = tp%10 + '0'; 348 349 tp /= 10; 350 351 } 352 353 for( i=cnt1-1;i>=0;i-- ){ 354 355 str2[ cnt2++ ] = str1[ i ]; 356 357 } 358 359 if( cnt2==0 ) str2[ cnt2++ ] = '0'; 360 361 str2[ cnt2 ] = '\0'; 362 363 addstr( "\nYour Score:" ); 364 365 addstr( str2 ); 366 367 move( LINES-1,COLS-1 ); 368 369 } 370 371 /******************************************************** 372 373 显示得分 374 375 show the score 376 377 *********************************************************/ 378 379 380 381 382 383 void show_score_gameoff(){ 384 385 move( 0,0 ); 386 387 addstr( Tip2 ); 388 389 char str1[ 105 ],str2[ 105 ]; 390 391 int cnt1 = 0,cnt2 = 0; 392 393 int tp = score; 394 395 int i; 396 397 while( tp ){ 398 399 str1[ cnt1++ ] = tp%10 + '0'; 400 401 tp /= 10; 402 403 } 404 405 for( i=cnt1-1;i>=0;i-- ){ 406 407 str2[ cnt2++ ] = str1[ i ]; 408 409 } 410 411 if( cnt2==0 ) str2[ cnt2++ ] = '0'; 412 413 str2[ cnt2 ] = '\0'; 414 415 move( LINES/2,COLS/3 ); 416 417 addstr( Tip2 ); 418 419 mvaddstr( LINES/2+1,COLS/3,"You can input 'P' to play again." ); 420 421 move( LINES-1,COLS-1 ); 422 423 } 424 425 /******************************************************** 426 427 show game over 428 429 *********************************************************/ 430 431 432 433 434 435 void ball_move(){ 436 437 signal( SIGALRM,SIG_IGN ); 438 439 440 441 bool moved = false; 442 443 int x_cur = my_moving_ball.x_pos; 444 445 int y_cur = my_moving_ball.y_pos; 446 447 bool crash_ed ; 448 449 450 451 int yy_cur = my_moving_brick[0].y; 452 453 if( (my_moving_brick[0].speed--)==1 ){ 454 455 my_moving_brick[0].y +=my_moving_brick[0].dir; 456 457 if( my_moving_brick[0].y+5==RightCol||my_moving_brick[0].y==LeftCol ) my_moving_brick[0].dir *= (-1); 458 459 my_moving_brick[0].speed = speed1; 460 461 } 462 463 cover_my_moving_brick( my_moving_brick[0].x,yy_cur ); 464 465 show_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); 466 467 move( LINES-1,COLS-1 ); 468 469 refresh(); 470 471 //my_moving_brick 472 473 if( my_moving_ball.x_Time1>0 && ((my_moving_ball.x_Time2--) == 1) ){ 474 475 moved = true; 476 477 my_moving_ball.x_pos += my_moving_ball.x_dir; 478 479 my_moving_ball.x_Time2 = my_moving_ball.x_Time1; 480 481 } 482 483 484 485 if( my_moving_ball.y_Time1>0 && ((my_moving_ball.y_Time2--) == 1) ){ 486 487 moved = true; 488 489 my_moving_ball.y_pos += my_moving_ball.y_dir; 490 491 my_moving_ball.y_Time2 = my_moving_ball.y_Time1; 492 493 } 494 495 496 497 if( moved == true ){ 498 499 crash_ed = ball_crash_brick(); 500 501 mvaddch( y_cur,x_cur,BLANK ); 502 503 mvaddch( my_moving_ball.y_pos,my_moving_ball.x_pos,my_moving_ball.ball_symbol ); 504 505 in_bound( &my_moving_ball ); 506 507 move( LINES-1,COLS-1 ); 508 509 refresh(); 510 511 } 512 513 signal( SIGALRM,ball_move ); 514 515 return ; 516 517 } 518 519 /******************************************************** 520 521 try move the ball 522 523 *********************************************************/ 524 525 526 527 528 529 bool ball_crash_brick(){ 530 531 if( my_moving_ball.y_pos==my_moving_brick[0].x ){ 532 533 if( my_moving_ball.x_pos>=my_moving_brick[0].y&&my_moving_ball.x_pos<=my_moving_brick[0].y+5 ){ 534 535 cover_my_moving_brick( my_moving_brick[0].x,my_moving_brick[0].y ); 536 537 my_moving_brick[0].flag = false; 538 539 return true; 540 541 } 542 543 } 544 545 else 546 547 return false; 548 549 } 550 551 /******************************************************** 552 553 when the ball crash with the brick 554 555 *********************************************************/ 556 557 558 559 560 561 void in_bound( struct BallInfo *myballPoint ){ 562 563 bool return_dir = false; 564 565 if( myballPoint->x_pos==LeftCol ){ 566 567 myballPoint->x_dir = 1; 568 569 return_dir = true; 570 571 }//left 572 573 else if( myballPoint->x_pos==RightCol ){ 574 575 myballPoint->x_dir = -1; 576 577 return_dir = true; 578 579 }//right 580 581 if( myballPoint->y_pos==TopRow ){ 582 583 myballPoint->y_dir = 1; 584 585 return_dir = true; 586 587 }//up 588 589 else if( myballPoint->y_pos==BotRow ){ 590 591 if( ((myballPoint->x_pos)>=my_moving_Baffle.y) && ((myballPoint->x_pos)<=my_moving_Baffle.y+my_moving_Baffle.len) ){ 592 593 myballPoint->y_dir = -1; 594 595 score ++; 596 597 show_score_gameon(); 598 599 return_dir = true; 600 601 } 602 603 else{ 604 605 show_score_gameoff(); 606 607 wrap_up(); 608 609 } 610 611 }//down 612 613 } 614 615 /******************************************************** 616 617 rebound the ball 618 619 *********************************************************/ 620 621 622 623 624 625 int set_ticker( int n_msecs ){ 626 627 struct itimerval new_timeset; 628 629 long n_sec, n_usecs; 630 631 632 633 n_sec = n_msecs / 1000; 634 635 n_usecs = ( n_msecs %1000 ) * 1000L; 636 637 638 639 new_timeset.it_interval.tv_sec = n_sec; 640 641 new_timeset.it_interval.tv_usec = n_usecs; 642 643 new_timeset.it_value.tv_sec = n_sec; 644 645 new_timeset.it_value.tv_usec = n_usecs; 646 647 648 649 return setitimer( ITIMER_REAL, &new_timeset, NULL ); 650 651 } 652 653 /******************************************************** 654 655 set the timer 656 657 *********************************************************/ 658 659 660 661 662 663 bool judge_in_bound( int x,int y ){ 664 665 if( x>=BotRow && x<=TopRow && y>=LeftCol && y<=RightCol ) 666 667 return true; 668 669 else 670 671 return false; 672 673 } 674 675 void show_baffle(){ 676 677 int i; 678 679 for( i=TopRow-1;i<=BotRow+1;i++ ){ 680 681 mvaddch( i,LeftCol-1,Baffle ); 682 683 mvaddch( i,RightCol+1,Baffle ); 684 685 } 686 687 for( i=LeftCol-1;i<=RightCol+1;i++ ){ 688 689 mvaddch( TopRow-1,i,Baffle ); 690 691 } 692 693 return ; 694 695 } 696 697 /******************************************************** 698 699 show the baffle 700 701 *********************************************************/ 702 703 704 705 706 707 void try_move_my_moving_baffle( char od ){ 708 709 if( od==LEFT ){ 710 711 if( my_moving_Baffle.y-1 >= LeftCol ){ 712 713 cover_my_moving_baffle(); 714 715 my_moving_Baffle.y --; 716 717 show_my_moving_baffle(); 718 719 } 720 721 } 722 723 /* left */ 724 725 if( od==RIGHT ){ 726 727 if( my_moving_Baffle.y+my_moving_Baffle.len<=RightCol ){ 728 729 cover_my_moving_baffle(); 730 731 my_moving_Baffle.y ++; 732 733 show_my_moving_baffle(); 734 735 } 736 737 } 738 739 /* right */ 740 741 } 742 743 /******************************************************** 744 745 solve my moving baffle's direction 746 747 *********************************************************/ 748 749 750 751 752 753 void cover_my_moving_baffle(){ 754 755 int i; 756 757 for( i=0;i<my_moving_Baffle.len;i++ ) 758 759 mvaddch( my_moving_Baffle.x,my_moving_Baffle.y+i,BLANK ); 760 761 return ; 762 763 } 764 765 void show_my_moving_baffle(){ 766 767 int i; 768 769 for( i=0;i<my_moving_Baffle.len;i++ ) 770 771 mvaddch( my_moving_Baffle.x,my_moving_Baffle.y+i,my_moving_Baffle.baffle_symbol ); 772 773 return ; 774 775 } 776 777 /******************************************************** 778 779 show my moving baffle 780 781 *********************************************************/ 782 783 784 785 786 787 int main(){ 788 789 char od; 790 791 792 793 bool flag = set_up( true ); 794 795 /* start the game */ 796 797 if( flag==false ) 798 799 return 0; 800 801 /* the user dont want to play the game */ 802 803 804 805 while( ( od=getch() )!='Q' ){ 806 807 if( od=='f'&&my_moving_ball.x_Time1>Min ) my_moving_ball.x_Time1 --; 808 809 else if( od=='s'&&my_moving_ball.x_Time1<Max ) my_moving_ball.x_Time1 ++; 810 811 else if( od=='F'&&my_moving_ball.y_Time1>Min ) my_moving_ball.y_Time1 --; 812 813 else if( od=='S'&&my_moving_ball.y_Time1<Max ) my_moving_ball.y_Time1 ++; 814 815 /* change the ball's speed */ 816 817 if( od=='J'&&my_moving_Baffle.len>=2 ) { 818 819 cover_my_moving_baffle(); 820 821 my_moving_Baffle.len --; 822 823 show_my_moving_baffle(); 824 825 } 826 827 else if( od=='L'&&my_moving_Baffle.y+my_moving_Baffle.len<RightCol ){ 828 829 cover_my_moving_baffle(); 830 831 my_moving_Baffle.len ++; 832 833 show_my_moving_baffle(); 834 835 } 836 837 /* change my moving baffle's len */ 838 839 if( od=='P' ) { 840 841 clear_up(); 842 843 set_up( false ); 844 845 } 846 847 /* play again the game */ 848 849 if( od==LEFT||od==RIGHT ){ 850 851 try_move_my_moving_baffle( od ); 852 853 } 854 855 /* move my moving baffle */ 856 857 } 858 859 860 861 wrap_up(); 862 863 /* end up the game */ 864 865 return 0; 866 867 }
bounce.h
1 #include<stdio.h> 2 #include<curses.h> 3 #include<stdlib.h> 4 5 #define BLANK ' ' 6 #define BALL 'o' 7 #define Baffle '#' 8 #define BaffleSymbol '_' 9 10 #define TopRow 5 11 #define BotRow 20 12 #define LeftCol 10 13 #define RightCol 70 14 15 #define startX 10 16 #define startY 10 17 /* ball start position */ 18 19 #define startX_ 21 20 #define startY_ 10 21 #define BaffleLen 7 22 /* baffle start position */ 23 24 #define scorePosx 1 25 #define scorePosy 1 26 #define Tip1 "GameOn:" 27 #define Tip2 "GameOver" 28 #define Tip3 "YourScore:" 29 30 #define TICKS_PER_SEC 25 31 32 #define X_Time 5 33 #define Y_Time 8 34 35 #define LEFT '4' 36 #define RIGHT '6' 37 38 #define Min 1 39 #define Max 12 40 41 #define foreground 34 42 #define background 0 43 #define colormode 0 44 45 #define speed1 3 46 #define speed2 3 47 48 #define BRICK "BRICK" 49 50 #define DELTA 5 51 52 struct BallInfo{ 53 int x_pos,y_pos; 54 int x_Time1,y_Time1; 55 int x_Time2,y_Time2; 56 int x_dir,y_dir; 57 char ball_symbol; 58 }; 59 60 struct BaffleInfo{ 61 int x,y,len; 62 char baffle_symbol; 63 }; 64 65 66 struct Brick{ 67 int x,y; 68 int speed; 69 int dir; 70 bool flag; 71 };