找回密码
 入驻
搜索
查看: 173435|回复: 6

TC写的“泡泡堂”(1)

[复制链接]
发表于 2007-5-25 18:40:22 | 显示全部楼层 |阅读模式
泡泡堂(单机两人对站版,编译器:TC 2.0)
使用方法:
        双击PAOPAO.EXE运行,如果不是全屏的话,请按Alt+Enter键使它变成全屏。
     
        玩家一:黄色的笑脸
        向上: w
        向下: s
        向左: a
        向右: d
        放泡泡:空格
        玩家二:红色的笑脸
        向上: UP(方向键)
        向下: DOWN
        向左: LEFT
        向右: RIGHT
        放泡泡:回车
        退出:
                ESC
        o: 增加泡泡个数
        上下方向的箭头: 增加泡泡的威力。
        人物被泡泡炸后就不能动了,过一段时间才能恢复,如果在这段时间被另外一个玩家碰了的话,就输了。
编程思想:
            在游戏循环中不端检查按键,对控制键执行相关操作,对其他键则忽略处理。
        对于还没有爆炸的泡泡(或刚爆炸还没有擦除的泡泡)用“队列”存储。每
        循环一次就检查“队头”元素的时间到了没有,时间到了就让它爆炸(或擦除爆炸
        痕迹)。爆炸时还要检查其爆炸范围内有没有其他的泡泡,有的话就引爆它。
                                                                           游戏策划: 王宸博
                                                                           游戏编程: 王德浩
                                                                               2004年3月17日
                                                                                               */
3月24日,增加了一些注释和空格。
/*-------------------------------------------------
   paopaodang.c -- a demo of paopaotang game
              (c) wonderful,wangchengbo 2004
-------------------------------------------------*/
/**********************************************************/
/* 程序中用到的库函数所在头文件应用 #include 命令包含进来 */
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>
#include <ctype.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <alloc.h>
/**********************************************************/

#define TIME_DELAY 3/* 人物移动的延时*/
#define WIN_DELAY 18
#define MAXQSIZE   100
#define PAO_TIME   50 /*放泡泡后,等待泡泡爆炸的时间*/
#define BLAST_TIME 10 /*爆炸消失的时间*/
#define PAOMAN_DELAY 60 /* 人被炸后恢复需要的时间 */
/*                    键盘中断函数(借用一个TC做的CS游戏中的)          */
#define KEY_Y 0x15
#define KEY_N 0x31

#define KEY_A 0x1E
#define KEY_D 0x20
#define KEY_S 0x1f
#define KEY_W 0x11
#define KEY_ESC 0x01
#define KEY_ENTER 0x1c
#define KEY_SPACE 0x39
#define KEY_UP 0x48
#define KEY_LEFT 0x4b
#define KEY_RIGHT 0x4d
#define KEY_DOWN 0x50
#define PLAY1UP KEY_W
#define PLAY1LEFT KEY_A
#define PLAY1DOWN KEY_S
#define PLAY1RIGHT KEY_D
#define PLAY1FIRE KEY_SPACE
#define PLAY2UP KEY_UP
#define PLAY2DOWN KEY_DOWN
#define PLAY2LEFT KEY_LEFT
#define PLAY2RIGHT KEY_RIGHT
#define PLAY2FIRE KEY_ENTER

void InstallKeyboard(void);
void ShutDownKeyboard(void);
void far interrupt NewInt9(void);
int GetKey(int ScanCode);
char key_state[128],key_pressed[128];
void interrupt far (*OldInt9Handler)();


void InstallKeyboard(void)          /*键盘中断程序*/
{
int i;
for(i=0;i<128;i++)
key_state=key_pressed=0;
OldInt9Handler = getvect(9);         /*中断向量值*/
setvect(9,NewInt9);                /*中断程序NewInt9地址存入指定的中断向量表中INT 09H*/
}

void ShutDownKeyboard(void)
{
setvect(9,OldInt9Handler);
}

void far interrupt NewInt9(void)
{
unsigned char ScanCode,temp;
ScanCode=inportb(0x60);
temp=inportb(0x61);
outportb(0x61,temp | 0x80);
outportb(0x61,temp & 0x7f);
if(ScanCode&0x80)
   {
    ScanCode&=0x7f;
    key_state[ScanCode]=0;
   }
else
   {
    key_state[ScanCode]=1;
    key_pressed[ScanCode]=1;
   }
outportb(0x20,0x20);
}

int GetKey(int ScanCode)
{
int res;
res=key_state[ScanCode]|key_pressed[ScanCode];
key_pressed[ScanCode]=0;
return res;
}

/*>>>>>>>>>>>> Man function -- copyright Wonderful and WangChengBo <<<<<<<<<<<<<*/
typedef enum
{
    PLAY1=1, PLAY2
}which_play;

typedef enum
{
    CAN,
    CANNOT
}MOVE;
typedef struct
{
    int x, y;           /*the position of the man */
    which_play which;    /* play1 or play2?*/
    MOVE can_move;      /* can man move? */
    int len;           /*paopao's length*/
    int pao_num;           /* how many pao can the man fire?*/
    int old_time;      /* 人被泡泡炸后,恢复的时间 */
}man;
/*画人函数*/
DrawMan(man m)
{
    gotoxy(m.x+15, m.y+6);
    if (m.which == PLAY1)
    {
        textcolor(YELLOW);
    }
    else
    {
        textcolor(LIGHTRED);
    }
    putch(2);
}
/*画空心的人的函数*/
DrawPaoMan(man m)
{
    gotoxy(m.x+15, m.y+6);
    if (m.which == PLAY1)
    {
        textcolor(YELLOW);
    }
    else
    {
        textcolor(LIGHTRED);
    }
    putch(1);
}
/*擦除人的函数*/
EraseMan(man m)
{
    gotoxy(m.x+15, m.y+6);
    textcolor(BLACK);
    putch(' ');
}
/*画泡泡的函数*/
DrawPao(int x, int y)
{
    gotoxy(x+15, y+6);
    textcolor(LIGHTBLUE);
    putch('O');
}
/*画爆炸的#号的函数*/
DrawBlast1(int x, int y)
{
    gotoxy(x+15, y+6);
    textcolor(LIGHTBLUE);
    putch('#');
}


   
/*游戏开头显示的字符*/
char name[8][26] =
{
" O   O          O   O   ",
"  O OOOOOO       O OOOOOO",
"     OOO O          OOO O",
" O   O O O
 楼主| 发表于 2007-5-25 18:40:50 | 显示全部楼层
O   O O O",
"  O  OOO O       O  OOO O",
"     O  OO          O  OO",
" O   O    O     O   O    O",
"O    OOOOOO    O    OOOOOO"
};
int Name_X = 26;
int Name_Y = 8;

void DrawBegin()
{
    int x, y;
    for (y=0; y<Name_Y; ++y)
    {
        for(x=0; x<Name_X; ++x)
        {
            gotoxy(x+21, y+5);
            textcolor(LIGHTBLUE);
            putch(name[y][x]);
        }
    }

    gotoxy(19, 20);
    printf("Press any key to Enter the game!");
}
/*游戏地图,#为墙壁,@为箱子,试着自己改改*/
char map1[8][17] =
{"#################",
"# @@@@   @ #@# ##",
"# #@#@#@  @@@   #",
"#  @@@  @@ #@#@##",
"#@#@#@#@  @@@@@@#",
"#@@@@@   @@#@#@##",
"#@#@#@#@@  @@@@@#",
"#################"};
int Map_X = 17;
int Map_Y = 8;

char map[8][17];


void DrawMap()
{

        int x, y;
    for (y=0; y<Map_Y; ++y)
    {
        for(x=0; x<Map_X; ++x)
        {
            gotoxy(x+15, y+6);
            if(map[y][x] == '#')
            {
              textcolor(GREEN);
              putch(219);
             }
           else if(map[y][x] == '@')
           {
              textcolor(BROWN);
              putch(178);
           }
           else
                putch(' ');
         }
    }
    textcolor(BLUE);
    gotoxy(48, 4);
    printf("Player1 key:");
        gotoxy(48, 5);
    printf("  UP----w");
        gotoxy(48, 6);
    printf("  DOWN--s");
        gotoxy(48, 7);
    printf("  LEFT--a");
        gotoxy(48, 8);
    printf("  RIGHT-d");
        gotoxy(48, 9);
    printf("  FIRE--space");
    gotoxy(48, 11);
        printf("Player2 key:");
        gotoxy(48, 12);
    printf("  UP----up");
    gotoxy(48, 13);
        printf("  DOWN--down");
    gotoxy(48, 14);
        printf("  LEFT--left");
    gotoxy(48, 15);
        printf("  RIGHT-right");
    gotoxy(48, 16);
        printf("  FIRE--ENTER");
    gotoxy(48, 18);
        printf("exit game:");
        gotoxy(48, 19);
    printf("  ESC");

    gotoxy(38, 2);
    textcolor(LIGHTRED);
    putch('P');
    putch('A');
    putch('O');
    putch('P');
    putch('A');
    putch('O');

}

/*炸箱子后,出宝物的函数*/
Treasure(int x, int y)
{
    int i;
   
    i = random(15);

    if (i > 10)
    {
        switch (i)
        {
        case 11:
        case 12:
            map[y][x] = 'O';
            gotoxy(x+15, y+6);
            textcolor(YELLOW);
            putch('o');
            break;
        case 13:
        case 14:
            map[y][x] = '-';
            gotoxy(x+15, y+6);
            textcolor(YELLOW);
            putch(18);
            break;
        default:
            break;
        }
    }
    else
    {
        map[y][x] = ' ';
        gotoxy(x+15, y+6);
        putch(' ');
    }

}

/*人物m向上移动的函数*/
int MoveUp(man *m, man *p)
{
    if (map[m->y - 1][m->x] == '#' || map[m->y - 1][m->x] == '@'
        || map[m->y - 1][m->x] == 'o' || m->can_move == CANNOT)
    {
        return 1;
    }

    EraseMan(*m);

    if (map[m->y][m->x] == 'o')
    {
        DrawPao(m->x, m->y);
    }


    --(m->y);
    DrawMan(*m);

    switch (map[m->y][m->x])
    {
    case 'a':
    case 'b':
        m->can_move = CANNOT;
        m->old_time = clock();
        break;
    case 'O':
        ++(m->pao_num);
        map[m->y][m->x] = ' ';
        break;
    case '-':
        ++(m->len);
        map[m->y][m->x] = ' ';
        break;
    default:
        break;
    }

    if (m->x == p->x && m->y == p->y && p->can_move == CANNOT)
    {
        gotoxy(36, 3);
        printf("Play%d Win!!", m->which);
        return 0;
    }

    return 1;
}

/*人物m向下移动的函数*/
int MoveDown(man *m, man *p)
{
    if (map[m->y + 1][m->x] == '#' || map[m->y + 1][m->x] == '@'
        || map[m->y + 1][m->x] == 'o' || m->can_move == CANNOT)
    {
        return 1;
    }
    EraseMan(*m);

    if (map[m->y][m->x] == 'o')
    {
        DrawPao(m->x, m->y);
    }


    ++(m->y);
    DrawMan(*m);
   
    switch (map[m->y][m->x])
    {
    case 'a':
    case 'b':
        m->can_move = CANNOT;
        m->old_time = clock();
        break;
    case 'O':
        ++(m->pao_num);
回复

使用道具 举报

 楼主| 发表于 2007-5-25 18:41:25 | 显示全部楼层
;    map[m->y][m->x] = ' ';
        break;
    case '-':
        ++(m->len);
        map[m->y][m->x] = ' ';
        break;
    default:
        break;
    }
   
    if (m->x == p->x && m->y == p->y && p->can_move == CANNOT)
    {
        gotoxy(36, 3);
        printf("Play%d Win!!", m->which);
        return 0;
    }

    return 1;
        
        
}

/*人物m向左移动的函数*/
int MoveLeft(man *m, man *p)
{
    if (map[m->y][m->x - 1] == '#' || map[m->y][m->x - 1] == '@'
        || map[m->y][m->x - 1] == 'o' || m->can_move == CANNOT)
    {
        return 1;
    }
    EraseMan(*m);

    if (map[m->y][m->x] == 'o')
    {
        DrawPao(m->x, m->y);
    }


    --(m->x);
    DrawMan(*m);

    switch (map[m->y][m->x])
    {
    case 'a':
    case 'b':
        m->can_move = CANNOT;
        m->old_time = clock();
        break;
    case 'O':
        ++(m->pao_num);
        map[m->y][m->x] = ' ';
        break;
    case '-':
        ++(m->len);
        map[m->y][m->x] = ' ';
        break;
    default:
        break;
    }

    if (m->x == p->x && m->y == p->y && p->can_move == CANNOT)
    {
        gotoxy(36, 3);
        printf("Play%d Win!!", m->which);
        return 0;
    }

    return 1;
}

/*人物m向右移动的函数*/
int MoveRight(man *m, man *p)
{
    if (map[m->y][m->x + 1] == '#' || map[m->y][m->x + 1] == '@'
        || map[m->y][m->x + 1] == 'o' || m->can_move == CANNOT)
    {
        return 1;
    }

    EraseMan(*m);

    if (map[m->y][m->x] == 'o')
    {
        DrawPao(m->x, m->y);
    }


    ++(m->x);
    DrawMan(*m);

    switch (map[m->y][m->x])
    {
    case 'a':
    case 'b':
        m->can_move = CANNOT;
        m->old_time = clock();
        break;
    case 'O':
        ++(m->pao_num);
        map[m->y][m->x] = ' ';
        break;
    case '-':
        ++(m->len);
        map[m->y][m->x] = ' ';
        break;
    default:
        break;
    }

    if (m->x == p->x && m->y == p->y && p->can_move == CANNOT)
    {
        gotoxy(36, 3);
        printf("Play%d Win!!", m->which);
        return 0;
    }

    return 1;
}

/*>>>>>>>>>>> paopao functions -- copyright wonderful and WangChengBo <<<<<<<<<<<<*/
/*泡泡的数据结构*/
typedef struct
{
    int x;
    int y;
    int original_time;
    int len;
    which_play which;
}PAO;

/*--------------------------------------------------------------*/
/*以下为链表队列*/
typedef PAO QElemType;

typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;

typedef struct
{
    QueuePtr  front; /*队头,最早出队列的一端*/
    QueuePtr  rear; /*队尾,允许插入的一端*/
}LinkQueue;

void InitalQueue(LinkQueue *Q)
{
    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
    Q->front->next = NULL;
}


int EnQueue(LinkQueue *Q, QElemType e)
{
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));

    if (p == NULL)
    {
        return 0;
    }

    p->data = e;
    p->next = NULL;
    Q->rear->next = p;
    Q->rear = p;
    return 1;
}

int QueueHead(LinkQueue *Q, QElemType *e)
{
    if (Q->front == Q->rear)
    {
        return 0;
    }

    *e = Q->front->next->data;
    return 1;
}

int FindElemDelete(LinkQueue *Q, QElemType *e, int x, int y)
{
    QueuePtr p, q = Q->front;

    for (p = Q->front->next; p != 0; p = p->next)
    {
        if (p->data.x == x && p->data.y == y)
        {
            q->next = p->next;
            *e = p->data;
            
            if (p == Q->rear)
            {
                Q->rear = q;
            }

            free(p);
            return 1;
        }
        else
        {
            q = p;
        }
    }
    return 0;
}


int DeQueue(LinkQueue *Q)
{
    QueuePtr p;

    if (Q->front == Q->rear)
    {
        return 0;
    }

    p = Q->front->next;
    Q->front->next = p->next;

    if (Q->rear == p)
    {
        Q->rear = Q->front;
    }
    free(p);
    return 1;
}


void DestroyQueue(LinkQueue *Q)
{
    while (Q->front)
    {
        Q->rear = Q->front->next;
        free(Q->front);
        Q->front = Q->rear;
    }
}

/*放泡泡的函数*/
void Paopao(man *m, LinkQueue *Q)
{
    PAO pao;
    if (m->can_move == CANNOT || m->pao_num == 0)
    {
        return;
    }
    DrawPaoMan(*m);
    map[m->y][m->x] = 'o';
    pao.x = m->x;
    pao.y = m->y;
    pao.original_time = clock();
    pao.len = m->len;
    pao.which = m->which;

    --m->pao_num;

    /*入队列 */
    EnQueue(Q, pao);
}

/*泡泡
回复

使用道具 举报

 楼主| 发表于 2007-5-25 18:41:50 | 显示全部楼层
爆炸的函数*/
void PaoBlast(PAO pao, man *p1, man *p2, LinkQueue *Q, LinkQueue *B)
{
    int i = 1, end = 0;
    PAO e;

    switch (pao.which)
    {
        case PLAY1:
            ++(p1->pao_num);
            break;
        case PLAY2:
            ++(p2->pao_num);
            break;
    }

    DrawBlast1(pao.x, pao.y);
    map[pao.y][pao.x] = 'b';
   
    if (p1->x == pao.x && p1->y == pao.y)
    {
        DrawPaoMan(*p1);
        p1->can_move = CANNOT;
        p1->old_time = clock();
    }
    else if (p2->x == pao.x && p2->y == pao.y)
    {
        DrawPaoMan(*p2);
        p2->can_move = CANNOT;
        p2->old_time = clock();
    }
   
    /*--------------------Up----------------------*/
    for (; i <= pao.len; ++i)
    {
        end = 0;
        
        switch (map[pao.y-i][pao.x])
        {
        case '#':
            end = 1;
            break;

        case ' ':
            DrawBlast1(pao.x, pao.y-i);
            map[pao.y-i][pao.x] = 'b';
            break;

        case '@':
            end = 1;
            DrawBlast1(pao.x, pao.y-i);
            map[pao.y-i][pao.x] = 'a';
            break;

        case 'o':
            if (FindElemDelete(Q, &e, pao.x, pao.y-i) == 1)
            {
                e.original_time = clock();
                EnQueue(B, e);
                PaoBlast(e, p1, p2, Q, B);
            }
            break;
        
        default:
            break;
        }
   
        if (p1->x == pao.x && p1->y == pao.y-i)
        {
            DrawPaoMan(*p1);
            p1->can_move = CANNOT;
            p1->old_time = clock();
        }
        else if (p2->x == pao.x && p2->y == pao.y-i)
        {
            DrawPaoMan(*p2);
            p2->can_move = CANNOT;
            p2->old_time = clock();
        }
        
        if (end == 1)
        {
            break;
        }
    }
回复

使用道具 举报

发表于 2007-5-25 19:04:37 | 显示全部楼层
好长啊。。
回复

使用道具 举报

发表于 2007-5-25 19:04:56 | 显示全部楼层
应该上传个成品上来。
回复

使用道具 举报

发表于 2007-5-25 20:11:46 | 显示全部楼层
超长~~~~~~~~~~~~~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 入驻

本版积分规则

QQ|Archiver|手机版|小黑屋|思明论坛

GMT+8, 2024-9-28 17:34 , Processed in 0.010958 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表