c语言俄罗斯方块游戏程序设计报告

时间:2024.4.20

C语言课程设计报告

主标题: C语言课程设计   

 副标题:俄罗斯方块游戏   

                    ----界面设计

姓    名:              

指导教师:         

院    系: 信息工程学院        

专    业: 计算机科学与技术    

班    级: 11计本(二)班      

小组成员:  

提交日期:  20##-6-7            

俄罗斯方块程序设计报告

一、           问题描述

   要求支持键盘操作和7种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越高,消去一行所得到的分数越高,为玩家提供了不同的选择。

二、           功能分析

俄罗斯方块游戏需要解决的问题包括:

⑴按任意键开始游戏,随机产生方块并自动下移

⑵用Esc键退出游戏。

⑶用键变换方块

⑷用键和键左右移动方块

⑸用键使方块加速下移

⑹用空格键使方块直接下移

⑺能正确判断满行并消行、计分、定级别

⑻能正确计时

⑼设定游戏为不同级别,级别越高难度越大

重点:

     *游戏面包的数据结构:二维数组

     *7种形状方块的数据结构:结构体保存每种形状方块的坐标、颜色

三、程序设计:

1、程序总体设计结构:首先初始化进入图形模式,进入欢迎界面,玩家按任意进入主菜单界面,按键进入游戏界面,键然后设置新的时钟中断。开始游戏后,进入该程序最核心的部分——处理和实现进行过程中的各种事件和函数。在处理中判断游戏是否结束,如果没有结束,则重新开始游戏,否则结束游戏。

详解如下:

(1)、游戏方块预览功能。在游戏过程中,当在游戏底板中出现一个游戏方块时,必须在游戏方块预览区域中出现下一个游戏方块,这样有利于游戏玩家控制游戏的策略。由于在此游戏中存在19种不同的游戏方块,所以在游戏方块预览区域中需要显示随机生成的游戏方块。

(2)、游戏方块控制功能。通过各种条件的判断,实现对游戏方块的左移、右移、快速下移、自由下落、旋转功能,以及行满消除行的功能。

      游戏执行主流程图

(3)、游戏显示更新功能。在判断键值时,有左移VK_LEFT、右移VK_RIGHT、下移VK_DOWN、变形旋转VK_UP、退出VK_ESC键值的判断。当游戏方块左右移动、下落、旋转时,要清除先前的游戏方块,用新坐标重绘游戏方块。当消除满行时,要重绘游戏底板的当前状态。

 (4)、游戏速度分数更新功能。在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数。比如,消除一行加10分。当游戏分数达到一定数量之后,需要给游戏者进行等级的上升,每上升一个等级,游戏方块的下落速度将加快,游戏的难度将增加。

(5)、游戏帮助功能。玩家进入游戏后,将有对本游戏如何操作的友情提示。

主函数:

void main()

{

    InitializeGraph();

    SetTimer(newtimer); /*设置新的时钟中断*/

    while(1)

    {

        StartGame();

        ProcessInGame();

        if(GameOver())

            break;

        bOver = FALSE;

    }

    KillTimer();

    closegraph();

}

2、界面设计

   分为左右两个部分:

   *左边为游戏面板

   *右边有三部分:下一个形状提示框、速度框和计分框

3、重要数据的数据结构设计

1)定义方块形状:

定义如下的结构体来表示每一个形状:

struct block{

 int arrXY[8];

 int nColor;

 int nNext;

}; /*保存某一形状信息的结构体*/

  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),

    }

             

2)、定义游戏的主界面:宽10、高20的游戏板

   1 数据结构:全局数组Gameboard[12][22],1表示已有的方块,0表示这个位置空着。在10*20基础上各自加2行、2列为了便于判断形状在移动时是否到边、到底。整个屏幕的坐标系原先为640*480。在此游戏中,将16个像素定义为一个方格的边长,所以坐标系转变成为了40*30(640/16=40,480/10=30)。

  2 玩家进行游戏时,需要对游戏界面进行初始化工作。此代码被main()函数调用。主要进行的工作如下:

  (1) 循环调用line()函数绘制当前游戏板。

  (2) 调用nScore()函数显示初始的成绩,初始成绩为0。

  (3) 调用npeed()函数显示初始的速度(等级),初始速度1。

   ****************************************************

   * 注:x,y为左上角坐标

   * *   m,n对应于Vertical_boxs,Horizontal_boxs

   * *   分别表示纵横方向上方块的个数(以方块为单位)

   **    BOARD_LEFT_X ,BOARD_LEFT_Y

   *****************************************************

4、函数设计

   1、本程序有主函数和个函数组成:本程序总共由24个函数组成。

   2、函数相互作用关系见下图

四、函数功能的描述:

五、 

五、运行效果

                                                                            

  

                                                                                      

       

                            

六、源代码详解

#include

#include

#include

#include /*系统提供的头文件*/

#define TIMER 0x1c /*定义时钟中断的中断号*/

#define VK_LEFT  0x4b00/*左移键*/

#define VK_RIGHT 0x4d00/*右移键*/

#define VK_DOWN  0x5000 /*加速键*/

#define VK_UP    0x4800 /*变形键*/

#define VK_SPACE 0x3920 /*变形键*/

#define VK_END   0x4f00 /*暂停键*/

#define VK_ESC   0x011b

#define VK_ENTER 0x1c0d

#define BSIZE 16 /*方块的边长是16个象素*/

#define MAX_SHAPE 19 /*总共有19种各形态的方块*/

#define BOARD_WIDTH 10 /*游戏面板的宽度,以方块的宽度为单位*/

#define BOARD_HEIGHT 20/*游戏面板的高度,以方块的宽度为单位*/

#define BGCOLOR BLACK /*背景色*/

#define FORECOLOR WHITE /*前景色*/

#define FALSE 0

#define TRUE 1

#define EMPTY 0

#define FILLED 1

#define BOARD_LEFT_X 10 /*游戏面板左上角的横坐标*/

#define BOARD_LEFT_Y 5 /*游戏面板左上角的纵坐标*/

/*定义全局变量*/

extern int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2];

extern int nCurrent_block_index  ; /*当前下落的方块的索引号*/

extern int nNext_block_index ; /*下一个方块的索引号*/

extern int nSpeed, nScore; /*速度和得分*/

extern int nSpeedUpScore; /*第一次要加速需达到的分数*/

extern int bAccel, bOver;

extern int nOriginX, nOriginY;/*某一形状的原点的绝对坐标*/

extern unsigned int TimerCounter;  /* 计时变量,每秒钟增加18 */

struct block{

 int arrXY[8];

 int nColor;

 int nNext;

}; /*保存某一形状信息的结构体*/

typedef struct block BLOCK;

extern BLOCK arrayBlock[19];

void interrupt newtimer(void);/*新的时钟中断处理函数*/

void SetTimer(void interrupt(*IntProc)(void));/*设置新的时钟中断处理过程*/

void KillTimer();/*恢复原有的时钟中断处理过程*/

void InitializeGraph();/*初始化图形模式*/

void InitializeGameboard() ;/*初始化游戏面板*/

void DrawSquare(int x, int y);/*在坐标(x,y)处画方块*/

void DrawBlock(int BlockIndex, int sx, int sy,int color);/*在(sx,sy)处绘制颜色为color的形状*/

int IsConflict(int BlockIndex, int x, int y);/*判断形状能否存在于坐标(x,y)处*/

void HandleLeft(int BlockIndex,int *x, int *y);/*左键处理函数*/

void HandleRight(int BlockIndex,int *x, int *y);/*右键处理函数*/

void HandleUp(int *BlockIndex,int *x, int *y);/*上键处理函数*/

int HandleDown(int BlockIndex,int *x, int *y);/*下键处理函数*/

int IsLineFull(int y);/*判断y行是否填满*/

void KillLine(int y);/*消去y行*/

int KillLines(int y);/*消去y行及上面被填满的行*/

int IsGameOver();/*结束游戏*/

int GameOver();/*用户自己决定是否结束游戏*/

void StartGame();/*开始游戏*/

void ProcessInGame();/*处理游戏中各种事件*/

/**********************************************************

 *  函数原型:void InitializeGraph()                                            *

 *  传入参数:无                                                            *

 *  返 回 值:无                                                        *

 *  函数功能:初始化进入图形模式                                                    *

 **********************************************************/

void InitializeGraph()

{

    int gdriver = VGA, gmode=VGAHI, errorcode;

        /* 初始化图形模式*/

    initgraph(&gdriver, &gmode, "c:\\turboc2");

    /* 读取初始化结果 */

    errorcode = graphresult();

    if (errorcode != grOk) /* 错误发生 */

    {

        printf("Graphics error: %s\n", grapherrormsg(errorcode));

        printf("Press any key to halt:");

        getch();

        exit(1); /* 返回错误码 */

    }

}

/**********************************************************

 *  函数原型:void InitializeGameboard()                                              *

 *  传入参数:无                                                                        *

 *  返 回 值:无                                                                    *

 *  函数功能:初始化游戏面板以及下一形状提示框、计分框和难度框  *

 **********************************************************/

void InitializeGameboard()

{

    /* 绘制游戏面板(即游戏区域)*/

    setfillstyle(SOLID_FILL,BGCOLOR);

    bar(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_LEFT_X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));

    setcolor(WHITE);

    rectangle(BSIZE*BOARD_LEFT_X,BSIZE*BOARD_LEFT_Y,BSIZE*(BOARD_LEFT_X+BOARD_WIDTH),BSIZE*(BOARD_LEFT_Y+BOARD_HEIGHT));

    /*绘制下一形状提示框*/

    setcolor(BLUE);

    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

    outtextxy(BSIZE*(25+4), BSIZE*(5+1), "next");

    setfillstyle(SOLID_FILL, BGCOLOR);

    bar(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));

    setcolor(YELLOW);

    rectangle(BSIZE*(24.5+2), BSIZE*6, BSIZE*(24.5+2+5), BSIZE*(6+5));

    /*绘制速度框*/

    setcolor(BLUE);

    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

    outtextxy(BSIZE*(25+4), BSIZE*(12+1), "level");

    setfillstyle(SOLID_FILL, BGCOLOR);

    bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));

    setcolor(YELLOW);

    rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));

    setcolor(RED);

    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

    outtextxy(BSIZE*(25+4), BSIZE*(13+1), "0");

    /*绘制计分框*/

    setcolor(BLUE);

    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

    outtextxy(BSIZE*(25+4), BSIZE*(19+1), "score");

    setfillstyle(SOLID_FILL, BGCOLOR);

    bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));

    setcolor(YELLOW);

    rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));

    setcolor(RED);

    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

    outtextxy(BSIZE*(25+4), BSIZE*(20+1), "0");

}

int Gameboard[BOARD_WIDTH+2][BOARD_HEIGHT+2];

int nCurrent_block_index;/* 当前下落的方块的索引号*/

int nNext_block_index ; /*下一个方块的索引号*/

int nSpeed, nScore; /*速度和得分*/

int nSpeedUpScore = 1000; /*第一次要加速需达到的分数*/

int bAccel, bOver;

int nOriginX=5, nOriginY=1;/*某一形状的原点的绝对坐标*/

BLOCK arrayBlock[19]={

    /*x1,y1,x2,y2,x3,y3,x4,y4, color,   next*/

    { 0,-2, 0,-1, 0, 0, 1, 0,  CYAN,    1}, /*        */

    {-1, 0, 0, 0, 1,-1, 1, 0,  CYAN,    2}, /*   #    */

    { 0,-2, 1,-2, 1,-1, 1, 0,  CYAN,    3}, /*   #    */

    {-1,-1,-1, 0, 0,-1, 1,-1,  CYAN,    0}, /*   ##   */

    { 0,-2, 0,-1, 0, 0, 1,-2,MAGENTA,   5}, /*        */

    {-1,-1,-1, 0, 0, 0, 1, 0,MAGENTA,   6}, /*   ##   */

    { 0, 0, 1,-2, 1,-1, 1, 0,MAGENTA,   7}, /*   #    */

    {-1,-1, 0,-1, 1,-1, 1, 0,MAGENTA,   4}, /*   #    */

    {-1, 0, 0,-1, 0, 0, 1, 0,YELLOW,    9}, /*        */

    {-1,-1, 0,-2, 0,-1, 0, 0,YELLOW,   10}, /*        */

    {-1,-1, 0,-1, 0, 0, 1,-1,YELLOW,   11}, /*   #    */

    { 0,-2, 0,-1, 0, 0, 1,-1,YELLOW,    8}, /*  ###   */

    {-1, 0, 0,-1, 0, 0, 1,-1, BROWN,   13}, /*   ##   */

    { 0,-2, 0,-1, 1,-1, 1, 0, BROWN,   12}, /*  ##    */

    {-1,-1, 0,-1, 0, 0, 1, 0, WHITE,   15}, /*   ##    */

    { 0,-1, 0, 0, 1,-2, 1,-1, WHITE,   14}, /*   ##   */

    { 0,-3, 0,-2, 0,-1, 0, 0,   RED,   17},/*  #     */

    {-1, 0, 0, 0, 1, 0, 2, 0,   RED,   16},/*  #     */

                                                                /*  #     */

                                                                /*  #     */

    { 0,-1, 0, 0, 1,-1, 1, 0,  BLUE,   18},/*  ##    */

                                                                /*  ##    */

};

/**********************************************************

 *  函数原型:void StartGame ()                                                             *

 *  传入参数:无                                                                    *

 *  返 回 值:无                                                                *

 *  函数功能:游戏开始时调用的函数,其中绘制界面需调用函数  *

 *            InitializeGameboard(), 接下来需初始化游戏面板的   *

 *            各个方块和一些全局变量的初值                  *

 **********************************************************/

void StartGame()

{

    int i,j;

    /*设置游戏面板中每个方块的初始值*/

    for(j=0;j<=BOARD_HEIGHT;j++)

        for(i=0;i

    {

        if(i==0 || i==BOARD_WIDTH+1)

            Gameboard[i][j] = FILLED;

        else

            Gameboard[i][j] = EMPTY;

    }

    for(i=0;i

        Gameboard[i][BOARD_HEIGHT+1] = FILLED;

    InitializeGameboard();

    /*设置游戏变量的初值*/

    nNext_block_index = -1; /*游戏初始,没有下一个形状的索引号*/

    nSpeed = 0;

    nScore = 0;

}

/**********************************************************

 *  函数原型:void ProcessInGame()                                                                              *

 *  传入参数:无                                                                                            *

 *  返 回 值:无                                                                                        *

 *  函数功能:核心函数,主要用于处理在游戏中的各种事件(如按下各种按键)    *

 **********************************************************/

void ProcessInGame()

{

    int key;

    bioskey(0);

    randomize();

    while(1)

    {

        if(nNext_block_index==-1)

        {

            nCurrent_block_index = rand()%19;

            nNext_block_index = rand()%19;

            /*绘制下一个提示形状*/

            DrawBlock(nNext_block_index, 19,6,arrayBlock[nNext_block_index].nColor );

        }

        else

        {

            nCurrent_block_index = nNext_block_index;

            DrawBlock(nNext_block_index, 19,6,BGCOLOR ); /* 消除原来的提示形状 */

            nNext_block_index = rand()%19;

            DrawBlock(nNext_block_index, 19,6,arrayBlock[nNext_block_index].nColor ); /*绘制下一个提示形状 */

        }

        nOriginX=5, nOriginY=1;

        TimerCounter = 0;

        DrawBlock(nCurrent_block_index, nOriginX,nOriginY, arrayBlock[nCurrent_block_index].nColor );/*在面板内绘制当前形状*/

        while(1)

        {

            if (bioskey(1))

                key=bioskey(0);

            else key=0;

            bAccel = FALSE;

            switch(key)

            {

                case VK_LEFT: /* 左移 */

                    HandleLeft(nCurrent_block_index,&nOriginX,&nOriginY );

                    break;

                case VK_RIGHT: /* 右移 */

                    HandleRight(nCurrent_block_index,&nOriginX,&nOriginY );

                    break;

                case VK_UP: /* 旋转 */

                case VK_SPACE:

                    HandleUp(&nCurrent_block_index, &nOriginX,&nOriginY);

                    break;

                case VK_DOWN: /* 下落加速键 */

                        bAccel=TRUE;

                    break;

                case VK_END: /* 暂停*/

                    bioskey(0);

                    break;

                case VK_ESC: /* 退出游戏 */

                    bOver=TRUE;

                    return;

            }

            if(bAccel || TimerCounter>(20-nSpeed*2))

                if(HandleDown(nCurrent_block_index,&nOriginX,&nOriginY))

                    break;

            if(bOver)

                return;

        }

    }

}

/**********************************************************

 *  函数原型:void main()                                                                   *

 *  传入参数:无                                                            *

 *  返 回 值:无                                                        *

 *  函数功能:入口函数,包含俄罗斯方块程序的主流程              *

 **********************************************************/

void main()

{

    InitializeGraph();

    SetTimer(newtimer); /*设置新的时钟中断*/

    while(1)

    {

        StartGame();

        ProcessInGame();

        if(GameOver())

            break;

        bOver = FALSE;

    }

    KillTimer();

    closegraph();

}

unsigned int TimerCounter=0; /* 计时变量,每秒钟增加18 */

/**********************************************************

 *  函数原型:void interrupt (*oldtimer)(void)                                          *

 *  传入参数:无                                                                                *

 *  返 回 值:无                                                                            *

 *  函数功能:指向原来时钟中断处理过程入口的中断处理函数指针(句柄)  *

 **********************************************************/

void interrupt (*oldtimer)(void);

/**********************************************************

 *  函数原型:void interrupt newtimer(void)                             *

 *  传入参数:无                                                            *

 *  返 回 值:无                                                        *

 *  函数功能:新的时钟中断处理函数                                              *

 **********************************************************/

void interrupt newtimer(void)

{

    (*oldtimer)();

    TimerCounter++;

}

/**********************************************************

 *  函数原型:void SetTimer(void interrupt(*)(void))            *

 *  传入参数:无                                                            *

 *  返 回 值:无                                                        *

 *  函数功能:设置新的时钟中断处理函数                                      *

 **********************************************************/

void SetTimer(void interrupt(*IntProc)(void))

{

    oldtimer=getvect(TIMER);

    disable();

    setvect(TIMER,IntProc);

    enable();

}

/**********************************************************

 *  函数原型:void KillTimer()                                                      *

 *  传入参数:无                                                            *

 *  返 回 值:无                                                        *

 *  函数功能:恢复原先的时钟中断处理函数                               

*

 **********************************************************/

void KillTimer()

{

    disable();

    setvect(TIMER,oldtimer);

    enable();

}

/**********************************************************

 *  函数原型:void DrawSquare(int x, int y)                             *

 *  传入参数:游戏面板中的横坐标x,纵坐标y                *

 *  返 回 值:无                                                        *

 *  函数功能:在坐标(x, y)处绘制方块                                      *

 **********************************************************/

void DrawSquare(int x, int y)

{

    if(y<1)

        return;

    bar(BSIZE*(x+9)+1,BSIZE*(y+4)+1,BSIZE*(x+10)-1,BSIZE*(y+5)-1);

}

/**********************************************************

 *  函数原型:void DrawBlock(int BlockIndex, int sx, int sy,int color)  *

 *  传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y,颜色color *

 *  返 回 值:无                                                                                            *

 *  函数功能:在坐标(sx, sy)处绘制颜色为color的形状                                       *

 **********************************************************/

void DrawBlock(int BlockIndex, int sx, int sy,int color)

{

    int i,c;

    setfillstyle(SOLID_FILL, color);

    for(i=0;i<7;i+=2)

        DrawSquare(arrayBlock[BlockIndex].arrXY[i]+sx, arrayBlock[BlockIndex].arrXY[i+1]+sy);

}

/**********************************************************

 *  函数原型:int IsConflict(int BlockIndex, int x, int y)          *

 *  传入参数:形状的索引BlockIndex,绝对横坐标x,绝对纵坐标y        *

 *  返 回 值:无冲突返回0,有冲突返回1                          *

 *  函数功能:判断形状是否能存在于坐标(x, y)处                                *

 **********************************************************/

int IsConflict(int BlockIndex, int x, int y)

{

    int i;

    for (i=0;i<=7;i++,i++)

    {

        if (arrayBlock[BlockIndex].arrXY[i]+x<1 || arrayBlock[BlockIndex].arrXY[i]+x>10)

            return TRUE;

        if (arrayBlock[BlockIndex].arrXY[i+1]+y<1)

            continue;

        if (Gameboard[arrayBlock[BlockIndex].arrXY[i]+x][arrayBlock[BlockIndex].arrXY[i+1]+y])

            return TRUE;

    }

    return FALSE;

}

/**********************************************************

 *  函数原型:int HandleLeft(int BlockIndex,int *x, int *y)                     *

 *  传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的    *

 *            指针*y                                                  *

 *  返 回 值:无                                                                                    *

 *  函数功能:按下左方向键时的处理函数                                                              *

 **********************************************************/

void HandleLeft(int BlockIndex,int *x, int *y) /*按下左方向键时的处理函数*/

{

    if(!IsConflict(BlockIndex,*x-1,*y))

    {

        DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/

        (*x)--;

        DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/

    }

}

/**********************************************************

 *  函数原型:int HandleRight(int BlockIndex,int *x, int *y)                    *

 *  传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的    *

 *            指针*y                                                  *

 *  返 回 值:无                                                                                    *

 *  函数功能:按下右方向键时的处理函数                                                              *

 **********************************************************/

void HandleRight(int BlockIndex,int *x, int *y)/*按下右方向键时的处理函数*/

{

    if(!IsConflict(BlockIndex,*x+1,*y))

    {

        DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/

        (*x)++;

        DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/

    }

}

/**********************************************************

 *  函数原型:int HandleUp(int BlockIndex,int *x, int *y)                           *

 *  传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的    *

 *            指针*y                                                  *

 *  返 回 值:无                                                                                    *

 *  函数功能:按下上方向键(旋转键)时的处理函数                                            *

 **********************************************************/

void HandleUp(int *BlockIndex,int *x, int *y) /*按下旋转键时的处理函数*/

{

    int NextBlockIndex, i;

    static int arrayOffset[5]={0,-1,1,-2,2};

    NextBlockIndex = arrayBlock[*BlockIndex].nNext;

    for(i=0;i<5;i++)

        if(!IsConflict(NextBlockIndex, *x+arrayOffset[i],*y))

    {

        DrawBlock(*BlockIndex, *x, *y, BGCOLOR); /*擦除原先的形状*/

        *BlockIndex = arrayBlock[*BlockIndex].nNext;

        (*x) += arrayOffset[i];

        DrawBlock(*BlockIndex, *x, *y, arrayBlock[*BlockIndex].nColor); /*绘制当前形状*/

    }

}

/**********************************************************

 *  函数原型:int HandleDown(int BlockIndex,int *x, int *y)                     *

 *  传入参数:形状的索引BlockIndex,绝对横坐标的指针*x,绝对纵坐标的    *

 *            指针*y                                                  *

 *  返 回 值:仍在自由下落返回0,无法下落了返回1                      *

 *  函数功能:按下向下方向键或自由下落时的处理函数                                      *

 **********************************************************/

int HandleDown(int BlockIndex,int *x, int *y)/*按下下方向键或自由下落时的处理函数*/

{

    char ScoreBuffer[10]={0},SpeedBuffer[10]={0};

    int i;

    int NumLinesKilled=0;

    /*if(TimerCounter>(20-nSpeed*2))*/

    {

        TimerCounter = 0; /*重置时钟中断*/

        if(!IsConflict(BlockIndex,*x,*y+1)) /*仍在下落*/

        {

            DrawBlock(BlockIndex,*x,*y,BGCOLOR); /*擦除原先的形状*/

            (*y)++;

            DrawBlock(BlockIndex, *x, *y, arrayBlock[BlockIndex].nColor); /*绘制当前形状*/

            return FALSE;/*仍在下落返回FALSE*/

        }

        else /*无法再下落了*/

        {

            DrawBlock(BlockIndex,*x,*y,FORECOLOR);

            for (i=0;i<=7;i++,i++)

            {

                if ((*y)+arrayBlock[BlockIndex].arrXY[i+1]<1)

                    continue;

                Gameboard[(*x)+arrayBlock[BlockIndex].arrXY[i]][(*y)+arrayBlock[BlockIndex].arrXY[i+1]]=1;

            }

            NumLinesKilled = KillLines(*y);

            if(NumLinesKilled>0)

            {

                switch(NumLinesKilled)

                {

                    case 1:

                        nScore+=100;

                    case 2:

                        nScore+=300;

                    case 3:

                        nScore+=500;

                    case 4:

                        nScore+=800;

                }

                /*重绘计分框*/

                setfillstyle(SOLID_FILL,BLACK);

                bar(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));

                setcolor(YELLOW);

                rectangle(BSIZE*25,BSIZE*20, BSIZE*(25+8), BSIZE*(20+1));

                itoa(nScore,ScoreBuffer, 10);

                setcolor(RED);

                settextjustify(CENTER_TEXT, BOTTOM_TEXT);

                outtextxy(BSIZE*(25+4), BSIZE*(20+1), ScoreBuffer);

                if(nScore > nSpeedUpScore)

                {

                    nSpeed++;

                    nSpeedUpScore+= nSpeed*1000;

                    /*重绘速度框*/

                    setfillstyle(SOLID_FILL,BLACK);

                    bar(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));

                    setcolor(YELLOW);

                    rectangle(BSIZE*25,BSIZE*13, BSIZE*(25+8), BSIZE*(13+1));

                    itoa(nSpeed,SpeedBuffer,10);

                    setcolor(YELLOW);

                    settextjustify(CENTER_TEXT, BOTTOM_TEXT);

                    outtextxy(BSIZE*(25+4), BSIZE*(13+1), SpeedBuffer);

                }

            }

            if(IsGameOver())

                bOver = TRUE;

            return TRUE; /*下落到底返回TRUE*/

        }

    }

}

/**********************************************************

 *  函数原型:int IsLineFull(int y)                                             *

 *  传入参数:纵坐标y                                                   *

 *  返 回 值:填满返回1,否则返回0                        *

 *  函数功能:判断第y行是否已被填满                                             *

 **********************************************************/

int IsLineFull(int y)

{

    int i;

    for(i=1;i<=10;i++)

        if(!Gameboard[i][y])

            return FALSE;

    return TRUE;

}

/**********************************************************

 *  void KillLine(int y)                                                                    *

 *  传入参数:纵坐标y                                                   *

 *  返 回 值:无                                                        *

 *  函数功能:消去第y行                                                                     *

 **********************************************************/

void KillLine(int y)

{

    int i,j;

    for(j=y;j>=2;j--)

        for(i=1;i<=10;i++)

        {

            if(Gameboard[i][j]==Gameboard[i][j-1])

                continue;

            if(Gameboard[i][j-1]==FILLED)

            {

                Gameboard[i][j]=FILLED;

                setfillstyle(SOLID_FILL,FORECOLOR);

            }

            else /*Gameboard[i][j-1]==EMPTY*/

            {

                Gameboard[i][j] = EMPTY;

                setfillstyle(SOLID_FILL,BGCOLOR);

            }

            DrawSquare(i,j);

        }

}

/**********************************************************

 *  函数原型:int KillLines(int y)                                              *

 *  传入参数:纵坐标y                                                   *

 *  返 回 值:消去的行数                                        *

 *  函数功能:消去第y行以及与第y行连续的上面被填满的行      *

 **********************************************************/

int KillLines(int y)

{

    int i, j, LinesKilled=0;

    for(i=0;i<4;i++)

    {

        while(IsLineFull(y))

        {

            KillLine(y);

            LinesKilled++;

            i++;

        }

        y--;

        if(y<1)

            break;

    }

    return LinesKilled;

}

/**********************************************************

 *  函数原型:int IsGameOver()                                                      *

 *  传入参数:无                                                            *

 *  返 回 值:游戏结束返回1,否则返回0                    *

 *  函数功能:判断游戏是否结束                                                      *

 **********************************************************/

int IsGameOver()

{

    int i;

    for(i=1;i<=10;i++)

        if(Gameboard[i][1])

        return TRUE;

    return FALSE;

}

/**********************************************************

 *  函数原型:int GameOver()                                                                                *

 *  传入参数:无                                                                                            *

 *  返 回 值:退出游戏返回1,否则返回0                                                  *

 *  函数功能:在界面上输出游戏结束信息,并根据用户按键选择决定是否退出游戏*

 **********************************************************/

 int GameOver()

{

    int key;

    settextjustify(CENTER_TEXT,TOP_TEXT);

    /* 输出游戏结束信息 */

    setcolor(RED);

    outtextxy(BSIZE*15,BSIZE*12,"Game  Over");

    setcolor(GREEN);

    outtextxy(BSIZE*15,BSIZE*14,"Enter : New  Game");

    outtextxy(BSIZE*15,BSIZE*15,"Esc : Exit");

    for(;;)

    {

        while(!bioskey(1))

            ;

        key=bioskey(0);

        if (key==VK_ENTER)

            return FALSE; /* 按下回车键,重新开始游戏 */

        if (key==VK_ESC)

            return TRUE;    /* 按下ESC键,退出游戏 */

    }

}

更多相关推荐:
俄罗斯方块课程设计报告

目录1.系统概述12.设计说明书43.系统操作界面64.源程序编码75.测试计划366.改进意见397.课程设计心得体会408.参考书籍、资料40系统概述1.1现状分析在个人电脑日益普及的今天,一些有趣的桌面游…

俄罗斯方块设计报告书

海南师范大学软件设计模式课程报告20xx20xx年度第一学期课程名称题目院系信息科学技术学院班级任课教师成员1成绩评定分数一任务分配二指导教师评语2目录目录3摘要4一绪论511俄罗斯方块游戏简介512俄罗斯方块...

俄罗斯方块设计报告

课程设计报告题目基于VC++的俄罗斯方块游戏课程名称学生创新实践院部名称XX学院专业计算机科学与技术班级M08(嵌入式)学生姓名XX学号XX课程设计地点校外课程设计学时2周(40学时)指导教师金陵科技学院教务处…

俄罗斯方块游戏课程设计报告

计算机工程学院课程设计说明书课程名称设计项目学生姓名学号专业班级指导教师年月一任务与具体要求二设计说明书包括的内容三应完成的图纸四评语及成绩指导教师签字年月日目录1系统概述22原有程序概况33现在系统操作界面5...

俄罗斯方块实验报告

程序设计实践报告20xx20xx学年第2学期题目专学生姓班级学指导教指导单日俄罗斯方块游戏设计业名号师位软件工程系期20xx0327俄罗斯方块游戏设计一课题内容和要求本程序的主要任务就是编写简单的俄罗斯方块游戏...

俄罗斯方块游戏设计报告

实训报告设计题目俄罗斯方块游戏设计院系班级学号姓名指导教师设计地点开课时间学院制学生姓名成绩评语指导教师签名年月日4目录1设计目的和任务111目的112任务12开发环境121硬件环境122软件环境13设计题目2...

俄罗斯方块游戏设计报告

课程软件开发技术设计题目俄罗斯方块游戏设计院系班级计科121学号姓名王积辉移动计算技术与应用课程设计报告1设计目的和任务11目的在现今电子信息高速发展的时代电子游戏已深入人们的日常生活成为老少皆宜的娱乐方式俄罗...

C#设计报告 俄罗斯方块

项目实训报告书学生姓名课程名称C课程设计题目俄罗斯方块专业班级指导教师完成日期目录一概述211背景212开发与运行环境3二需求分析3三系统设计4四详细设计541界面设计542代码设计7五结束语25六参考文献26...

c-俄罗斯方块-课程设计报告-刘阳

吉林工程技术师范学院信息工程学院C语言程序设计课程设计报告题目俄罗斯方块专业计算机科学与技术班级计算机1241姓名刘阳学号120xx44120指导教师郭天娇时间20xx年6月17日至20xx年6月28日摘要俄罗...

C++俄罗斯方块课程设计报告书

大学C面向对象课程设计报告院系计算机工程学院专业学生姓名班级学号20xx07206题目俄罗斯方块起迄日期20xx61820xx629设计地点计算机学院机房指导教师完成日期20xx年6月29日目录一需求分析31课...

俄罗斯方块实验报告

《软件工程与开发实践1》软件设计报告题目:俄罗斯方块学院:计算机学院专业:计算机科学与技术一、软件设计概述(目的、任务、开发环境、参考资料)俄罗斯方块游戏属于经典小游戏,游戏规则简单,但又不乏趣味。而计算的一大…

俄罗斯方块C语言程序设计报告

俄罗斯方块程序设计报告20xx624C语言课程设计报告俄罗斯方块程序设计报告一问题描述俄罗斯方块Tetris俄文是一款电视游戏机和掌上游戏机游戏它由俄罗斯人阿列克谢帕基特诺夫发明故得此名俄罗斯方块的基本规则是移...

俄罗斯方块设计报告(37篇)