六种模式史上最强c语言俄罗斯方块
Posted 键盘奏鸣曲
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了六种模式史上最强c语言俄罗斯方块相关的知识,希望对你有一定的参考价值。
::: hljs-center
--------写在前面--------
:::
第一次做标题党,大家轻喷哈。这个游戏是博主在大一c语言实训时独立完成的,所有内容均为原创。小游戏耗时5天完成,除了常见的单人模式外,增加了作弊模式,双人模式,计时赛等玩法,真滴很好玩哦。虽然现在看起来很简陋,但对于当时的我来说实属不易,从页面设计到游戏背景音乐的选取再到关键算法的编写,每一步都凝汇了自己的努力,通宵鏖战的画面依然历历在目。现在分享出来,一方面是希望可以帮助到大家,另一方面也想纪念美好的大一时光。源码地址放在文末了,大家自取。
如果对您有帮助,可以点赞收藏支持一下,如果能点个关注那就更好了✅,谢谢大家啦!
::: hljs-center
-----------------------正文-----------------------
:::
最终效果
主页
模式选择
按1进入单人模式
按2进入双人模式
标准模式:除了左右下移动,增加了直接下落和暂停,增加了等级判定
地狱模式:在标准模式的前提下加快了下落速度,更刺激!
作弊模式:增加炫彩模式,变形,加速以及减速功能
双人标准赛:设计了一个判定胜负平局的算法
双人地狱存活赛:刺激到不行!!
双人计时赛:设置了计时器,重新设定了判定胜负平局的算法,在规定时间内分数高者胜!
结束动画
代码部分
main.c
#include <stdio.h>
#include <stdlib.h>
#include "game.h"
#include "mywindows.h"
#include <conio.h>
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
void chooseMode()
if(kbhit())
mciSendString("close g",NULL,0,NULL);
switch(getch())
case 49:
case 97: gameInit(1);break;
case 50:
case 98: gameInit(2);break;
case 51:
case 99: gameInit(3);break;
void chooseMode2()
if(kbhit())
mciSendString("close g",NULL,0,NULL);
switch(getch())
case 49:
case 97: gameInit1(1);break;
case 50:
case 98: gameInit1(2);break;
case 51:
case 99: gameInit1(3);break;
int main()
///初始化句柄,必须放在最开始
initHandle();
///开始动画
mciSendString("open 俄罗斯方块进入音乐.mp3 alias g",NULL,0,NULL);
mciSendString("play g repeat",NULL,0,NULL);
printAnimation();
if(kbhit())
getch();
chooseWindow();
if(kbhit())
switch(getch())
case 49:
case 97: chooseWindow2();chooseMode();break;
case 50:
case 98: chooseWindow3();chooseMode2();break;
return 0;
mywindows.c
#include "mywindows.h" //尖括号常用于引入系统头文件,双引号常用于引入自己定义的头文件 默认检索顺序不同
HANDLE handle;
//函数定义
void initHandle()
handle = GetStdHandle(STD_OUTPUT_HANDLE);
hideCursor();//游戏启动后隐藏光标位置
//
void setColor(int color)
SetConsoleTextAttribute(handle,color);
void setPos(int x,int y)
COORD coord = x*2,y; //字母abcd:一个字符,汉字:两个字符
SetConsoleCursorPosition(handle,coord); //设置句柄位置
void hideCursor()
CONSOLE_CURSOR_INFO info; //系统的结构体变量名字都是大写
info.bVisible = FALSE; //设置光标是否可见
info.dwSize = 1; //设置光标宽度(1-100)
SetConsoleCursorInfo(handle,&info);//指针取地址符
game.c 关键代码
单人模式窗体打印
void printGradeLevel1(int num)
switch(num)
case 1:
grade1+=10; break;
case 2:
grade1+=30; break;
case 3:
grade1+=50; break;
case 4:
grade1+=80; break;
if(grade1 < 100)
level1 = 1;
else if(grade1 >= 100 && grade1 < 300)
level1 =2;
setColor(0x0c);
setPos(4,8);
printf("分数:%d",grade1);
setPos(4,9);
printf("等级:%d",level1);
void printGradeLevel2(int num)
switch(num)
case 1:
grade2+=10; break;
case 2:
grade2+=30; break;
case 3:
grade2+=50; break;
case 4:
grade2+=80; break;
if(grade2 < 100)
level2 = 1;
else if(grade2 >= 100 && grade2 < 300)
level2 =2;
setColor(0x09);
setPos(51,8);
printf("分数:%d",grade2);
setPos(51,9);
printf("等级:%d",level2);
双人模式窗体打印
void windowPrint2(int x,int y)
int i,j; //用来遍历二维数组
for(i=0;i<25;i++)
for(j=0;j<58;j++)
if(windowShape2[i][j] == 1)
setColor(0xc0);
setPos(x+j,y+i); //x是列,y是行
printf("%2s",""); // <--> printf(" ");
for(i=0;i<25;i++)
for(j=29;j<58;j++)
if(windowShape2[i][j] == 1)
setColor(0x90);
setPos(x+j,y+i); //x是列,y是行
printf("%2s",""); // <--> printf(" ");
//操作规则框架
void printInfo()
setColor(0x0c);
setPos(2,2);
printf("N");
setPos(2,3);
printf("E");
setPos(2,4);
printf("X");
setPos(3,3);
printf("T");
setPos(3,14);
printf("红方操作规则");
setPos(3,15);
printf("------------");
setPos(2,16);
printf("按 a 或 A 左移");
setPos(2,17);
printf("按 d 或 D 右移");
setPos(2,18);
printf("按 s 或 S 下移");
setPos(2,19);
printf("按 w 或 W 变方向");
setPos(2,20);
printf("按 q 直接下落");
setColor(0x03);
setPos(49,2);
printf("N");
setPos(49,3);
printf("E");
setPos(49,4);
printf("X");
setPos(50,3);
printf("T");
setPos(50,14);
printf("蓝方操作规则");
setPos(50,15);
printf("------------");
setPos(49,16);
printf("按 ←键 左移");
setPos(49,17);
printf("按 →键 右移");
setPos(49,18);
printf("按 ↑键 下移");
setPos(49,19);
printf("按 ↓键 变方向");
setPos(49,20);
printf("按 回车 直接下落");
setPos(27,1);
printf("--战况--");
setPos(27,3);
printf("--------");
方块打印
void printBlock1(int x,int y,int shape,int status,int color)
int i,j;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
if(block[shape][status][i][j] == 1)
setColor(color);
setPos(x+j,y+i);
printf("■");
void printBlock2(int x,int y,int shape,int status,int color)
int i,j;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
if(block[shape][status][i][j] == 1)
setColor(color);
setPos(x+j,y+i);
printf("■");
碰撞检测
//碰撞检测基于下一个位置的检测,数组与界面坐标的对应
int crash1(int x,int y,int shape,int status)
int i,j;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
if(block[shape][status][i][j] == 1)
if(windowShape2[y+i][x+j] == 1)
///发生碰撞
if(cur_block1.x == 17 && cur_block1.y == 1)
///游戏结束
return -2;
///方块落到游戏池底部,发生碰撞
return -1;
return 0;
胜负判断
void bottomBlock1()
while(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) != -1&&crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) != -2)
cur_block1.y += 1;
if(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) == -1)
///发生碰撞:方块落到游戏池底部
///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块
save1();
removeLine1();
// lineClear();
updateGame1();
copyBlock1();
else if(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) == -2)
///游戏结束
按键检测以及双人胜负判断算法
int gameInit1(int mode)
if(mode == 1)
mciSendString("open 双人标准.mp3 alias d",NULL,0,NULL);
mciSendString("play d repeat",NULL,0,NULL);
if(mode == 2)
mciSendString("open 双人地狱.mp3 alias e",NULL,0,NULL);
mciSendString("play e repeat",NULL,0,NULL);
if(mode == 3)
mciSendString("open 双人限时.mp3 alias f",NULL,0,NULL);
mciSendString("play f repeat",NULL,0,NULL);
int counter = 180;
float speed ;
if(mode == 1)
speed = 0.45;
else if(mode == 2)
speed = 0.25;
else if(mode == 3)
speed = 1;
///初始化句柄,必须放在最开始
initHandle();
///打开音乐文件
windowPrint2(0,0);
printInfo();
printGradeLevel1(0);
printGradeLevel2(0);
///游戏开始时间
clock_t startTime = clock();
///定时器
clock_t time1,time2;
time1 = clock();
startBlock1();
startBlock2();
nextBlock1();
nextBlock2();
while(1)
//按键驱动
///检测是否有按键按下
if(kbhit())
switch(getch())
case w:
case W:
changeStatusBlock1();break;
case a:
case A:
leftBlock1();break;
case d:
case D:
rightBlock1();break;
case s:
case S:
downBlock1();break;
case 72:
changeStatusBlock2();break;
case 75:
leftBlock2();break;
case 77:
rightBlock2();break;
case 80:
downBlock2();break;
case 32:
bottomBlock1();break;
case 13:
bottomBlock2();break;
time2 = clock();
if(mode == 1|| mode == 2)
///每0.45秒下落一次
if((float)(time2-time1)/CLOCKS_PER_SEC > speed)
setPos(27,2);
if(downBlock1() == -2)
if(grade2>grade1)
printf("蓝 方 胜!");break;
else if(downBlock2() == -2)
if(grade1==grade2)
printf("平 局");break;
else
printf("红 方 胜!");break;
setPos(27,3);
if(downBlock2() == -2)
if(grade1>grade2)
printf("红 方 胜!");break;
else if(downBlock1() == -2)
if(grade1==grade2)
printf("平 局");break;
else
printf("蓝 方 胜!");break;
time1 = time2;
else if(mode == 3)
setPos(2,10);
printf("剩余时间:%3dS",counter);
setPos(50,10);
printf("剩余时间:%3dS",counter);
if((float)(time2-time1)/CLOCKS_PER_SEC > speed)
counter--;
setPos(27,2);
if(counter == 0)
if(grade2>grade1)
printf("蓝 方 胜!");break;
if(grade1==grade2)
printf("平 局");break;
else
printf("红 方 胜!");break;
if(downBlock1() == -2)
if(grade2>grade1)
printf("蓝 方 胜!");break;
else if(downBlock2() == -2)
if(grade1==grade2)
printf("平 局");break;
else
printf("红 方 胜!");break;
setPos(27,3);
if(downBlock2() == -2)
if(grade1>grade2)
printf("红 方 胜!");break;
else if(downBlock1() == -2)
if(grade1==grade2)
printf("平 局");break;
else
printf("蓝 方 胜!");break;
time1 = time2;
if(mode == 1)
mciSendString("close d",NULL,0,NULL);
if(mode == 2)
mciSendString("close e",NULL,0,NULL);
if(mode == 3)
mciSendString("close f",NULL,0,NULL);
Sleep(1150);
printOver();
printFinish(mode);
初始界面动画打印
void printStart(int x,int y)
//随机产生颜色
int color = rand()%0x10;
//处理黑色的情况
if(color == 0x00)
color = 0x0f;
setColor(color);
setPos(x,y);
printf("■■■■■ ■■■■■ ■■■■■ ■■■■ ■■■ ■■■■");
setPos(x,y+1);
printf(" ■ ■ ■ ■ ■ ■ ■");
setPos(x,y+2);
printf(" ■ ■■■■ ■ ■■■ ■ ■■■");
setPos(x,y+3);
printf(" ■ ■ ■ ■ ■ ■ ■");
setPos(x,y+4);
printf(" ■ ■■■■■ ■ ■ ■ ■■■ ■■■");
setPos(25,14);
printf("按任意键开始游戏!");
setPos(50,30);
printf("author 赵敬轩");
源码地址
gitee:https://gitee.com/i-dream-code/Tetris/
github:https://github.com/zhaojingxuan123/StrongestTetris
百度云盘:链接:https://pan.baidu.com/s/1dJeANXcNqChrXf7zuRQRWw 提取码:geee
导入方法
博主使用的是codeblocks,一款很好用的编译器
网盘链接:链接:https://pan.baidu.com/s/1JkgUL8852lwx87j1NK2nsw 提取码:qqfm
安装好codeblocks后,将 20200705.cbp 直接拖到codeblocks的左侧面板即可
上方build=>run即可运行
总结
“在繁华中自律,在落魄中自愈”, 恍惚间,回首岁月静好。
以上是关于六种模式史上最强c语言俄罗斯方块的主要内容,如果未能解决你的问题,请参考以下文章