基于C++的俄罗斯方块游戏的开发与设计

news/2024/10/30 17:25:13/

目录

game.h

mywindows.h

main.cpp

game.cpp

mywindows.cpp 


 game.h

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <time.h>/**游戏逻辑模块**/#include <stdio.h>///方块结构体
typedef struct {int x;///游戏区列数int y;///游戏区行数int shape;///7种类型的方块int status;///每种方块有四种形态int color;///方块颜色
} BLOCK;void chooseWindow();///任意键开始
void chooseWindow2();///单人模式选择
void chooseWindow3();///双人模式选择void chooseMode();///选择任意一种单人游戏模式
void chooseMode2();///选择任意一种双人游戏模式///游戏所有初始化
int gameInit(int mode);///单人游戏模式
int gameInit1(int mode);///双人游戏模式///绘制游戏池边框
void windowPrint1(int x,int y);///绘制单人游戏池边框
void windowPrint2(int x,int y);///双人游戏区界面///打印操作说明
void printInfo();///双人游戏模式 操作规则框架
void printInfo1();///单人模式之第三种 炫彩模式 操作规则框架
void printInfoStandard();///单人游戏 标准模式 操作规则框架///游戏计时
void gameTime(clock_t start_time);///产生游戏的第一个方块
void startBlock();
void startBlock1();
void startBlock2();
///产生游戏的下一个方块
void nextBlock();
void nextBlock1();
void nextBlock2();
///拷贝方块
void copyBlock();
void copyBlock1();
void copyBlock2();///删除方块
void deleteBlock(int x,int y,int shape,int status);
void deleteBlock1(int x,int y,int shape,int status);
void deleteBlock2(int x,int y,int shape,int status);///打印方块
void printBlock(int x,int y,int shape,int status,int color);
void printBlock1(int x,int y,int shape,int status,int color);
void printBlock2(int x,int y,int shape,int status,int color);///方块下移   返回值:标识方块是否到游戏池底部
int downBlock();
int downBlock1();
int downBlock2();
///方块左移
void leftBlock();
void leftBlock1();
void leftBlock2();
///方块右移
void rightBlock();
void rightBlock1();
void rightBlock2();
///方块方向改变
void changeStatusBlock();
void changeStatusBlock1();
void changeStatusBlock2();
///方块形状改变
void changeShapeBlock();
///方块炫彩效果
void coolColor();///碰撞检测基于下一个位置的检测,数组与界面坐标的对应
int crash(int x,int y,int shape,int status);
int crash1(int x,int y,int shape,int status);
int crash2(int x,int y,int shape,int status);///保存方块
void save();
void save1();
void save2();
///刷新游戏池
void updateGame();
void updateGame1();
void updateGame2();
///消行
void removeLine();
void removeLine1();
void removeLine2();
///暂停
void pause();
///方块直接落底
void bottomBlock();
void bottomBlock1();
void bottomBlock2();///打印分数等级
void printGradelevel(int num);
void printGradelevel1(int num);
void printGradelevel2(int num);///游戏结束动画
void printOver();
///重新开始提示
void printFinish();
///重新开始游戏
void againGame(int mode);
void againGame1(int mode);///打印开始图案
void printStart(int x,int y);
void printStart1(int x,int y);
void printStart2(int x,int y);
void printStart3(int x,int y);///清除开始图案
void deleteStart(int x,int y);
void deleteStart1(int x,int y);
void deleteStart2(int x,int y);
void deleteStart3(int x,int y);///动画效果 ->定时(边界控制)
void printAnimation();#endif /// GAME_H_INCLUDED

 mywindows.h

#ifndef MYWINDOWS_H_INCLUDED
#define MYWINDOWS_H_INCLUDED
//避免重定义错误,多个文件同时引用头文件,当程序进行时,容易发生重定义的情况
//头文件进行封装,其余文件可以快速调用,减少代码书写/*系统调用模块*/
#include <windows.h>//头文件函数声明
//初始化句柄
void initHandle();//小驼峰命名常用于函数和变量命名,大驼峰常用于类的命名///设置颜色
void setColor(int color);///设置光标位置
void setPos(int x,int y);///隐藏光标
void hideCursor();//提示undefine reference -> 头文件与源文件名称不对应#endif // MYWINDOWS_H_INCLUDED

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include "game.h"
#include "mywindows.h"
#include <conio.h>#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")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;
}

game.cpp

///游戏逻辑
#include "game.h"
#include "data.h"
#include "mywindows.h"
#include <conio.h>#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")int k = 0;
int grade = 0;  ///分数
int level = 1;    ///等级
int l1=0;  ///控制点击‘x’炫彩的次数
BLOCK cur_block;   ///当前方块
BLOCK next_block;  ///下一个方块int k1 = 0;
int grade1 = 0;  ///玩家1分数
int level1 = 1;    ///玩家1等级
int grade2 = 0;  ///玩家2分数
int level2 = 1;  ///玩家2等级
int l=0,i,j;
BLOCK cur_block1;   ///玩家1当前方块
BLOCK next_block1;  ///玩家1下一个方块
BLOCK cur_block2;   ///玩家2当前方块
BLOCK next_block2;  ///玩家2下一个方块void printAnimation() {///动画效果 ->定时(边界控制)clock_t time1,time2;time1 = clock();int x = 5;printStart(x,5);///任意键开始界面while(1) {time2 = clock();if(time2 - time1 > 150) {  ///时间间隔300毫秒time1 = time2;deleteStart(x,5);printStart(++x,5);if(25 == x) {deleteStart(x,5);x=5;}}///按任意键退出if(kbhit()) {break;}}system("cls");
}void chooseWindow() {///任意键开始clock_t time1,time2;time1 = clock();int x = 5;printStart1(x,5);while(1) {time2 = clock();if(time2 - time1 > 150) {  ///时间间隔300毫秒time1 = time2;deleteStart1(x,5);printStart1(++x,5);if(25 == x) {deleteStart1(x,5);x=5;}}if(kbhit()) {///按任意键退出break;}}system("cls");
}void chooseWindow2() {///单人模式选择clock_t time1,time2;time1 = clock();int x = 5;printStart2(x,5);while(1) {time2 = clock();if(time2 - time1 > 150) {  ///时间间隔300毫秒time1 = time2;deleteStart2(x,5);printStart2(++x,5);if(25 == x) {deleteStart2(x,5);x=5;}}///按任意键退出if(kbhit()) {break;}}system("cls");
}void chooseWindow3() {///双人模式选择clock_t time1,time2;time1 = clock();int x = 5;printStart3(x,5);while(1) {time2 = clock();if(time2 - time1 > 150) {  ///时间间隔300毫秒time1 = time2;deleteStart3(x,5);printStart3(++x,5);if(25 == x) {deleteStart3(x,5);x=5;}}///按任意键退出if(kbhit()) {break;}}system("cls");
}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("按任意键开始游戏!");
}void printStart1(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(24,16);printf("-----------------");setPos(22,17);printf(" ■  按1进入单人模式  ■");setPos(22,20);printf(" ■  按2进入双人模式  ■");setPos(24,21);printf("-----------------");
}void printStart2(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(24,16);printf("-----------------");setPos(22,17);printf(" ■  按1进入标准模式  ■");setPos(22,20);printf(" ■  按2进入加速模式  ■");setPos(22,23);printf(" ■  按3进入炫彩模式  ■");setPos(24,24);printf("-----------------");
}void printStart3(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(24,16);printf(" ---------------");setPos(23,17);printf(" ■ 按1进入标准赛 ■");setPos(23,20);printf(" ■ 按2进入加速赛 ■");setPos(23,23);printf(" ■ 按3进入计时赛 ■");setPos(24,24);printf(" ---------------");
}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;}}
}void deleteStart(int x,int y) {///清除页面int i,j;for(i = y; i<=y+4; i++) {for(j = x; j<=x+33; j++) {setPos(j,i);printf("%2s","");}}
}void deleteStart1(int x,int y) {///清除页面int i,j;for(i = y; i<=y+4; i++) {for(j = x; j<=x+33; j++) {setPos(j,i);printf("%2s","");}}
}void deleteStart2(int x,int y) {///清除页面int i,j;for(i = y; i<=y+4; i++) {for(j = x; j<=x+33; j++) {setPos(j,i);printf("%2s","");}}}void deleteStart3(int x,int y) {///清除页面int i,j;for(i = y; i<=y+4; i++) {for(j = x; j<=x+33; j++) {setPos(j,i);printf("%2s","");}}
}void printOver() {///游戏结束打印方块int i,j,k=5;for(i=23; i>11; i--) {if(k%4>2) {setColor(rand()%0x60);}for(j=26; j<32; j++) {setPos(j,i);printf("■");Sleep(5);}k++;}
}void printOver1() {int i,j;for(i=23; i>0; i--) {for(j=1; j<15; j++) {setColor(0x76);setPos(j+15,i);printf("■");Sleep(5);}}
}void againGame1(int mode) {///重置分数/等级/游戏池数据->开始游戏level = 1;grade =0;int i,j;for(i=1; i<24; i++) {for(j=1; j<15; j++) {windowShape[i][j] = 0;}}setColor(0x00);system("cls");  ///清屏gameInit(mode);
}void printFinish1(int mode) {setColor(0x10);setPos(21,10);printf("游戏结束! ");setPos(18,11);printf("按Y重新开始 ");setPos(24,11);printf("按N结束游戏");///检测用户按键switch(getch()) {{case 'y':case 'Y':againGame1(mode);break;case 'n':case 'N':mciSendString(TEXT("stop a"),NULL,0,NULL);break;default:printFinish1(mode);break;}}
}void printFinish(int mode) {///游戏结束 是否重新开始setColor(0x10);setPos(26,10);printf(" 游戏结束! ");setPos(26,11);printf("按Y重新开始 ");setPos(26,12);printf("按N结束游戏 ");///检测用户按键switch(getch()) {{case 'y':case 'Y':againGame(mode);break;case 'n':case 'N':break;default:printFinish(mode);break;}}
}void againGame(int mode) {///重置分数/等级/游戏池数据->开始游戏level1 = 1;grade1 = 0;level2 = 1;grade2 = 0;int i,j;for(i=1; i<24; i++) {for(j=11; j<25; j++) {windowShape2[i][j] = 0;}}setColor(0x00);system("cls");  ///清屏for(i=1; i<24; i++) {for(j=33; j<47; j++) {windowShape2[i][j] = 0;}}setColor(0x00);system("cls");  ///清屏gameInit1(mode);
}void printGradeLevel(int num) {///打印单人游戏分数等级switch(num) {case 1:grade+=10;break;case 2:grade+=30;break;case 3:grade+=50;break;case 4:grade+=80;break;case 5:grade+=100;break;}if(grade < 100) {level = 1;} else if(grade >= 100 && grade < 400) {level =2;} else if(grade >= 400 && grade < 900) {level =3;} else if(grade >= 900 && grade < 1700) {level =4;} else if(grade >= 1700 && grade < 2700) {level =5;}setColor(0x09);setPos(3,6);printf("分数:%d",grade);setPos(3,7);printf("等级:%d",level);
}int gameInit(int mode) {///开始单人游戏float speed1;if(mode == 1) {///打开音乐文件mciSendString("open 单人标准.mp3 alias a",NULL,0,NULL);//alias a:为这个路径起一个别名 a///播放音乐mciSendString("play a repeat",NULL,0,NULL);}if(mode == 2) {mciSendString("open 单人加速.mp3 alias b",NULL,0,NULL);mciSendString("play b repeat",NULL,0,NULL);}if(mode == 3) {mciSendString("open 单人炫彩.mp3 alias c",NULL,0,NULL);mciSendString("play c repeat",NULL,0,NULL);}windowPrint1(15,0);if(mode==1) {speed1 = 0.45;printInfoStandard();} else if(mode == 2) {speed1 = 0.2;printInfoStandard();} else if(mode == 3) {speed1 = 0.45;printInfo1();}printGradeLevel(0);///游戏开始时间clock_t startTime = clock();gameTime(startTime);///定时器clock_t time1,time2;time1 = clock();///打印其余边框setPos(1,24);setColor(0x30);printf("                            ");setColor(0x30);setPos(1,0);printf("                            ");int i;startBlock();nextBlock();setColor(0x30);for(i=0; i<25; i++) {setPos(1,i);printf("  ");}setPos(40,25);while(1) {if(mode == 2||mode == 1) {///按键驱动///检测是否有按键按下if(kbhit()) {switch(getch()) {case 'w':case 'W':case 72:changeStatusBlock();break;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 32:pause();break;case 13:bottomBlock();break;}}}if(mode == 3) {///按键驱动///检测是否有按键按下if(kbhit()) {switch(getch()) {case 'w':case 'W':case 72:changeStatusBlock();break;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 'q':case 'Q':speed1-=0.01;break;case 'e':case 'E':speed1+=0.01;break;case 'z':case 'Z':changeShapeBlock();break;case 'x':case 'X':l1++;break;case 32:pause();break;case 13:bottomBlock();break;}}}time2 = clock();///每0.45秒下落一次if((float)(time2-time1)/CLOCKS_PER_SEC > speed1) {gameTime(startTime + k*CLOCKS_PER_SEC);if(downBlock() == -2)break;time1 = time2;}}if(mode == 1) {mciSendString("close a",NULL,0,NULL);}if(mode == 2) {mciSendString("close b",NULL,0,NULL);mciSendString("play b repeat",NULL,0,NULL);}if(mode == 3) {mciSendString("close c",NULL,0,NULL);mciSendString("play c repeat",NULL,0,NULL);}printOver1();printFinish1(mode);
}void windowPrint1(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);  ///x是列,y是行printf("%2s","");}}}
}void printInfo1() {///单人模式之第三种 炫彩模式 操作规则框架setColor(0x01);setPos(33,2);printf("N");setPos(32,3);printf("E");setPos(33,3);printf("X");setPos(34,3);printf("T");setPos(31,9);printf("   --操作规则--");setPos(31,11);printf("  按 a or A 左移");setPos(31,12);printf("  按 d or D 右移");setPos(31,13);printf("  按 s or S 下移");setPos(31,14);printf("  按 w or W 旋转");setPos(31,15);printf("  按   CR  触底");setPos(31,16);printf("  按 SPACE 暂停");setPos(31,17);printf("  按 q 加速");setPos(31,18);printf("  按 e 减速");setPos(31,19);printf("  按 z 变形");setPos(31,20);printf("  按 x 炫彩模式");
}void printInfoStandard() {///单人游戏 标准模式 操作规则框架setColor(0x01);setPos(33,2);printf("N");setPos(32,3);printf("E");setPos(33,3);printf("X");setPos(34,3);printf("T");setPos(31,10);printf("   --操作规则--");setPos(31,11);printf("  按 a or A 左移");setPos(31,12);printf("  按 d or D 右移");setPos(31,13);printf("  按 s or S 下移");setPos(31,14);printf("  按 w or W 旋转");setPos(31,15);printf("  按   CR  触底");setPos(31,16);printf("  按 SPACE 暂停");
}void gameTime(clock_t start_time) {///获取游戏运行时间setColor(0x0b);setPos(3,3);printf("本次游戏已运行 %d s",(clock()-start_time)/CLOCKS_PER_SEC);
}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 < 400) {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 < 400) {level2 =2;}setColor(0x09);setPos(51,8);printf("分数:%d",grade2);setPos(51,9);printf("等级:%d",level2);
}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(49,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 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","");}}}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","");}}}
}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(2,14);printf(" 红方操作规则");setPos(2,15);printf(" ------------");setPos(2,16);printf("按 a or A 左移");setPos(2,17);printf("按 d or D 右移");setPos(2,18);printf("按 s or S 下移");setPos(2,19);printf("按 w or W 旋转");setPos(2,20);printf("按 SPACE 触底");setColor(0x03);setPos(49,2);printf("N");setPos(49,3);printf("E");setPos(49,4);printf("X");setPos(50,3);printf("T");setPos(49,14);printf(" 蓝方操作规则");setPos(49,15);printf(" ------------");setPos(49,16);printf("按 ← 键 左移");setPos(49,17);printf("按 → 键 右移");setPos(49,18);printf("按 ↑ 键 旋转");setPos(49,19);printf("按 ↓ 键 下移");setPos(49,20);printf("按 CR 触底");setPos(27,2);printf("--战况--");setPos(27,3);printf("--------");
}void printBlock(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 deleteBlock(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) {setPos(x+j,y+i);printf("  ");}}}
}void startBlock() {///第一个方块:形状/形态/颜色->随机 位置(x,y)固定的    初始化cur_block///设置随机数种子(时间永远不一样)srand((unsigned)time(NULL));cur_block.x = 22;cur_block.y = 1;cur_block.shape = rand()%7;cur_block.status = rand()%4;cur_block.color = rand()%0x10;if(cur_block.color == 0x00) {///如果随机产生的颜色是黑色,把颜色设置成白色cur_block.color = 0x0f;}printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);
}void nextBlock() {///形状/形态/颜色->随机 位置(x,y)固定      初始化next_block值deleteBlock(next_block.x,next_block.y,next_block.shape,next_block.status);next_block.x = 35;next_block.y = 2;next_block.shape = rand()%7;next_block.status = rand()%4;next_block.color = rand()%0x10;if(next_block.color == 0x00) {///如果随机产生的颜色是黑色,把颜色设置成白色next_block.color = 0x0f;}printBlock(next_block.x,next_block.y,next_block.shape,next_block.status,next_block.color);
}void copyBlock() {///当前方块 = 下一个方块,并产生新的“下一个方块”cur_block = next_block;cur_block.x = 22;cur_block.y = 1;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);nextBlock();
}int downBlock() {///原理:删除正在显示的图层,纵坐标加一,重新打印if(l1%2!=0) {coolColor();}if(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) == -1) {///发生碰撞:方块落到游戏池底部///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块///保存方块->检测消行->打印游戏池->产生新方块save();removeLine();updateGame();copyBlock();return -1;}else if(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) == -2) {
///游戏结束return -2;}else {deleteBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status);cur_block.y += 1;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);return 1;}
}void leftBlock() {///原理:删除正在显示的图层,横坐标减一,重新打印///发生碰撞:方块碰到左边框,无法继续向左移动,向下移动if(crash(cur_block.x-1,cur_block.y,cur_block.shape,cur_block.status) != -1) {deleteBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status);cur_block.x -= 1;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);}
}void rightBlock() {///原理:删除正在显示的图层,横坐标加一,重新打印if(crash(cur_block.x+1,cur_block.y,cur_block.shape,cur_block.status) != -1) {deleteBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status);cur_block.x += 1;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);}
}void changeStatusBlock() {///旋转if(crash(cur_block.x,cur_block.y,cur_block.shape,(cur_block.status+1)%4) != -1) {deleteBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status);if(cur_block.status==3)cur_block.status = 0;elsecur_block.status++;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);}//cur_block.status = (cur_block.status+1)%4;
}void changeShapeBlock() {///改变图形if(crash(cur_block.x,cur_block.y,(cur_block.shape+1)%7,cur_block.status) != -1) {deleteBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status);if(cur_block.shape==6)cur_block.shape = 0;elsecur_block.shape++;printBlock(cur_block.x,cur_block.y,cur_block.shape,cur_block.status,cur_block.color);}
}void coolColor() {///炫彩int i;cur_block.color = rand()%0x10;///如果随机产生的颜色是黑色,把颜色设置成白色if(cur_block.color == 0x00) {cur_block.color = 0x0f;}
}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[y+i][x+j-15] == 1) {///发生碰撞if(cur_block.x == 22 && cur_block.y == 1) {///游戏结束return -2;}return -1;///方块落到游戏池底部,发生碰撞}}}}return 0;
}void save() {///根据方块在界面上的坐标,把坐标对应到游戏池下标的对应位置///方块为1的保存到windowShape数组int i,j;for(i=0; i<4; i++) {for(j=0; j<4; j++) {if(block[cur_block.shape][cur_block.status][i][j] == 1) {windowShape[i+cur_block.y][j+cur_block.x-15] = 1;}}}
}void updateGame() {///更新游戏区域方块int i,j;for(i=23; i>0; 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("  ");}}}
}void removeLine() {///消行之后,下移方块int i,j,m,n;int number = 0;for(i=23; i>1; i--) {int total = 0;for(j=1; j<15; j++) {if(windowShape[i][j] == 1) {total++;}if(total == 14) {number++;for(m = i; m>1; m--) { ///m>1,保证边界不被下移for(n=1; n<15; n++) {windowShape[m][n] = windowShape[m-1][n];}}i++;///统计一次消了几行}}}printGradeLevel(number);
}void pause() { ///暂停,程序去执行另一件事情clock_t time1;time1 = clock();while(1) {if(getch() == 32) {break;}}k +=  (clock()-time1)/CLOCKS_PER_SEC;
}void bottomBlock() { ///发生碰撞:方块落到游戏池底部while(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) != -1&&crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) != -2) {cur_block.y += 1;}if(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) == -1) {///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块save();removeLine();updateGame();copyBlock();} else if(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) == -2) {///游戏结束}
}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("■");}}}
}void deleteBlock1(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) {setPos(x+j,y+i);printf("  ");}}}
}void deleteBlock2(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) {setPos(x+j,y+i);printf("  ");}}}
}void startBlock1() {///第一个方块:形状/形态/颜色->随机 位置(x,y)固定的///初始化cur_block///设置随机数种子(时间永远不一样)srand((unsigned)time(NULL));cur_block1.x = 17;cur_block1.y = 1;cur_block1.shape = rand()%7;cur_block1.status = rand()%4;cur_block1.color = rand()%0x10;///如果随机产生的颜色是黑色,把颜色设置成白色if(cur_block1.color == 0x00) {cur_block1.color = 0x0f;}printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);
}void startBlock2() {///第一个方块:形状/形态/颜色->随机 位置(x,y)固定的///初始化cur_block///设置随机数种子(时间永远不一样)srand((unsigned)time(NULL));cur_block2.x = 39;cur_block2.y = 1;cur_block2.shape = rand()%7;cur_block2.status = rand()%4;cur_block2.color = rand()%0x10;///如果随机产生的颜色是黑色,把颜色设置成白色if(cur_block2.color == 0x00) {cur_block2.color = 0x0f;}printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);}void nextBlock1() {///形状/形态/颜色->随机 位置(x,y)固定///初始化next_block值deleteBlock1(next_block1.x,next_block1.y,next_block1.shape,next_block1.status);next_block1.x = 4;next_block1.y = 2;next_block1.shape = rand()%7;next_block1.status = rand()%4;next_block1.color = rand()%0x10;///如果随机产生的颜色是黑色,把颜色设置成白色if(next_block1.color == 0x00) {next_block1.color = 0x0f;}printBlock1(next_block1.x,next_block1.y,next_block1.shape,next_block1.status,next_block1.color);
}void nextBlock2() {///形状/形态/颜色->随机 位置(x,y)固定///初始化next_block值deleteBlock2(next_block2.x,next_block2.y,next_block2.shape,next_block2.status);next_block2.x = 52;next_block2.y = 2;next_block2.shape = rand()%7;next_block2.status = rand()%4;next_block2.color = rand()%0x10;///如果随机产生的颜色是黑色,把颜色设置成白色if(next_block2.color == 0x00) {next_block2.color = 0x0f;}printBlock2(next_block2.x,next_block2.y,next_block2.shape,next_block2.status,next_block2.color);
}void copyBlock1() {///当前方块 = 下一个方块,并产生新的“下一个方块”cur_block1 = next_block1;cur_block1.x = 17;cur_block1.y = 1;printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);nextBlock1();
}void copyBlock2() {///当前方块 = 下一个方块,并产生新的“下一个方块”cur_block2 = next_block2;cur_block2.x = 39;cur_block2.y = 1;printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);nextBlock2();
}int downBlock1() {///原理:删除正在显示的图层,纵坐标加一,重新打印if(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) == -1) {///发生碰撞:方块落到游戏池底部///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块///保存方块->检测消行->打印游戏池->产生新方块save1();removeLine1();updateGame1();copyBlock1();} else if(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) == -2) {return -2;///游戏结束} else {deleteBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status);cur_block1.y += 1;printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);return 1;}
}int downBlock2() {///原理:删除正在显示的图层,纵坐标加一,重新打印if(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) == -1) {///发生碰撞:方块落到游戏池底部///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块///保存方块->检测消行->打印游戏池->产生新方块save2();removeLine2();updateGame2();copyBlock2();}else if(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) == -2) {///游戏结束return -2;}else {deleteBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status);cur_block2.y += 1;printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);return 1;}
}void leftBlock1() {///原理:删除正在显示的图层,横坐标减一,重新打印///发生碰撞:方块碰到左边框,无法继续向左移动,向下移动if(crash1(cur_block1.x-1,cur_block1.y,cur_block1.shape,cur_block1.status) != -1) {deleteBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status);cur_block1.x -= 1;printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);}
}void leftBlock2() {///原理:删除正在显示的图层,横坐标减一,重新打印///发生碰撞:方块碰到左边框,无法继续向左移动,向下移动if(crash2(cur_block2.x-1,cur_block2.y,cur_block2.shape,cur_block2.status) != -1) {deleteBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status);cur_block2.x -= 1;printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);}}void rightBlock1() {///原理:删除正在显示的图层,横坐标加一,重新打印if(crash1(cur_block1.x+1,cur_block1.y,cur_block1.shape,cur_block1.status) != -1) {deleteBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status);cur_block1.x += 1;printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);}
}void rightBlock2() {///原理:删除正在显示的图层,横坐标加一,重新打印if(crash2(cur_block2.x+1,cur_block2.y,cur_block2.shape,cur_block2.status) != -1) {deleteBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status);cur_block2.x += 1;printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);}}void changeStatusBlock1() {///旋转if(crash1(cur_block1.x,cur_block1.y,cur_block1.shape,(cur_block1.status+1)%4) != -1) {deleteBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status);if(cur_block1.status==3)cur_block1.status = 0;elsecur_block1.status++;printBlock1(cur_block1.x,cur_block1.y,cur_block1.shape,cur_block1.status,cur_block1.color);}//cur_block.status = (cur_block.status+1)%4;
}void changeStatusBlock2() {///旋转if(crash2(cur_block2.x,cur_block2.y,cur_block2.shape,(cur_block2.status+1)%4) != -1) {deleteBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status);if(cur_block2.status==3)cur_block2.status = 0;elsecur_block2.status++;printBlock2(cur_block2.x,cur_block2.y,cur_block2.shape,cur_block2.status,cur_block2.color);}//cur_block.status = (cur_block.status+1)%4;
}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;
}int crash2(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_block2.x == 39 && cur_block2.y == 1) {///游戏结束return -2;}///方块落到游戏池底部,发生碰撞return -1;}}}}return 0;
}void save1() {///根据方块在界面上的坐标,把坐标对应到游戏池下标的对应位置///方块为1的保存到windowShape数组int i,j;for(i=0; i<4; i++) {for(j=0; j<4; j++) {if(block[cur_block1.shape][cur_block1.status][i][j] == 1) {windowShape2[i+cur_block1.y][j+cur_block1.x] = 1;}}}
}void save2() {///根据方块在界面上的坐标,把坐标对应到游戏池下标的对应位置///方块为1的保存到windowShape数组int i,j;for(i=0; i<4; i++) {for(j=0; j<4; j++) {if(block[cur_block2.shape][cur_block2.status][i][j] == 1) {windowShape2[i+cur_block2.y][j+cur_block2.x] = 1;}}}
}void updateGame1() {int i,j;for(i=23; i>0; i--) {for(j=11; j<25; j++) {if(windowShape2[i][j] == 1) {setColor(0x0e);setPos(j,i);printf("■");} else {setColor(0x00);setPos(j,i);printf("  ");}}}
}void updateGame2() {int i,j;for(i=23; i>0; i--) {for(j=33; j<47; j++) {if(windowShape2[i][j] == 1) {setColor(0x0e);setPos(j,i);printf("■");} else {setColor(0x00);setPos(j,i);printf("  ");}}}
}void removeLine1() {int i,j,m,n;int number = 0;for(i=23; i>1; i--) {int total = 0;for(j=11; j<25; j++) {if(windowShape2[i][j] == 1) {total++;}if(total == 14) {number++;for(m = i; m>1; m--) { ///m>1,保证边界不被下移for(n=11; n<25; n++) {windowShape2[m][n] = windowShape2[m-1][n];}}i++;///统计一次消了几行}}}printGradeLevel1(number);
}void removeLine2() {int i,j,m,n;int number = 0;for(i=23; i>1; i--) {int total = 0;for(j=33; j<47; j++) {if(windowShape2[i][j] == 1) {total++;}if(total == 14) {number++;for(m = i; m>1; m--) { ///m>1,保证边界不被下移for(n=33; n<47; n++) {windowShape2[m][n] = windowShape2[m-1][n];}}i++;///统计一次消了几行}}}printGradeLevel2(number);
}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();updateGame1();copyBlock1();} else if(crash1(cur_block1.x,cur_block1.y+1,cur_block1.shape,cur_block1.status) == -2) {///游戏结束}
}void bottomBlock2() {while(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) != -1&&crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) != -2) {cur_block2.y += 1;}if(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) == -1) {///发生碰撞:方块落到游戏池底部///产生新的方块:下一个方块值 -> 当前正在下落的方块,重新产生下一个方块save2();removeLine2();updateGame2();copyBlock2();} else if(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) == -2) {///游戏结束}
}

mywindows.cpp 

#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};    ///字母:一个字符,汉字:两个字符SetConsoleCursorPosition(handle,coord); ///设置句柄位置
}
void hideCursor() {CONSOLE_CURSOR_INFO info;        ///系统的结构体变量名字都是大写info.bVisible = FALSE;           ///设置光标是否可见info.dwSize = 1;                 ///设置光标宽度(1-100)SetConsoleCursorInfo(handle,&info);///指针取地址符
}


http://www.ppmy.cn/news/325614.html

相关文章

Python实现的儿童数数字游戏源代码,数出屏幕里出现的水果个数,并选择对应的数字

Python实现的儿童数数字游戏源代码&#xff0c;数出屏幕里出现的水果个数&#xff0c;并选择对应的数字 完整代码下载地址&#xff1a;Python实现的儿童数数字游戏源代码 核心代码 游戏名 &#xff1a;水果秀&#xff08;fruit show) 游戏作者&#xff1a;Python代码大全 微信…

经典算法案例001-08:如何使用质数设计扫雷(Minesweeper)游戏

扫雷(Minesweeper)游戏 1、扫雷(Minesweeper) 大家都熟悉Windows操作系统中的经典游戏扫雷(Minesweeper)&#xff0c;如果把质数当作一颗雷&#xff0c;那么&#xff0c;下表中红色的数字哪些是雷(质数)&#xff1f;您能找出多少个呢&#xff1f;请评论回复。o(∩_∩)o 哈哈 2、…

T1140,T1150,T2128

T1140&#xff0c;T1150&#xff0c;T2128 T1140T1150T2128计蒜客网址 T1140 扫雷游戏是一款十分经典的单机小游戏。它的精髓在于&#xff0c;通过已翻开格子所提示的周围格地雷数&#xff0c;来判断未翻开格子里是否是地雷。 现在给出 n 行 m 列的雷区中的地雷分布&#xff…

1150. 【克罗地亚】NIKOLA

题目描述 Nikola现在已经成为一个游戏里的重要人物。这个游戏是由一行N个方格&#xff0c;N个方格用1到N的数字表示。Nikola开始是在1号位置&#xff0c;然后能够跳到其他的位置&#xff0c;Nikola的第一跳必须跳到2号位置。随后的每一跳必须满足两个条件&#xff1a; 1、如果…

小游戏

http://armorgames.com/play/1150/compulse 无聊时杀杀时间哦~

javascript实现2048小游戏

2048这种小游戏我相信大多数人都应该玩过&#xff0c;是一款非常经典的益智类小游戏。那么接下来&#xff0c;我们就来看看这款游戏是怎么实现的&#xff0c;如何才能写出这样的游戏。 1、分析界面构成 观察2048游戏的界面可以看出&#xff0c;整体是一个大盒子包裹着&#x…

js初级小游戏

刚刚学完js初级&#xff0c;写了一个简单的小游戏&#xff0c;记录一下自己的成长。 小球吃到礼物会变色。 一下是源码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>Docum…