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);
}




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。