unix编程实践_7_事件驱动编程

2022-11-14 14:25:19 浏览数 (1)

在unxi/linux编程实践第七章的基础上完成的一个小的终端弹球游戏,先来个截图。

存在问题

  • 光标闪烁问题。

知识点

这个小游戏用到了以下几个知识点:

  • 信号处理
  • 计时器的使用
  • curses库的使用

环境&命令

  • ubuntu 18.04
  • gcc mybounce.c -o mybounce -lncurses
  • ./mybounce

代码

mybounce.c

代码语言:javascript复制
#include <stdio.h>
#include	<curses.h>
#include	<signal.h>
#include	"mybounce.h"
#include <termios.h>
#include <sys/time.h>

struct ppball the_ball ;

/**  the main loop  **/

void set_up();
void wrap_up();
int downedge1=15,downedge2=29;
bool game_over_flag=false;
static struct termios info;

int main()
{
	int	c;
	printf("33[?25l");

	set_up();

	while ( ( c = getchar()) != 'q' ){
		//if ( c == 'f' )	     the_ball.x_ttm--;
		//else if ( c == 's' ) the_ball.x_ttm  ;
		//else if ( c == 'F' ) the_ball.y_ttm--;
		//else if ( c == 'S' ) the_ball.y_ttm  ;
		if ( c == 'f' ){
			the_ball.x_ttm--;
			the_ball.y_ttm--;
		}else if(c=='s'){
			the_ball.x_ttm  ;
			the_ball.y_ttm  ;
		}else if(c=='z'){
			if(game_over_flag){
				wrap_words(10,32,15);
				wrap_words(11,27,29);
				refresh();
				move(999,999);
				set_up();
			}
		}else if(c=='j'){
			if(downedge1>11){
				mvaddch(20,downedge2,' ');
				downedge1--;
				downedge2--;
			}
		}else if(c=='k'){
			if(downedge2<69){
				mvaddch(20,downedge1,' ');
				downedge1  ;
				downedge2  ;
			}
		}
	}

	wrap_up();
	yesecho();
}

void wrap_words(int x,int y,int num_space){
	int i=0;
	for(i=0;i<num_space;i  ){
		move(x,y i);
		addch(' ');
		refresh();
	}
}

int noecho(){
	if(tcgetattr(0,&info)==-1){
		perror("tcgettattr");
		exit(1);
	}
	info.c_lflag &= ~ECHO;
	if(tcsetattr(0,TCSANOW,&info)){
		perror("setattr error");
		exit(1);
	}
}

void yesecho(){
	info.c_lflag&= ECHO;
	if(tcsetattr(0,TCSANOW,&info)){
		perror("setattr error");
		exit(1);
	}
}

void set_up()
/*
 *	init structure and other stuff
 */
{
	void	ball_move(int);

	the_ball.y_pos = Y_INIT;
	the_ball.x_pos = X_INIT;
	the_ball.y_ttg = the_ball.y_ttm = Y_TTM ;
	the_ball.x_ttg = the_ball.x_ttm = X_TTM ;
	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  );
	paintedge();
	paintline();
	noecho();
	refresh();
	
	signal( SIGALRM, ball_move );
	set_ticker( 1000 / TICKS_PER_SEC );	/* send millisecs per tick */
}

void paintedge(){
	move(4,9);
	addstr("---------------------------------------------------------------");
	int i=0;
	for(i=5;i<=20;i  ){
		move(i,9);
		addstr("|");
	}
	for(i=5;i<=20;i  ){
		move(i,71);
		addstr("|");
	}
}

void paintline(){
	for(int i=downedge1;i<=downedge2;i  ){
		move(20,i);
		addch('_');
	}
	move(999,999);
	refresh();
}

void wrap_up()
{

	set_ticker( 0 );
	endwin();		/* put back to normal	*/
}


void ball_move(int signum)
{
	int	y_cur, x_cur, moved;
	paintline();

	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 ; 
		return_val = 1 ;
	} else if ( bp->y_pos == BOT_ROW ){
		if(bp->x_pos>=downedge1 && bp->x_pos<=downedge2){	
			bp->y_dir = -1 ;
	       	return_val = 1;
			paintline();
			refresh();
		}else{
			set_ticker(1000000000);
			move(10,32);
			addstr("---GAME OVER---");
			move(11,27);
			addstr("you can press 'z',paly again.");
			refresh();
			game_over_flag=true;
		}	
	}
	if ( bp->x_pos == LEFT_EDGE ){
		bp->x_dir = 1 ;
	       	return_val = 1 ;
	} else if ( bp->x_pos == RIGHT_EDGE ){
		bp->x_dir = -1;
	       	return_val = 1;
	}

	return return_val;
}


set_ticker( 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     */

	return setitimer(ITIMER_REAL, &new_timeset, NULL);
}

mybounce.h

代码语言:javascript复制
/* 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 ;

	} ;

欢迎与我分享你的看法。 转载请注明出处:http://taowusheng.cn/

0 人点赞