今天给大家带来一个用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.h与game.c两个文件中
game.h与game.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;
}
好了俄罗斯方块小游戏的代码就分享完毕,希望大家不要吝啬手里的点赞收藏,给作博主点个关注,博主会更有动力更新优质内容。文章来源:https://www.toymoban.com/news/detail-616963.html
小彩蛋:有心的小伙伴可能已经发现了,博主有一个函数的功能是未达到一定等级电脑会自动关机哦,还不写出来分享给自己的小伙伴,让他体验不游戏则关机的痛苦哈哈哈哈。文章来源地址https://www.toymoban.com/news/detail-616963.html
到了这里,关于C语言项目小游戏之俄罗斯方块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!