前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >unix编程实践_7_事件驱动编程

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

作者头像
yifei_
发布2022-11-14 14:25:19
3900
发布2022-11-14 14:25:19
举报
文章被收录于专栏:yifei的专栏yifei的专栏

在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("\033[?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/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 存在问题
  • 知识点
  • 环境&命令
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档