標籤:unix環境進階編程 c語言
在linux下用c語言利用訊號機制完成了一個彈球的小遊戲,代碼如下:
bounce.h
/* bounce.h*//* some settings for the game*/#defineBLANK' '#defineDFL_SYMBOL'o'#defineTOP_ROW5#defineBOT_ROW 20#defineLEFT_EDGE10#defineRIGHT_EDGE70#defineX_INIT10/* starting col*/#defineY_INIT10/* starting row*/#defineTICKS_PER_SEC50/* affects speed*/#defineX_TTM5#defineY_TTM8/** the ping pong ball **/struct ppball {inty_pos, x_pos,y_ttm, x_ttm,y_ttg, x_ttg,y_dir, x_dir;charsymbol ;} ;
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 3struct 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;elseadd_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;elseadd_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;elsereturn 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);}
Linux C Project :pong