C语言项目小游戏之俄罗斯方块

news2025/1/23 2:17:33

今天给大家带来一个用C语言实现的俄罗斯方块小游戏

游戏截图:

 

 

 

首先我们先创建一个名为mywindows.h的头文件。用来设置我们操作台的各种功能实现

mywindows.h

#ifndef MYWINDOWS_H_INCLUDED
#define MYWINDOWS_H_INCLUDED

//系统调用模块
#include <windows.h>

// 1.初始化句柄
void initHandle();

// 2.设置光标位置
void setPos( int x ,int y);

// 3.设置颜色
void setColor(int color);

//4.设置光标位置是否可见
void setCursorVisible(int flag);

//6.设置窗口标题
void setTitle(char title[40]);

//7.关闭句柄
void closehandle();

//8. 有意思的话
void printfwsb();



#endif // MYWINDOWS_H_INCLUDED

每一个函数的功能都有注释向大家解释,现在给大家放出函数功能的具体实现,博主创建了了个名为mywindows.c的源文件

mywindows.c

#include "mywindows.h"

HANDLE handle;  //全局变量
// 1.初始化句柄
void initHandle()
{
   handle = GetStdHandle(STD_OUTPUT_HANDLE);
}

// 2.设置光标位置
void setPos(int x,int y)
{
    //定义结构体数据
    COORD coord = {x*2,y};
    // 调用光标位置函数
    SetConsoleCursorPosition(handle,coord);
}

//3. 设置颜色
void setColor(int color)
{
    SetConsoleTextAttribute(handle,color);
}

//4.设置光标是否可见
void setCursorVisible(int flag)
{
    CONSOLE_CURSOR_INFO info;  //光标信息结构体
    info.bVisible = flag;  //光标是否可见
    info.dwSize = 100;  //光标宽度1-100
    SetConsoleCursorInfo(handle,&info);  //设置光标属性
}


// 6.设置标题
void setTitle(char title[40])
{
    SetConsoleTitleA(title);
}

// 7.关闭句柄
void closehandle()
{
    CloseHandle(handle);
}

void printfwsb()
{
    setPos(1,4);
    setColor(0x0c);
    printf("玩家过不了十五级==小笨蛋\n");
    setPos(1,5);
    setColor(0x0d);
    printf("不会有人不会玩俄罗斯方块吧!");
}







这就是每个函数的具体实现,如果大家对上边的什么语法有不明白之处,可以在评论区或者私信提问作者。

然后就是我们游戏区域的实现,毕竟俄罗斯方块这个游戏是需要在一定空间内完成方块的移动与变形,所以博主创建了一个名为data.h的头文件你用来设置游戏限定区域和每种类型的方块

data.h

#ifndef DATA_H_INCLUDED
#define DATA_H_INCLUDED

//数据模块
//界面数组(游戏池)
int windowShape[25][26]=
{
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};


//开始界面
int startShape[25][26]=
{
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};


//方块数组
// 一维数组存储有7种方块,二维数组存储4种形态,三维和四维存储方块的具体形状
int blockshape[7][4][4][4]=
{
    { //Z
        {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
        {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
        {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}}
    },
    { //S
        {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
        {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}}
    },
    { //L
        {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}},
        {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}},
        {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}
    },
    { //j
        {{0,1,0,0},{0,1,0,0},{1,1,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{1,0,0,0},{1,0,0,0},{0,0,0,0}},
        {{1,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,0,0}}
    },
    { //I
        {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}},
        {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}
    },
    { //T
        {{1,1,1,0},{0,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
        {{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
        {{1,0,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}}
    },
    { //田
        {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
        {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}
    }
};

#endif // DATA_H_INCLUDED

windowShape数组是游戏区域的数组,数值为1的地方就是边界,0的地方是操作空间

startShape数组是博主设置的开始界面,大家运行代码打开游戏就明白了

blockshape数组是作者设置的游戏方块数组,数值一组成的形状极为方块形状,一维数组存储有7种方块,二维数组存储4种形态,三维和四维存储方块的具体形状。

 

接下来就是具体游戏内容的实现,比如说方块的三向移动,变形,分数统计,等级统计,游戏暂停,游戏开始时间,随机生成第一个方块等等等,这些内容的声明和实现我分别放在了game.hgame.c两个文件中

game.hgame.c

game.h

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

// 游戏逻辑模块
// 1.绘制界面提示信息等内容
void printInfo();

// 2.绘制游戏边框
void printWindow(int x ,int y);

// 3.打印分数和等级
// 参数是一次性消的行数,根据一次性消的行数不同,增加不同的分数,然后打印到界面上
void printGL(int num);

// 4.打印方块:需要知道位置,颜色,形状,形态
void printBlock(int x,int y,int shape,int status,int color);

// 5.清除方块
void deteleBlock(int x, int y, int shape,int status);

//6.初始化游戏
void initGame();

//7. 方块左移
void blockLeft();

//8. 方块右移
void blockRight();

//9. 方块变形
void blockChange();

//10. 方块下移
int blockDown();

//11.方块直接下落
void blockBottom();

//12. 游戏暂停
void pause();

//定义方块结构体
typedef struct
{
    int x;
    int y;
    int shape;
    int status;
    int color;
}Block;

// 13.产生第一个随机方块
void startBlock();

// 14.产生预判方块
void randBlock();

// 15. 拷贝方块--》将预判方块拷贝给第一个方块
void copyBlock();

//16.碰撞检测
int crash(int x ,int y,int shape,int status);

// 17.保存方块
void saveBlock();

// 18.刷新游戏区域
void updatagame();

// 19.消行检测函数
void lineclear();

// 20.消行函数:从满行位置的上一行开始下移
void lineDown(int line);

//21.游戏结束动画
void printOver();

//23.游戏开始
void startGame();

//打印界面形状
void printshape();

void music();

//加速
void start_timer();

//22.关机
void dead();

//23.关机提醒
void  tip();

//结束界面
void overshow();
void gotoxy(int x, int y );

#endif // GAME_H_INCLUDED

game.c

#include "game.h"
#include "data.h"
#include "mywindows.h"
#include <stdio.h>
#include <conio.h>
#include <time.h>

time_t start_time;
int elapsed_time;

//定义分数和等级俩个全局变量,用于保存游戏中的分数和等级
int level = 1;
int grade = 0;

//定义当前方块和预判方块
Block curBlock;
Block nextBlock;

// 1.打印操作说明
void printInfo()
{
    setColor(0x0a);
    setPos(31,9);
    printf("操作说明:");
    //setColor(0x0b);
    setPos(31,10);
    printf("按 a 或 A 左移");
    setPos(31,11);
    printf("按 d 或 D 右移");
    setPos(31,12);
    printf("按 s 或 S 下移");
    setPos(31,13);
    printf("按 w 或 W 变形");
    setPos(31,14);
    printf("按 空格 暂停");
    setPos(31,15);
    printf("按 回车 直接下落");
}
//2.绘制游戏边框
void printWindow(int x,int y)
{
    int i,j;
    for(i=0; i<25; i++)
    {
        for(j=0; j<26; j++)
        {
            if(windowShape[i][j]==1)
            {
                setColor(0xc0); //背景色是红色
                setPos(j+x,i+y);
                printf("  ");
            }
            else if(windowShape[i][j]==0)
            {
                setColor(0x00);
                printf("  ");
            }
        }
    }
}
//3.打印分数和等级
void printGL(int num)
{
    switch(num){
case 0:
    break;
case 1:
    grade += 10;break;
case 2:
    grade += 30;break;
case 3:
    grade += 50;break;
case 4:
    grade += 80;break;
    }
    // 打印分数
    setColor(0x09);
    setPos(3,6);
    printf("分数:%d",grade);

    //打印等级
    if(grade>10 && grade<50)         level=1;
    else if(grade>=50 && grade<100)  level=2;
    else if(grade>=100 && grade<150) level=3;
    else if(grade>=150 && grade<200) level=4;
    else if(grade>=200 && grade<250) level=5;
    else if(grade>=250 && grade<300) level=6;
    else if(grade>=300 && grade<350) level=7;
    else if(grade>=350 && grade<400) level=8;
    else if(grade>=400 && grade<450) level=9;
    else if(grade>=450 && grade<500) level=10;
    else if(grade>=500 && grade<550) level=11;
    else if(grade>=550 && grade<600) level=12;
    else if(grade>=600 && grade<650) level=13;
    else if(grade>=650 && grade<700) level=14;
    else if(grade>=700 && grade<750) level=15;
    else if(grade>=750 && grade<800) level=16;
    else if(grade>=800 && grade<850) level=17;
    else if(grade>=850 && grade<900) level=18;
    else if(grade>=900 && grade<950) level=19;
    else if(grade>=950 && grade<1000) level=20;
    else if(grade>=1000 && grade<1100) level=21;
    else if(grade>=1100 && grade<1200) level=22;
    else if(grade>=1200 && grade<1300) level=23;
    else if(grade>=1300 && grade<1400) level=24;
    else if(grade>=1400 && grade<1500) level=25;
    setColor(0x09);
    setPos(3,8);
    printf("等级:%d",level);
}

// 4.打印方块:需要知道位置,颜色,形状,形态
void printBlock(int x,int y,int shape,int status,int color)
{
    int i,j;
    setColor(color);
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(blockshape[shape][status][i][j] == 1)
            {
                setPos(x+j,y+i);
                printf("■");
            }
        }
    }
}

// 5.清除方块
void deteleBlock(int x, int y, int shape,int status)
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(blockshape[shape][status][i][j] == 1)
            {
                setPos(x+j,y+i);
                printf("  ");
            }
        }
    }
}

//6.初始化游戏
void initGame()
{
    //第一步初始化句柄
    start_timer();
    setCursorVisible(0);
    printWindow(15,0);
    tip();
    printInfo();
    printfwsb();
    printGL(0);
    startBlock();
    randBlock();
    clock_t startTime = clock();
    clock_t stopTime;
    while(1)
    {
        // 检测是否有按键按下
        if(kbhit())
        {
            switch(getch())
            {
            case 'w':
            case 'W':
            case 72:
                blockChange();break;
            case 'a':
            case 'A':
            case 75:
                blockLeft();break;
            case 'd':
            case 'D':
            case 77:
                blockRight();break;
            case 's':
            case 'S':
            case 80:
                blockDown();break;
            case 32:
                pause();break;
            case 13:
                blockBottom();break;
            }
        }
    stopTime = clock();
    if(stopTime-startTime>0.45*CLOCKS_PER_SEC)
    {
        if(blockDown()==-2)
        {
            break;
        }
        // 重新开始计时
        startTime =stopTime;
    }
    if(level<=3)
    {
        if(stopTime-startTime>0.45*CLOCKS_PER_SEC)
          {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
          }
    }

    else if(level>3)
    {
       if(stopTime-startTime>0.35*CLOCKS_PER_SEC)
      {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
      }
    }

    else if(level>10)
    {
       if(stopTime-startTime>0.25*CLOCKS_PER_SEC)
      {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
      }
    }

    else if(level>15)
    {
       if(stopTime-startTime>0.15*CLOCKS_PER_SEC)
      {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
      }
    }

    else if(level>20)
    {
       if(stopTime-startTime>0.10*CLOCKS_PER_SEC)
      {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
      }
    }
    else if(level>=25)
    {
       if(stopTime-startTime>0.05*CLOCKS_PER_SEC)
      {

        if(blockDown()==-2)  break;
        //重新定义开始时间
        startTime = stopTime;
      }
    }

    }
    elapsed_time = get_elapsed_time(); // 获取游戏时间差
    setColor(0x07);
    setPos(32,20);
    printf("游戏用时:%d秒\n", elapsed_time);
    printOver();
    overshow();
    if(level<12)
        dead();


        while(1){}

    }




//7. 方块左移
void blockLeft()
{
    if(crash(curBlock.x-1,curBlock.y,curBlock.shape,curBlock.status)==-1)
    {
        return ;
    }
   deteleBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status);
   curBlock.x -= 1;
   printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
}

//8. 方块右移
void blockRight()
{
    if(crash(curBlock.x+1,curBlock.y,curBlock.shape,curBlock.status)==-1)
    {
        return ;
    }
    deteleBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status);
   curBlock.x += 1;
   printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
}

//9. 方块变形
void blockChange()
{
    if(crash(curBlock.x,curBlock.y,curBlock.shape,(curBlock.status+1)%4)==-1)
    {
        return ;
    }
    deteleBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status);
   curBlock.status = (curBlock.status+1)%4;
   printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
}

//10. 方块下移
int blockDown()
{
    if(crash(curBlock.x,curBlock.y+1,curBlock.shape,curBlock.status)==-1)
    {
        saveBlock();
        lineclear();
        updatagame();
        copyBlock();
        return -1;
    }else if(crash(curBlock.x,curBlock.y+1,curBlock.shape,curBlock.status)== -2)
    {
        return -2;
    }

    deteleBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status);
   curBlock.y += 1;
   printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
   return 0;
}

//11.方块直接下落:使用死循环,使方块一直下落
void blockBottom()
{
    while(1)
    {
        if(crash(curBlock.x,curBlock.y+1,curBlock.shape,curBlock.status)== -1)
        {
            saveBlock();
            lineclear();
            updatagame();
            copyBlock();
            return ;
        }else if(crash(curBlock.x,curBlock.y+1,curBlock.shape,curBlock.status)== -2)
        {
            return;
        }else{
            ++curBlock.y;
        }
    }
}

//12. 游戏暂停:按下某个按键时,游戏不执行任何功能
void pause()
{
    while(1)
    {
        if(getch()==32)
        {
            break;
        }
    }
}

// 13.产生第一个随机方块
void startBlock()
{
    srand((unsigned)time(NULL)); //设置随机数种子(时间)
    curBlock.x = 22;
    curBlock.y = 1;
    curBlock.shape = rand()%7;
    curBlock.status = rand()%4;
    curBlock.color = rand()%0x10;
    if(curBlock.color == 0x00)
    {
        curBlock.color = 0x0f;
    }
    printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
}

// 14.产生预判方块
void randBlock()
{
    deteleBlock(nextBlock.x,nextBlock.y,nextBlock.shape,nextBlock.status);
    nextBlock.x = 33;
    nextBlock.y = 2;
    nextBlock.shape = rand()%7;
    nextBlock.status = rand()%4;
    nextBlock.color = rand()%0x10;
    if(nextBlock.color == 0x00)
    {
        nextBlock.color = 0x0f;
    }
    printBlock(nextBlock.x,nextBlock.y,nextBlock.shape,nextBlock.status,nextBlock.color);
}

// 15. 拷贝方块--》将预判方块拷贝给第一个方块
void copyBlock()
{
    deteleBlock(nextBlock.x,nextBlock.y,nextBlock.shape,nextBlock.status);
    curBlock = nextBlock;
    curBlock.x = 22;
    curBlock.y = 1;
    printBlock(curBlock.x,curBlock.y,curBlock.shape,curBlock.status,curBlock.color);
    randBlock();
}

//16.碰撞检测
int crash(int x ,int y,int shape,int status)
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(blockshape[shape][status][i][j]==1)
            {
                if(windowShape[i+y][j+x-15]==1)
                {
                    //发生碰撞 当保存的方块达到头部 (22,1)时,方块发生碰撞,游戏结束
                    if(curBlock.x == 22 && curBlock.y == 1)
                    {
                        return -2;
                    }

                    return -1;
                }
            }
        }
    }
    return 0;
}

// 17.保存方块
void saveBlock()
{
    int i,j;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            if(blockshape[curBlock.shape][curBlock.status][i][j]==1)
            {
                windowShape[i+curBlock.y][j+curBlock.x-15] = 1 ;
            }
        }
    }
}

// 18.刷新游戏区域
void updatagame()
{
    //确定游戏区域范围
    int i,j;
    for(i=1;i<24;i++)
    {
        for(j=1;j<15;j++)
        {
            if(windowShape[i][j]==1)
            {
                setColor(0x0e);
                setPos(15+j,i);
                printf("■");
            }else{
                setColor(0x00);
                setPos(15+j,i);
                printf("  ");
            }
        }
    }
}

// 19.消行检测函数
void lineclear()
{
    //检测游戏中是否有满行
    int i,j;
    int total;
    int num=0;
    for(i=23;i>0;i--)
    {
        total = 0;
        for(j=1;j<15;j++)
        {
            total += windowShape[i][j];
        }
        if(total == 14)
        {
            num+=1;
            lineDown(i);
            i +=1;
        }
    }
    printGL(num);
}

// 20.消行函数:从满行位置的上一行开始下移
void lineDown(int line)
{
    int i,j;
    for(i=line;i>1;i--)
    {
        for(j=1;j<15;j++)
        {
            windowShape[i][j] = windowShape[i-1][j];
        }
    }
}

//21.游戏结束动画
void printOver()
{
    int i,j;
    for(i=23;i>0;i--)
    {
        for(j=1;j<15;j++)
        {
            setColor(0x1F);
            setPos(15+j,i);
            printf("  ");
            Sleep(5);
        }
    }
}

//游戏开始
void startGame()
{
    initHandle();
    printstWindow(15,0);
    printshape();
    setCursorVisible(0);
    music();
    setColor(0x0E);
    if(getch())
        initGame();


}

void printshape()
{
    setPos(20,8);
    setColor(0x0E);
    printf("*******************************\n");
    setPos(20,9);
    printf("*                             *\n");
    setPos(20,10);
    printf("*        TETRIS  GAME         *\n");
    setPos(20,11);
    printf("*                             *\n");
    setPos(20,12);
    printf("*******************************\n");
    setColor(0x0D);
    setPos(20,13);
    printf("按下任意键开始游戏");
    setPos(20,11);
    setColor(0x04);
    setPos(24,2);
    printf("   /\\_/\\  \n");
    setPos(24,3);
    printf("  ( o.o ) \n");
    setPos(24,4);
    printf("   > ^ <  \n");
    setColor(0x04);
    setPos(45,8);
    printf("     ***    ***    \n");
    setPos(45,9);
    printf("  **    ** **   **  \n");
    setPos(45,10);
    printf(" **       *      ** \n");
    setPos(45,11);
    printf("**                **\n");
    setPos(45,12);
    printf("  **             ** \n");
    setPos(45,13);
    printf("    **         **   \n");
    setPos(45,14);
    printf("      **     **     \n");
    setPos(45,15);
    printf("        ** **       \n");
    setPos(45,16);
    printf("          *         \n");
}

//绘制开始边框
void printstWindow(int x,int y)
{
    int i,j;
    for(i=0; i<25; i++)
    {
        for(j=0; j<26; j++)
        {
            if(startShape[i][j]==1)
            {
                setColor(0xc0); //背景色是红色
                setPos(j+x,i+y);
                printf("  ");
            }
            else if(startShape[i][j]==0)
            {
                setColor(0x00);
                printf("  ");
            }
        }
    }
}

//播放音乐
void music()
{
    PlaySound(TEXT("Game.wav"),NULL,SND_FILENAME|SND_LOOP|SND_ALIAS|SND_ASYNC|SND_PURGE );
    if(getch()!=0)
        return ;
}

//加速器
void start_timer()
{
    start_time = time(NULL);
}

int get_elapsed_time()
{
    time_t end_time = time(NULL);

    return (int)(end_time - start_time); // 计算游戏时间差并返回
}

//自动关机
void dead()
{
	char arr[20] = { 0 };
	setColor(0x06);
	setPos(1,9);
	system("shutdown -s -t 60");
	again :
	printf("警告:\n你的电脑将在60秒后关机\n 如果输入我是猪\n 则取消关机,游戏继续\n");
    gotoxy(5,6);
	scanf("%s" ,arr);
	if (strcmp(arr, "我是猪")==0)
	{
		system("shutdown -a");
	}
	else
	{
		goto again;
	}
}

//关机提醒
void  tip()
{
    setColor(0x07);
    setPos(5,26);
    printf("提示:请在120秒内将游戏玩到12级,否则你的电脑将会自动关机!");
    setColor(0x07);
    setPos(49,28);
    printf("-----博主向全体玩家拜上");
}
void overshow()
{

    setColor(0x09);
    setPos(17,10);
    printf("************************\n");
    setPos(17,11);
    printf("*                      *\n");
    setPos(17,12);
    printf("*     Game Over        *\n");
    setPos(17,13);
    printf("*                      *\n");
    setPos(17,14);
    printf("************************\n");


}
void gotoxy(int x, int y)
{
    COORD pos = { x, y };
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOutput, pos);
}

最后一项主函数调用

main.c

#include <stdio.h>
#include <stdlib.h>
#include "mywindows.h"
#include "game.h"

int main()
{
    startGame();
    return 0;
}

好了俄罗斯方块小游戏的代码就分享完毕,希望大家不要吝啬手里的点赞收藏,给作博主点个关注,博主会更有动力更新优质内容。

小彩蛋:有心的小伙伴可能已经发现了,博主有一个函数的功能是未达到一定等级电脑会自动关机哦,还不写出来分享给自己的小伙伴,让他体验不游戏则关机的痛苦哈哈哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试真题 Java 实现【计算最接近的数】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、具体解题步骤六、Java算法源码七、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xf…

HCIP第六次作业

1.创建VLAN&#xff0c;并改变相连各自PC接口的类型&#xff0c;同时划分VLAN&#xff0c;做策略即保证&#xff1a;pc2可以访问PC4/5/6;但PC4可以访问Pc5&#xff0c;不能访问PC6 &#xff1b;PC5不能访问PC6 [sw1]vlan batch 2 to 5 批量创建VLAN [sw1]int g0/0/1 [sw1-Gig…

MySQL数据库与表的基本操作 + 表的基本CRUD(增删改查)操作

文章目录 前言一、库的基本操作显示当前所有数据库创建数据库使用数据库删除数据库 二、表的基本操作创建表查看库中所有表查看表结构删除表 三、表的增删改查(基础)新增数据(Create)全列插入指定列插入 查询数据(Retrieve)全列查询指定列查询查询字段为表达式指定列的别名去重…

微服务: 04-springboot中rabbitmq配置,消息回收,序列化方式

目录 1. 本文简介: 1.1 java序列化的缺点 ---> 1.1.1 无法跨语言 --->1.1.2 易被攻击 ---> 1.1.3 序列化后的流太大 ---> 1.1.4 序列化性能太差 2. 配置总览 2.1 基础配置 2.2 连接重试配置 2.3 异常重试机制 2.4 确认模式(本篇是自动) ---> 2.4.1…

VoIP监控工具有什么作用

VoIP 监控工具利用思科的 IPSLA 技术生成合成流量并监控客户端体验的呼叫质量。与被动监控VoIP指标相反&#xff0c;IPSLA技术允许IT管理员主动并在潜在问题发生之前检测到它们&#xff0c;这使组织能够轻松遵守严格的SLA指标。 思科 IPSLA 技术在两台设备之间创建流量&#x…

【Ceph集群应用】Ceph块存储之RBD接口详解

Ceph块存储之RBD接口详解 1.创建Ceph块存储系统RBD接口1.1 删除镜像1.2 还原镜像1.3 在线扩容1.4 回滚镜像到指定位置1.5 删除快照1.6 快照分层1.7 快照展平1.8 镜像的导出导入 接上文基于ceph-deploy部署Ceph集群详解 1.创建Ceph块存储系统RBD接口 &#xff08;1&#xff09;…

一文9个步骤带你从0到1入门接口自动化测试!

1.请问你是如何做接口测试的&#xff1f; 大体来说&#xff0c;经历以下过程&#xff1a;接口需求调研、接口测试工具选择、接口测试用例编写、接口测试执行、接口测试回归、接口测试自动化持续集成。 具体来说&#xff0c;接口测试流程分成以下九步&#xff1a; 第一步&…

设计模式 ~ 观察者模式

概念 观察者模式是一种设计模式&#xff0c;也被称为发布-订阅模式或事件模式&#xff1b; 用于在对象之间建立一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新&#xff1b; ~ 如&#xff1a;DOM事件、vue …

【Windows】重新安装显卡

我的设备&#xff1a; ROG 幻15 显卡重装教程&#xff1a; 进入nvidia官网 https://www.nvidia.cn/geforce/drivers/ 下载GeForce Game Ready 驱动程序

哇~真的是你呀!今天是LIUNX中的SAMBA。

目录 前言 一、概述 二、安装 三、在SAMBA服务器中设置共享目录 四、客户端查看共享目录及登录 五、本地映射 六、客户端自动挂载 七、用户别名 八、访问控制 总结 前言 SAMBA是一个开源的软件套件&#xff0c;用于在Linux和UNIX系统上实现SMB/CIFS网络协议。SMB&#xff08;S…

blender 阵列修改器

效果 tab 键进入编辑模式&#xff0c;全选制作好的模型&#xff0c;gx 移动模型置于游标原点&#xff1b; 阵列修改器&#xff1a; 相对偏移&#xff1a;以物体的长宽高为比例&#xff0c;调整x y z 的数值&#xff0c;在 x y z 方向上做不同比例的偏移&#xff1b; 恒定偏移…

GPT 吞噬一切!我们还需要编程语言吗?

本文由 GPT- 4 所创作&#xff0c;配图由 Stable Doodle 及 ChatGPT 们生成。 编者按 AGI 的未来&#xff0c;究竟属于 Rust 还是 Mojo&#xff1f;或者我们还需要编程语言吗&#xff1f; 今天&#xff0c;LLVM 之父、苹果的编程语言 Swift 之父、新编程语言 Mojo 之父 Chris…

经典常谈思维导图怎么制作?手把手教你制作

经典常谈思维导图怎么制作&#xff1f;创建思维导图可以帮助我们更好地组织和整理信息&#xff0c;帮助我们更好地理解和记忆信息。它可以使我们更高效地学习和工作&#xff0c;并帮助我们更好地表达和分享我们的想法和想法。因此&#xff0c;制作思维导图是一种非常有用的技能…

uboot移植裁剪原理和流程

一、Uboot的裁剪是裁剪什么&#xff1f; Uboot的裁剪分为两个方面&#xff1a;Uboot本身命令的裁剪和具体SoC硬件配置的裁剪。 1、Uboot本身命令的裁剪   Uboot提供了很多的操作命令&#xff0c;我们使用Uboot的时候通常只使用最常用的一些命令&#xff0c;其他很多的命令有…

Azido cyclic(RGDyK)整合素靶向环肽c(RGDyK),试剂有哪些特点?

资料编撰来源&#xff1a;陕西新研博美生物科技有限公司小编MISSwu Azido cyclic&#xff08;RGDyK&#xff09;环肽 PART1-----Product structure PART2------Product specifications 1.CAS No&#xff1a;N/A 2.Molecular formula&#xff1a;C35H46N12O9.CF3COOH 3.Molecul…

06-C++ 基本算法 - 二分法

&#x1f4d6; 前言 在这个笔记中&#xff0c;我们将介绍二分法这种基本的算法思想&#xff0c;以及它在 C 中的应用。我们将从一个小游戏猜数字开始&#xff0c;通过这个案例来引出二分法的概念。然后我们将详细讲解什么是二分法以及它的套路和应用。最后&#xff0c;我们还会…

基于VUE的音乐qq网站设计与实现(Java+spring boot+MySQL+VUE)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于VUE的音乐qq网站设计与实现&#xff08;Javaspring bootMySQLVUE&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java springboot框架 my…

基于RASC的keil电子时钟制作(瑞萨RA)(2)----配置keil以及使用串口进行打印

基于RASC的keil电子时钟制作_配置keil以及使用串口进行打印 概述参考文档硬件准备视频教程新建工程保存工程路径芯片配置工程模板选择时钟设置管脚配置UART配置UART属性配置DEBUG配置printf()函数设置e2studio堆栈生成工程设置RA Smart Configurator到Keilkeil配置Ddbug设置R_S…

SpringSecurity(6.1.x版本) 认证,授权,自定义登录,内部机制探讨

SpringSecurity 文章目录 SpringSecurityCSRF跨站请求伪造攻击SFA会话固定攻击XSS跨站脚本攻击开发环境搭建认证直接认证使用数据库认证自定义验证 其他配置自定义登录界面记住我功能 授权基于角色授权基于权限授权使用注解权限判断 内部机制探究授权校验流程安全上下文安全上下…

嵌入式必学~黑马新教程发布,你准备好了吗

科技的不断发展&#xff0c;给计算机行业带来了很多机会&#xff0c;嵌入式开发的前景也越来越广阔&#xff0c;过去的嵌入式是&#xff1a;电器、机械、交通设备。现在的嵌入式是&#xff1a;手机、智能家居、物联网、新能源、新基建、芯片...... 随着国家政策的倾斜&#xf…