这里为大家敲写一段怎样用C语言实现俄罗斯方块:
首先推荐大家使用CodeBlocks这个软件,方便添加不同的工程。
代码中有很多注释便于理解!
下面是效果图和全部的代码以及注释,大家可以观看并自己新增内容!
1、首先是main.c文件:
#include <stdio.h> #include <stdlib.h> #include "game.h" int main() { gameInit(); return 0; }
2、然后是mywindows.h文件:
#ifndef MYWINDOWS_H_INCLUDED #define MYWINDOWS_H_INCLUDED // 封装系统函数-系统调用模块 #include <windows.h> // 初始化句柄 extern void initHandle(); // 设置颜色 extern void setColor(int color); // 设置光标位置 extern void setPos(int x, int y); // 设置光标是否可见 extern void setCursorVisible(int flag); // 关闭句柄 extern void closeHandle(); #endif // MYWINDOWS_H_INCLUDED
3、接下来是mywindows.c文件:
#include "mywindows.h" HANDLE handle; // 初始化句柄 void initHandle() { handle = GetStdHandle(STD_OUTPUT_HANDLE); } // 设置颜色 void setColor(int color) { SetConsoleTextAttribute(handle, color); } void setPos(int x, int y) { //, , COORD coord = {x*2, y}; SetConsoleCursorPosition(handle, coord); } // 设置光标是否可见 void setCursorVisible(int flag) { CONSOLE_CURSOR_INFO info; info.bVisible = flag; //光标是否可见 info.dwSize = 100; //光标宽度1-100 SetConsoleCursorInfo(handle, &info); } // 关闭句柄 void closeHandle() { CloseHandle(handle); }
4、下面是data.h文件,也就是数据库的存储地址:
#ifndef DATA_H_INCLUDED #define DATA_H_INCLUDED //函数声明\变量声明 // 存储数据-数据模块 //界面数组 extern int windowShape[25][26]; extern int block[7][4][4][4]; #endif // DATA_H_INCLUDED
5、数据库内容:data.c
#include "data.h" //函数的定义 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} };// 边框为1,游戏池长度为14 int block[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}} } };
6、游戏头部:game.h:
#ifndef GAME_H_INCLUDED #define GAME_H_INCLUDED // 游戏逻辑模块 #include <stdio.h> #include <time.h> typedef struct{ int x; int y; int shape; int status; int color; }BLOCK; // 定义当前正在下落的方块,和下一个方块 BLOCK curBlock; BLOCK nextBlock; // 绘制游戏池边框 extern void gamePool(int x, int y); // 打印操作说明 extern void printRule(); // 打印分数和等级 extern void printGradeLevel(int num); // 游戏计时 extern void gameTime(clock_t startTime); // 打印一个方块 extern void printBlock(int x, int y, int shape, int status, int color); // 删除一个方块 extern void delBlock(int x, int y, int shape, int status); //方块左移 extern void leftBlock(); //方块右移 extern void rightBlock(); //方块下移 extern int downBlock(); //方块变形 extern void changeBlock(); //方块直接落底 extern void bottomBlock(); //游戏暂停 extern void pause(); //随机产生游戏第一个方块 extern void startBlock(); //随机产生下一个方块 extern void blockNext(); //拷贝方块:把下一个方块变成当前正在下落的方块 extern void copyBlock(); //碰撞检测 extern int crash(int x, int y, int shape, int status); //保存方块 extern void saveBlock(); //刷新游戏池 extern void updateGamePool(); //消行检测 extern void lineClear(); //消行下移 extern void lineDown(int line); // 初始化游戏 extern void gameInit(); #endif // GAME_H_INCLUDED
7、最后一部分,游戏内容,game.c文件:
#include "game.h" #include "mywindows.h" #include "data.h" #include <conio.h> int level = 1; int grade = 100; // 打印游戏池 void gamePool(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(x+j,y+i); printf(" "); // printf("%2s", ""); } } } } // 打印操作说明 void printRule() { setColor(0x0f); setPos(31, 9); printf("操作规则:"); setPos(32, 11); printf("按a或A左移"); setPos(32, 12); printf("按d或D右移"); setPos(32, 13); printf("按s或S下移"); setPos(32, 14); printf("按w或W变形"); setPos(32, 15); printf("按空格暂停"); setPos(32, 16); printf("按回车直接下落"); } void printGradeLevel(int num) { switch(num) { case 0: break; case 1: grade += 10;break; case 2: grade += 25;break; case 3: grade += 50;break; case 4: grade += 70;break; } //等级-->作业 setColor(0x09); setPos(3,6); printf("分数:%d", grade); setColor(0x0a); setPos(3,7); printf("等级:%d", level); } void gameTime(clock_t startTime) { //clock_t endTime = clock(); //clock_t ti = (endTime-startTime)/CLOCKS_PER_SEC; setColor(0x0d); setPos(3,8); printf("本次游戏运行时间:%ld", (clock()-startTime)/CLOCKS_PER_SEC); } // 打印一个方块 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(1 == block[shape][status][i][j]) { setPos(x+j,y+i); printf("■"); } } } } // 删除一个方块 void delBlock(int x, int y, int shape, int status) { int i, j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(1 == block[shape][status][i][j]) { setPos(x+j,y+i); printf(" "); //打印两个空格 } } } } //方块左移 void leftBlock() { //已经显示的方块删除,改变坐标,重新打印 if(crash(curBlock.x-1, curBlock.y, curBlock.shape,curBlock.status) == -1) { return; } delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.x -= 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); } //方块右移 void rightBlock() { if(crash(curBlock.x+1, curBlock.y, curBlock.shape,curBlock.status) == -1) { return; } delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.x += 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); } //方块下移 int downBlock() { if(crash(curBlock.x, curBlock.y+1,curBlock.shape,curBlock.status) == -1) { //落到游戏池底部,产生新方块 saveBlock(); lineClear(); updateGamePool(); copyBlock(); return -1; }else if(crash(curBlock.x, curBlock.y+1,curBlock.shape,curBlock.status) == -2) { //游戏结束 return -2; }else{ delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.y += 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); return 0; } } //方块变形 void changeBlock() { if(crash(curBlock.x, curBlock.y, curBlock.shape, (curBlock.status+1)%4) == -1){ return; } delBlock(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); } //方块直接落底 void bottomBlock() { while(1){ //流程参考方块下落 if(downBlock() !=0){ return; } } } //游戏暂停 void pause() { // } //随机产生游戏第一个方块 void startBlock() { //设置时间为随机数种子 srand((unsigned)time(NULL)); //初始化curBlock curBlock.x = 22; curBlock.y = 1; //rand取一个随机整数 curBlock.shape = rand()%7; //0-6 curBlock.status = rand()%4; //0-3 curBlock.color = rand()%0x10; if(0x00 == curBlock.color) { curBlock.color = 0x0f; } printBlock(curBlock.x, curBlock.y, curBlock.shape, curBlock.status, curBlock.color); } //随机产生下一个方块 void blockNext() { //初始化nextBlock delBlock(nextBlock.x,nextBlock.y, nextBlock.shape,nextBlock.status); nextBlock.x = 34; nextBlock.y = 2; nextBlock.shape = rand()%7; nextBlock.status = rand()%4; nextBlock.color = rand()%0x10; if(0x00 == nextBlock.color) { nextBlock.color = 0x0f; } printBlock(nextBlock.x,nextBlock.y, nextBlock.shape,nextBlock.status,nextBlock.color); } //拷贝方块:把下一个方块变成当前正在下落的方块 void copyBlock() { //当前方块=下一个方块 curBlock = nextBlock; curBlock.x = 22; curBlock.y = 1; printBlock(curBlock.x, curBlock.y, curBlock.shape, curBlock.status, curBlock.color); blockNext(); } //碰撞检测 //x,y为方块的下一个位置, status下一种形态 //碰撞返回-1,未碰撞返回0, 游戏结束返回-2 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(block[shape][status][i][j] == 1) { if(windowShape[i+y][j+x-15] == 1) { //方块一产生就发生碰撞 if(curBlock.x == 22 && curBlock.y == 1) { return -2; } return -1; } } } } return 0; } //保存方块 void saveBlock() { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(block[curBlock.shape][curBlock.status][i][j] == 1) { windowShape[i+curBlock.y][j+curBlock.x-15] = 1; } } } } //刷新游戏池 void updateGamePool() { int i,j; //从下到上刷新游戏池 for(i=23;i>0;i--) { for(j=1;j<15;j++) { if(windowShape[i][j] == 1) { setColor(0x0e); setPos(j+15,i); printf("■"); }else{ setColor(0x00); setPos(j+15,i); printf(" "); } } } } //消行检测 //检测满行->这一行所有值都为1 void lineClear() { int i,j; int num = 0; //统计一次消行数目 for(i=23;i>0;i--) { int total = 0; for(j=1;j<15;j++) { total += windowShape[i][j]; } if(total == 14) { //满行 lineDown(i); i += 1; num += 1; } } printGradeLevel(num); } //消行下移 //从满行的这行开始,上面所有行顺序下移 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]; } } } // 初始化游戏 void gameInit() { //第一步,必须初始化句柄 //clock_t startTime = clock(); initHandle(); setCursorVisible(FALSE); gamePool(15,0); printRule(); printGradeLevel(0); startBlock(); blockNext(); //定时开始时间,结束时间,通过控制时间差实现定时 clock_t start,stop; start = clock(); while(1) //for(;;) { //检测是否有按键按下 if(kbhit()) { switch(getch()) { case 'a': case 'A': case 75: leftBlock();break; case 'd': case 'D': case 77: rightBlock();break; case 's': case 'S': case 80: downBlock();break; case 'w': case 'W': case 72: changeBlock();break; case 32: pause();break; case 13: bottomBlock();break; } } //获取时间 stop = clock(); if(stop-start>0.5*CLOCKS_PER_SEC) { downBlock(); //重新计时 start = stop; } } }
好,到现在这个游戏也就结束了!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学编程网。
- 本文固定链接: https://zxbcw.cn/post/204586/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)