⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 els.c

📁 C语言源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *俄罗斯方块源程序
 */
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>  /*图形函数库*/

/*定义按键码*/
#define VK_LEFT  0x4b00
#define VK_RIGHT 0x4d00
#define VK_DOWN  0x5000
#define VK_UP    0x4800
#define VK_ESC   0x011b
#define TIMER 0x1c      /*设置中断号*/

/*定义常量*/
#define MAX_BOX 19          /*总共有19种各形态的方块*/
#define BSIZE 20            /*方块的边长是20个象素*/
#define Sys_x 160           /*显示方块界面的左上角x座标*/
#define Sys_y 25            /*显示方块界面的左上角y座标*/
#define Horizontal_boxs 10  /*水平的方向以方块为单位的长度*/
#define Vertical_boxs 15    /*垂直的方向以方块为单位的长度,也就说长是15个方块*/
#define Begin_boxs_x Horizontal_boxs/2  /*产生第一个方块时出现的起始位置*/

#define FgColor 3       /*前景颜色,如文字.2-green*/
#define BgColor 0       /*背景颜色.0-blac*/

#define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46        /*右边状态栏的x座标*/

#define false 0
#define true 1
/*移动的方向*/
#define MoveLeft 1
#define MoveRight 2
#define MoveDown 3
#define MoveRoll 4
/*以后坐标的每个方块可以看作是像素点是BSIZE*BSIZE的正方形*/
/*定义全局变量*/
int current_box_numb;   /*保存当前方块编号*/
int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;/*x,y是保存方块的当前坐标的*/
int flag_newbox=false;  /*是否要产生新方块的标记0*/
int speed=0;            /*下落速度*/
int score=0;            /*总分*/
int speed_step=30;       /*每等级所需要分数*/
void interrupt (*oldtimer)(void);/* 指向原来时钟中断处理过程入口的中断处理函数指针 */

struct BOARD            /*游戏底板结构,表示每个点所具有的属性*/
{
    int var;            /*当前状态 只有0和1,1表示此点已被占用*/
    int color;          /*颜色,游戏底板的每个点可以拥有不同的颜色.增强美观*/
}Table_board[Vertical_boxs][Horizontal_boxs];

/*方块结构*/
struct SHAPE
{
    char box[2];            /*一个字节等于8位,每4位来表示一个方块的一行
                              如:box[0]="0x88",box[1]="0xc0"表示的是:
                              1000
                              1000
                              1100
                              0000*/
    int color;              /*每个方块的颜色*/
    int next;               /*下个方块的编号*/
};


/*初始化方块内容.即定义MAX_BOX个SHAPE类型的结构数组,并初始化*/
struct SHAPE shapes[MAX_BOX]=
{
/*
 *   口     口口口   口口      口
 *   口     口         口  口口口
 *   口口              口        
 */

    {0x88,  0xc0,   CYAN,   1},
    {0xe8,  0x0,    CYAN,   2},
    {0xc4,  0x40,   CYAN,   3},
    {0x2e,  0x0,    CYAN,   0},
/*
 *   口        口口 口口口
 *   口 口     口       口
 * 口口 口口口 口    
 */
    {0x44,  0xc0,   MAGENTA,  5},
    {0x8e,  0x0,    MAGENTA,  6},
    {0xc8,  0x80,   MAGENTA,  7},
    {0xe2,  0x0,    MAGENTA,  4},

/*
 *   口
 *   口口         口口
 *     口       口口
 */
    {0x8c,  0x40,   YELLOW, 9},
    {0x6c,  0x0,    YELLOW, 8},

/*
 *   口        口口
 * 口口          口口
 * 口
 */
    {0x4c,  0x80,   BROWN,  11},
    {0xc6,  0x0,    BROWN,  10},

/*
 *   口       口                口
 * 口口口     口口   口口口   口口
 *            口       口       口
 */
    {0x4e,  0x0,    WHITE,  13},
    {0x8c,  0x80,   WHITE,  14},
    {0xe4,  0x0,    WHITE,  15},
    {0x4c,  0x40,   WHITE,  12},

/* 口
 * 口
 * 口       口口口口
 * 口
 */
    {0x88,  0x88,   RED,    17},
    {0xf0,  0x0,    RED,    16},

/*
 * 口口
 * 口口
 */

    {0xcc,  0x0,    BLUE,   18}

};


unsigned int TimerCounter=0;  /*定时计数器变量*/

/* 新的时钟中断处理函数 */
void interrupt newtimer(void)
{
    (*oldtimer)();   /* call the old routine */
    TimerCounter++;/* increase the global counter */
}

/* 设置新的时钟中断处理过程 */
void SetTimer(void interrupt(*IntProc)(void))
{
    oldtimer=getvect(TIMER); /*获取中断号为TIMER的中断处理函数的入口地址*/
    disable(); /* 设置新的时钟中断处理过程时,禁止所有中断 */
    setvect(TIMER,IntProc);
    /*将中断号为TIMER的中断处理函数的入口地址改为IntProc()函数的入口地址
    即中断发生时,将调用IntProc()函数。*/
    enable();  /* 开启中断 */
}

/* 恢复原有的时钟中断处理过程 */
void KillTimer()
{
    disable();
    setvect(TIMER,oldtimer);
    enable();
}


void show_intro(int xs,int ys)
{
 char stemp[50];
 setcolor (15);
 rectangle(xs,ys,xs+239,ys+100);
 sprintf(stemp," -Roll  -Downwards");
 stemp[0]=24;
 stemp[8]=25;
 setcolor(14);
 outtextxy(xs+40,ys+30,stemp);

 sprintf(stemp," -Turn Left   -Turn Right");
 stemp[0]=27;
 stemp[13]=26;

 outtextxy(xs+40,ys+45,stemp);
 outtextxy(xs+40,ys+60,"Esc-Exit ");
 setcolor(FgColor);
}

/*显示分数*/
void ShowScore(int score)
{
    int x,y;
    char score_str[5];/*保存游戏得分*/
    setfillstyle(SOLID_FILL,BgColor);
    x=LeftWin_x;
    y=100;
    bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);
    sprintf(score_str,"%3d",score);
    outtextxy(x,y,"SCORE");
    outtextxy(x,y+10,score_str);
}

/*显示速度*/
void ShowSpeed(int speed)
{
    int x,y;
    char speed_str[5];/*保存速度值*/
    setfillstyle(SOLID_FILL,BgColor);
    x=LeftWin_x;
    y=150;
    bar(x-BSIZE,y,x+BSIZE*3,y+BSIZE*3);
    /*确定一个以(x1,y1)为左上角,(x2,y2)为右下角的矩形窗口, 再按规定图模和颜色填充。*/
    sprintf(speed_str,"%3d",speed+1);
    outtextxy(x,y,"Level");
    outtextxy(x,y+10,speed_str);
    /*输出字符串指针speed_str所指的文本在规定的(x, y)位置*/
    outtextxy(x,y+50,"Nextbox");
}


/**********初始化界面*******
 *参数说明:
 *      x,y为左上角坐标
 *      m,n对应于Vertical_boxs,Horizontal_boxs
 *      分别表示纵横方向上方块的个数(以方块为单位)
 *      BSIZE Sys_x Sys_y
 **********************************/
void initialize(int x,int y,int m,int n)
{

    int i,j,oldx;
    oldx=x;
    for(j=0;j<n;j++)
    {
        for(i=0;i<m;i++)
        {

            Table_board[j][i].var=0;
            Table_board[j][i].color=BgColor;
            line(x,y,x+BSIZE,y);
            line(x,y,x,y+BSIZE);
            line(x,y+BSIZE,x+BSIZE,y+BSIZE);
            line(x+BSIZE,y,x+BSIZE,y+BSIZE);
            x+=BSIZE;
        }
        y+=BSIZE;
        x=oldx;
    }
    Curbox_x=x;
    Curbox_y=y;/*x,y是保存方块的当前坐标的*/
    flag_newbox=false;  /*是否要产生新方块的标记0*/
    speed=0;            /*下落速度*/
    score=0;            /*总分*/
    ShowScore(score);
    ShowSpeed(speed);

}


/*   删除一行满的情况
 *   这里的y为具体哪一行为满
 */
int DelFullRow(int y)
{
    /*该行游戏板往下移一行*/
    int n,top=0;                /*top保存的是当前最高点,出现一行全空就表示为最点了,移动是到最高点结束*/
    register m,totoal;
    for(n=y;n>=0;n--)/*从当前行往上看*/
    {
        totoal=0;
        for(m=0;m<Horizontal_boxs;m++)
        {
            if(!Table_board[n][m].var)totoal++;             /*没占有方格+1*/
            if(Table_board[n][m].var!=Table_board[n-1][m].var)  /*上行不等于下行就把上行传给下行 xor关系*/
            {
                Table_board[n][m].var=Table_board[n-1][m].var;
                Table_board[n][m].color=Table_board[n-1][m].color;
            }
        }
        if(totoal==Horizontal_boxs)                     /*发现上面有连续的空行提前结束*/
        {
            top=n;
            break;
        }
    }
    return(top);                /*返回最高点*/
}


/*找到一行满的情况*/
void setFullRow(int t_boardy)
{
    int n,full_numb=0,top=0;            /*top保存的是当前方块的最高点*/
    register m;
/*
t_boardy 口       5
         口       6
   口口口口口口   7
n  口口口口口口   8
 */
    for(n=t_boardy+3;n>=t_boardy;n--)
    {
        if(n<0 || n>=Vertical_boxs ){continue;} /*超过低线了*/
        for(m=0;m<Horizontal_boxs;m++)          /*水平的方向*/
        {
            if(!Table_board[n+full_numb][m].var)break;      /*发现有一个是空就跳过该行*/
        }
        if(m==Horizontal_boxs)                  /*找到满行了*/
        {
            if(n==t_boardy+3)                   /*第一次献给了n,最高的*/
                top=DelFullRow(n+full_numb);        /*清除游戏板里的该行,并下移数据*/
            else
                DelFullRow(n+full_numb);
            full_numb++;                        /*统计找到的行数*/

        }
    }
    if(full_numb)
    {
        int oldx,x=Sys_x,y=BSIZE*top+Sys_y;
        oldx=x;
        score=score+full_numb*10;              /*加分数*/
        /*这里相当于重显调色板*/
        for(n=top;n<t_boardy+4;n++)
        {
            if(n>=Vertical_boxs)continue;   /*超过低线了*/
            for(m=0;m<Horizontal_boxs;m++)  /*水平的方向*/
            {
                if(Table_board[n][m].var)
                    setfillstyle(SOLID_FILL,Table_board[n][m].color);/*Table_board[n][m].color*/
                else
                    setfillstyle(SOLID_FILL,BgColor);

                bar(x,y,x+BSIZE,y+BSIZE);
                line(x,y,x+BSIZE,y);
                line(x,y,x,y+BSIZE);
                line(x,y+BSIZE,x+BSIZE,y+BSIZE);
                line(x+BSIZE,y,x+BSIZE,y+BSIZE);
                x+=BSIZE;
            }
            y+=BSIZE;
            x=oldx;
        }
        ShowScore(score);
        if(speed!=score/speed_step)
          {speed=score/speed_step; ShowSpeed(speed);}
        else
          {ShowSpeed(speed);}
    }
}


/*
 * 将新形状的方块放置在游戏板上,并返回此方块号
 */
int MkNextBox(int box_numb)
{

    int mask=128,t_boardx,t_boardy,n,m;
    t_boardx=(Curbox_x-Sys_x)/BSIZE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -