标签:
/*
fun.c源文件
*/
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#include "play.h"
#include <stdio.h>
#include <stdlib.h>
void init(void);
void exit_a(void);
void paint_boat(int);
void paint_table(int, int, int);
int settimer(int);
void move_person(int);
void win(void);
void lost(void);
struct person p1;
int beg_boat;
void main(void)
{
long ch;
init();
signal(SIGINT, SIG_IGN);
/*
设置定时器,单位出发时间初始化为20毫秒。
小球水平,垂直方向运动,以单位定时器的倍数为准,加入为x:5,则触发五次定时器,则小球横向移动一个单元格,
加速,是通过减少相应方向定时器的倍数。
*/
signal(SIGALRM, move_person );
settimer(20);
while ((ch = getch()) != ‘q‘){
if (ch == KEY_LEFT)
paint_boat(1);
if (ch == KEY_RIGHT)
paint_boat(-1);
if (ch == ‘ ‘)
signal(SIGALRM, SIG_IGN);
if (ch == ‘c‘) {
signal(SIGALRM, move_person);
settimer(20);
}
if (ch == ‘w‘) {
if (p1.y_ttm > SPEED_MIN)
p1.y_ttm--;
}
if (ch == ‘s‘) {
if (p1.y_ttm < SPEED_MAX)
p1.y_ttm++;
}
if (ch == ‘a‘) {
if (p1.x_ttm > SPEED_MIN)
p1.x_ttm--;
}
if (ch == ‘d‘) {
if (p1.x_ttm < SPEED_MAX)
p1.x_ttm++;
}
}
}
/*
退出时调用,用于恢复终端属性
*/
void exit_a(void)
{
endwin();
}
/*
初始化
*/
void init(void)
{
int n, m;
//初始化小球基本信息
p1.remain = (MINE_BOT - MINE_TOP + 1)*(MINE_RIGHT - MINE_LEFT + 1);
p1.score = 0;
//init the person
p1.pos_x = (LEFT_COL + RIGHT_COL)/2;
p1.pos_y = BOT_LINE;
p1.dir_x = LEFT;
p1.dir_y = UP;
p1.x_ttm = p1.x_ttg = 4;
p1.y_ttm = p1.y_ttg = 4;
p1.per = CHAR_PERSON;
//设置终端属性,函数来自与curses库
atexit(exit_a);
initscr();
noecho();
keypad(stdscr, TRUE);
crmode();
//paint the edge
for (n = TOP_LINE - 1; n <= (BOT_LINE + 1); n++) {
mvaddch(n, LEFT_COL - 1, CHAR_EDGE);
mvaddch(n, RIGHT_COL + 1, CHAR_EDGE);
mvaddch(n, LEFT_COL - 2, CHAR_EDGE);
mvaddch(n, RIGHT_COL + 2, CHAR_EDGE);
}
for (n = LEFT_COL - 1; n <= (RIGHT_COL + 1); n++) {
mvaddch(TOP_LINE - 1, n, CHAR_EDGE);
mvaddch(TOP_LINE - 2, n, CHAR_EDGE);
}
//paint table
paint_table( RIGHT_COL + 5, TOP_LINE + 5, 0);
//paint mine
for(n = MINE_TOP ; n <= MINE_BOT; n++)
for (m = MINE_LEFT; m <= MINE_RIGHT; m++)
mvaddch(n, m, CHAR_MINE);
// paint boat
beg_boat = (LEFT_COL + RIGHT_COL)/2 - LENGTH_BOAT/2;
paint_boat(1);
//paint the person
mvaddch(p1.pos_y, p1.pos_x, p1.per);
refresh();
}
//打印信息表,分数等,x,y为打印位置,how:0擦除,1打印
void paint_table(int x, int y, int how)
{
char tot[15];
char rem[15];
char sco[15];
char spe_x[15];
char spe_y[15];
//char s_p_x[15];
//char s_p_y[15];
//char s_d_x[15];
//char s_d_y[15];
static int flag = 0;
if (how == 0) {
mvaddstr(y, x, " ");
mvaddstr(y + 1, x, " ");
mvaddstr(y + 2, x, " ");
mvaddstr(y + 3, x, " ");
mvaddstr(y + 4, x, " ");
//mvaddstr(y + 5, x, " ");
//mvaddstr(y + 6, x, " ");
//mvaddstr(y + 7, x, " ");
} else {
sprintf(tot, "TOTAL: %d", (MINE_BOT - MINE_TOP + 1)*(MINE_RIGHT - MINE_LEFT + 1));
sprintf(rem, "REMAIN:%d", p1.remain);
sprintf(spe_x, "SPEED_X: %d", SPEED_MAX - p1.x_ttm);
sprintf(spe_y, "SPEED_Y: %d", SPEED_MAX - p1.y_ttm);
sprintf(sco, "SCORE: %d", p1.score);
//sprintf(s_p_x, "P_X: %d", p1.pos_x);
//sprintf(s_p_y, "P_Y: %d", p1.pos_y);
//sprintf(s_d_x, "D_X: %d", p1.dir_x);
//sprintf(s_d_y, "D_Y: %d", p1.dir_y);
mvaddstr(y, x, tot);
mvaddstr(y + 1, x, rem);
mvaddstr(y + 2, x, spe_x);
mvaddstr(y + 3, x, spe_y);
mvaddstr(y + 4, x, sco);
//mvaddstr(y + 4, x, s_p_x);
//mvaddstr(y + 5, x, s_p_y);
//mvaddstr(y + 6, x, s_d_x);
//mvaddstr(y + 7, x, s_d_y);
}
}
//打印短板,dir表示方向,1向左,-1向右
void paint_boat(int dir)
{
int n;
for ( n = 0; n < LENGTH_BOAT; n++)
mvaddch(BOT_LINE + 1, n + beg_boat, BLANK );
if (dir == 1 && beg_boat > LEFT_COL)
beg_boat--;
if (dir == -1 && beg_boat < (RIGHT_COL +1- LENGTH_BOAT))
beg_boat++;
for ( n = 0; n < LENGTH_BOAT; n++)
mvaddch(BOT_LINE + 1, n + beg_boat, CHAR_BOAT );
refresh();
}
//设置定时器
int settimer(int msec)
{
struct itimerval new;
long n_sec, n_usec;
n_sec = msec/1000;
n_usec = (msec%1000)*1000L;
new.it_interval.tv_sec = n_sec;//下次触发时间
new.it_interval.tv_usec = n_usec;
new.it_value.tv_sec = n_sec;//定时器间隔时间
new.it_value.tv_usec = n_usec;
return setitimer(ITIMER_REAL, &new, NULL);
}
/*
查看小球是否触碰到砖块
大砖块,分为两类,一类小球贴在砖块上,一类小球打在砖块上,不同方式对小球的运动影响不同
*/
void dig_mine(void)
{
int n_x, n_y;
static int min_val[MINE_BOT - MINE_TOP + 1][MINE_RIGHT - MINE_LEFT + 1];
n_y = p1.pos_y - MINE_TOP;
n_x = p1.pos_x - MINE_LEFT;
//打, 小球位置恰好为砖块位置,根据小球目前运动方向,四周砖块情况,决定怎么改变小球的运动状态(方向),并消除砖块,增加积分等。
if (n_x >= 0 && n_x <= (MINE_RIGHT - MINE_LEFT) && n_y >= 0 && n_y <= (MINE_BOT - MINE_TOP))
if (min_val[n_y][n_x] == MINE_HIDE) {
if (n_y - 1 >=0 && min_val[n_y - 1][n_x] == MINE_HIDE)
p1.dir_y = -p1.dir_y;
if (n_y + 1 <= (MINE_BOT - MINE_TOP) && min_val[n_y + 1][n_x] == MINE_HIDE)
p1.dir_y = -p1.dir_y;
if (n_x - 1 >= 0 && min_val[n_y][n_x - 1] == MINE_HIDE)
p1.dir_x = -p1.dir_x;
if (n_x + 1 <= (MINE_RIGHT - MINE_LEFT) && min_val[n_y][n_x + 1] == MINE_HIDE)
p1.dir_x = -p1.dir_x;
min_val[n_y][n_x] = MINE_DIG;
mvaddch(p1.pos_y, p1.pos_x, BLANK);
p1.remain--;
p1.score += (SPEED_MAX - p1.x_ttm)*(SPEED_MAX - p1.y_ttm)/10;
return;
}
//贴,小球运动方向上,下一个位置,恰好是砖块位置(重点),根据四周情况,改变小球运动状态
if (n_x + 1 >= 0 && n_x - 1 <= (MINE_RIGHT - MINE_LEFT) && n_y + 1 >= 0 && n_y - 1<= (MINE_BOT - MINE_TOP)) {
if (n_y - 1 >=0 && n_x >= 0 && n_x <= MINE_RIGHT - MINE_LEFT)
if (min_val[n_y - 1][n_x] == MINE_HIDE&& p1.dir_y == UP) {
min_val[n_y -1 ][n_x] = MINE_DIG;
mvaddch(p1.pos_y - 1, p1.pos_x, BLANK);
p1.remain--;
p1.score += (SPEED_MAX - p1.x_ttm)*(SPEED_MAX - p1.y_ttm)/10;
p1.dir_y = -p1.dir_y;
}
if (n_y + 1 <= MINE_BOT - MINE_TOP && n_x >= 0 && n_x <= MINE_RIGHT - MINE_LEFT)
if (min_val[n_y + 1][n_x] == MINE_HIDE&& p1.dir_y == DOWN) {
min_val[n_y + 1][n_x] = MINE_DIG;
mvaddch(p1.pos_y + 1, p1.pos_x, BLANK);
p1.remain--;
p1.score += (SPEED_MAX - p1.x_ttm)*(SPEED_MAX - p1.y_ttm)/10;
p1.dir_y = -p1.dir_y;
}
if (n_x - 1 >= 0 && n_y >= 0 && n_y <= MINE_BOT - MINE_TOP)
if (min_val[n_y][n_x - 1] == MINE_HIDE&& p1.dir_x == LEFT) {
min_val[n_y][n_x - 1] = MINE_DIG;
mvaddch(p1.pos_y, p1.pos_x - 1, BLANK);
p1.remain--;
p1.score += (SPEED_MAX - p1.x_ttm)*(SPEED_MAX - p1.y_ttm)/10;
p1.dir_x = -p1.dir_x;
}
if (n_x + 1 <= MINE_RIGHT - MINE_LEFT && n_y >= 0 && n_y <= MINE_BOT - MINE_TOP)
if (min_val[n_y][n_x + 1] == MINE_HIDE&& p1.dir_x == RIGHT) {
min_val[n_y][n_x + 1] = MINE_DIG;
mvaddch(p1.pos_y, p1.pos_x + 1, BLANK);
p1.remain--;
p1.score += (SPEED_MAX - p1.x_ttm)*(SPEED_MAX - p1.y_ttm)/10;
p1.dir_x = -p1.dir_x;
}
}
}
/*
小球运行判定函数
*/
void move_person(int signo)
{
signal(SIGALRM, SIG_IGN);
int flag = 0, bef_x, bef_y;
bef_x = p1.pos_x;
bef_y = p1.pos_y;
//指定次数定时器是否触发
if (p1.x_ttm > 0 && p1.x_ttg-- == 1) {
p1.x_ttg = p1.x_ttm;
flag += 2;
}
if (p1.y_ttm > 0 && p1.y_ttg-- == 1) {
p1.y_ttg = p1.y_ttm;
flag += 1;
}
if (flag > 0) {
//lost 判定小球是否越出下边界,是,则失败,结束
if (p1.dir_y == DOWN && bef_y == BOT_LINE)
if (bef_x < beg_boat || bef_x >= (beg_boat + LENGTH_BOAT)) {
paint_table(RIGHT_COL + 5, TOP_LINE + 5, 0);
paint_table(LEFT_COL + 6, TOP_LINE + 4, 1);
lost();
return;
}
else
p1.dir_y = -p1.dir_y;
//win 判定砖块被全打光,是 ,胜利,游戏结束
if (p1.remain == 0) {
paint_table(RIGHT_COL + 5, TOP_LINE + 5, 0);
paint_table(LEFT_COL + 6, TOP_LINE + 4, 1);
win();
return;
}
//小球在砖块潜在位置,才进行砖块判定
if (p1.pos_x >= MINE_LEFT - 1 && p1.pos_x <= MINE_RIGHT+1 && p1.pos_y >= MINE_TOP - 1 && p1.pos_y <= MINE_BOT+1)
dig_mine();
if (flag == 1)
p1.pos_x += p1.dir_x;
else if (flag == 2)
p1.pos_y += p1.dir_y;
else {
p1.pos_x += p1.dir_x;
p1.pos_y += p1.dir_y;
}
//打印信息表
paint_table(RIGHT_COL + 5, TOP_LINE + 5, 0);
paint_table(RIGHT_COL + 5, TOP_LINE + 5, 1);
mvaddch(bef_y, bef_x, BLANK);
//当小球,遇到上,左,右边界时,改变运行方向
if ( p1.dir_x == LEFT &&p1.pos_x == LEFT_COL)
p1.dir_x = -p1.dir_x;
if (p1.dir_x == RIGHT && p1.pos_x == RIGHT_COL)
p1.dir_x = -p1.dir_x;
if (p1.dir_y == UP &&p1.pos_y == TOP_LINE)
p1.dir_y = -p1.dir_y;
mvaddch(p1.pos_y, p1.pos_x, CHAR_PERSON);
move(LINES - 1, COLS -1);
refresh();
}
signal(SIGALRM, move_person);
}
//成功时,打印
void win(void)
{
move(TOP_LINE + 3, LEFT_COL + 20);
printw("%s", " ");
move(TOP_LINE + 4, LEFT_COL + 20);
printw("%s", "* * *** * * * * * * ** * ");
move(TOP_LINE + 5, LEFT_COL + 20);
printw("%s", " * * * * * * * * * * * * * ");
move(TOP_LINE + 6, LEFT_COL + 20);
printw("%s", " * * * * * * * * * * * * ");
move(TOP_LINE + 7, LEFT_COL + 20);
printw("%s", " * * * * * * * * * * * ** ");
move(TOP_LINE + 8, LEFT_COL + 20);
printw("%s", " * *** *** * * * * * ");
move(TOP_LINE + 9, LEFT_COL + 20);
printw("%s", " ");
refresh();
}
//失败时打印
void lost(void)
{
move(TOP_LINE + 3, LEFT_COL + 20);
printw("%s", " ");
move(TOP_LINE + 4, LEFT_COL + 20);
printw("%s", "* * *** * * * *** **** ***** ");
move(TOP_LINE + 5, LEFT_COL + 20);
printw("%s", " * * * * * * * * * * * ");
move(TOP_LINE + 6, LEFT_COL + 20);
printw("%s", " * * * * * * * * **** * ");
move(TOP_LINE + 7, LEFT_COL + 20);
printw("%s", " * * * * * * * * * * ");
move(TOP_LINE + 8, LEFT_COL + 20);
printw("%s", " * *** *** **** *** **** * ");
move(TOP_LINE + 9, LEFT_COL + 20);
printw("%s", " ");
refresh();
}
算法未经允许,请勿转载,谢谢。
标签:
原文地址:http://my.oschina.net/u/2313065/blog/477080