枕上从妨一夜睡,灯前读尽十年诗。这篇文章主要讲述六种模式史上最强c语言俄罗斯方块相关的知识,希望能为你提供帮助。
::: hljs-center
【六种模式史上最强c语言俄罗斯方块】--------写在前面--------
:::
第一次做标题党,大家轻喷哈。这个游戏是博主在大一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即可运行
文章图片
文章图片
总结“在繁华中自律,在落魄中自愈”, 恍惚间,回首岁月静好。
推荐阅读
- JavaScript 之 Proxy
- Java深层系列「并发编程系列」深入分析和研究MappedByteBuffer的实现原理和开发指南
- 分布式项目中,选型与依赖管理
- 从商详页看多线程编排
- [Python公开课]零基础玩转Python进阶篇----第二节(Python的异常分析及解决)
- 未更新完毕
- crontab的环境变量配置
- 实施遇到Ubuntu系统问题
- 漫画趣解Flink实时数仓