Linux C Project :pong
在linux下用c语言利用信号机制完成了一个弹球的小游戏,代码如下:
bounce.h
/* bounce.h */ /* some settings for the game */ #define BLANK ' ' #define DFL_SYMBOL 'o' #define TOP_ROW 5 #define BOT_ROW 20 #define LEFT_EDGE 10 #define RIGHT_EDGE 70 #define X_INIT 10 /* starting col */ #define Y_INIT 10 /* starting row */ #define TICKS_PER_SEC 50 /* affects speed */ #define X_TTM 5 #define Y_TTM 8 /** the ping pong ball **/ struct ppball { int y_pos, x_pos, y_ttm, x_ttm, y_ttg, x_ttg, y_dir, x_dir; char symbol ; } ;
pppaddle.h
struct pppaddle { int pad_top; int pad_bot; int pad_col; char pad_char; }; void paddle_init(struct pppaddle * p); int paddle_up(struct pppaddle * p); int paddle_down(struct pppaddle * p); int paddle_contact(int x,int y,struct pppaddle * p);
pong.c
#include <curses.h> #include <signal.h> #include "bounce.h" #include <stdlib.h> #include "pppaddle.h" #define MAXSPEED 10 #define MAXMODIFY 3 struct ppball the_ball; struct pppaddle the_paddle; int ball_left = 3; /** the main loop **/ void set_up(); void wrap_up(); void draw_wall(); void draw_paddle(); int main() { int c; set_up(); while (ball_left > 0 && (c = getchar()) != 'Q') { if (c == 'j') { if (paddle_down(&the_paddle) == 1) { move(the_paddle.pad_top - 1, the_paddle.pad_col); addch(' '); move(the_paddle.pad_bot, the_paddle.pad_col); addch('#'); } } if (c == 'k') { if (paddle_up(&the_paddle) == 1) { move(the_paddle.pad_bot + 1, the_paddle.pad_col); addch(' '); move(the_paddle.pad_top, the_paddle.pad_col); addch('#'); } } } wrap_up(); } void set_up() /* * init structure and other stuff */ { void ball_move(int); paddle_init(&the_paddle); the_ball.y_pos = Y_INIT; the_ball.x_pos = X_INIT; the_ball.y_ttg = the_ball.y_ttm = rand() % MAXSPEED; the_ball.x_ttg = the_ball.x_ttm = rand() % MAXSPEED; the_ball.y_dir = 1; the_ball.x_dir = 1; the_ball.symbol = DFL_SYMBOL; initscr(); noecho(); crmode(); signal( SIGINT, SIG_IGN); mvaddch(the_ball.y_pos, the_ball.x_pos, the_ball.symbol); draw_wall(); refresh(); signal( SIGALRM, ball_move); set_ticker(1000 / TICKS_PER_SEC); /* send millisecs per tick */ } void wrap_up() { set_ticker(0); endwin(); /* put back to normal */ } void ball_move(int signum) { int y_cur, x_cur, moved; signal( SIGALRM, SIG_IGN); /* dont get caught now */ y_cur = the_ball.y_pos; /* old spot */ x_cur = the_ball.x_pos; moved = 0; if (the_ball.y_ttm > 0 && the_ball.y_ttg-- == 1) { the_ball.y_pos += the_ball.y_dir; /* move */ the_ball.y_ttg = the_ball.y_ttm; /* reset*/ moved = 1; } if (the_ball.x_ttm > 0 && the_ball.x_ttg-- == 1) { the_ball.x_pos += the_ball.x_dir; /* move */ the_ball.x_ttg = the_ball.x_ttm; /* reset*/ moved = 1; } if (moved) { mvaddch(y_cur, x_cur, BLANK); mvaddch(y_cur, x_cur, BLANK); mvaddch(the_ball.y_pos, the_ball.x_pos, the_ball.symbol); bounce_or_lose(&the_ball); move(LINES - 1, COLS - 1); refresh(); } signal( SIGALRM, ball_move); /* for unreliable systems */ } int bounce_or_lose(struct ppball *bp) { int return_val = 0; if (bp->y_pos == TOP_ROW) { bp->y_dir = 1; change_the_speed(); return_val = 1; } else if (bp->y_pos == BOT_ROW) { bp->y_dir = -1; change_the_speed(); return_val = 1; } if (bp->x_pos == LEFT_EDGE) { bp->x_dir = 1; change_the_speed(); return_val = 1; } else if (paddle_contact(bp->x_pos, bp->y_pos, &the_paddle)) { bp->x_dir = -1; change_the_speed(); return_val = 1; } if(the_ball.x_pos == 71) { move(the_ball.y_pos,the_ball.x_pos); addch(' '); move(LINES - 1, COLS - 1); refresh(); bp->x_pos = 10; bp->y_pos = 10; ball_left--; if(ball_left == 0) { clear(); exit(0); } } return return_val; } void draw_wall() { int i; for (i = 9; i <= 70; i++) { move(4, i); addch('*'); } for (i = 4; i <= 21; i++) { move(i, 9); addch('*'); } for (i = 9; i <= 70; i++) { move(21, i); addch('*'); } for (i = the_paddle.pad_top; i <= the_paddle.pad_bot; i++) { move(i, the_paddle.pad_col); addch('#'); } } void draw_paddle() { int i; for (i = the_paddle.pad_top; i <= the_paddle.pad_bot; i++) { move(i, the_paddle.pad_col); addch('#'); } } void change_the_speed() { int add_or_delete = rand() % MAXSPEED; if (add_or_delete % 2 == 0) add_or_delete = 1; else add_or_delete = -1; int speed_change = rand() % MAXMODIFY; if (the_ball.x_ttm + (speed_change * add_or_delete) > 0) the_ball.x_ttm = the_ball.x_ttm + (speed_change * add_or_delete); add_or_delete = rand() % MAXSPEED; if (add_or_delete % 2 == 0) add_or_delete = 1; else add_or_delete = -1; speed_change = rand() % MAXMODIFY; if (the_ball.y_ttm + (speed_change * add_or_delete) > 0) the_ball.y_ttm = the_ball.y_ttm + (speed_change * add_or_delete); }
pppaddle.c
#include "pppaddle.h" void paddle_init(struct pppaddle * p) { p->pad_char = '#'; p->pad_col = 71; p->pad_bot = 16; p->pad_top = 11; } int paddle_up(struct pppaddle * p) { if(p->pad_top != 5) { p->pad_top--; p->pad_bot--; return 1; } return 0; // int i; // for(i = the_paddle.pad_top; i <= the_paddle.pad_bot;i++) // { // move(i,the_paddle.pad_col); // addch('#'); // } } int paddle_down(struct pppaddle * p) { if(p->pad_bot != 20) { p->pad_top++; p->pad_bot++; return 1; } return 0; // int i; // for(i = the_paddle.pad_top; i <= the_paddle.pad_bot;i++) // { // move(i,the_paddle.pad_col); // addch('#'); // } } int paddle_contact(int x,int y,struct pppaddle * p) { if(x == 70 && y <= p->pad_bot && y >= p->pad_top) return 1; else return 0; }
set_ticker.c
#include <stdio.h> #include <sys/time.h> #include <signal.h> /* * set_ticker.c * set_ticker( number_of_milliseconds ) * arranges for the interval timer to issue * SIGALRM's at regular intervals * returns -1 on error, 0 for ok * * arg in milliseconds, converted into micro seoncds */ void 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; /* set reload */ new_timeset.it_interval.tv_usec = n_usecs; /* new ticker value */ new_timeset.it_value.tv_sec = n_sec ; /* store this */ new_timeset.it_value.tv_usec = n_usecs ; /* and this */ setitimer(ITIMER_REAL, &new_timeset, NULL); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。