game.cpp
//游戏逻辑
#include "game.h"
#include "data.h"
#include "mywindows.h"
#include <conio.h>
#include <mmsystem.h>
#pragma comment (lib, "winmm.lib")
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 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 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 gameTime(clock_t start_time){
setColor(0x0b);
setPos(3,3);
printf("本次游戏已运行 %d s",(clock()-start_time)/CLOCKS_PER_SEC);
}**/
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("■");
}
}
}
}
/**结构体:是一种集合,可以包含多个变量货值数组(成员)
模板:
struct 结构体名{
结构体包含的变量或者数组;
}; -->分号不能少
1.先定义结构体类型,在定义结构体变量
struct stu{
char *name;
int age;
float score;
};
struct stu stu1,stu2; //stu1,stu2是结构体变量
2.定义结构体类型的同时定义结构体变量
struct stu{
char *name;
int age;
float score;
}stu1,stu2;
struct stu stu3,stu4;
3.直接定义结构体变量
struct{
char *name;
int age;
float score;
}stu1,stu2;
没有结构体名称,后面无法定义结构体变量。
typedef struct stu{
char *name;
int age;
float score;
}STU;
STU stu1,stu2;
**/
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();
// lineClear();
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();
// lineClear();
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;
else cur_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;
else cur_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 lineClear(){
///遍历windowShape,判断是否有满行:这行所有值加起来为14
int i,j;
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; //保证能对所有行进行检测
}
}
}
void lineDown(int line){
///从第line行开始,i= i-1
int i,j;
for(i = line;i>1;i--){ ///i>1,保证边界不被下移
for(j=1;j<15;j++){
windowShape[i][j] = windowShape[i-1][j];
}
}
}
**/
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){
///游戏结束
}
}
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();
// lineClear();
updateGame2();
copyBlock2();
}
else if(crash2(cur_block2.x,cur_block2.y+1,cur_block2.shape,cur_block2.status) == -2){
///游戏结束
}
}
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 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);
}
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);
}
int k = 0;
int grade = 0; //分数
int level = 1; //等级
int l1=0,k;
BLOCK cur_block; ///当前方块
BLOCK next_block; ///下一个方块
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",""); // <--> printf(" ");
}
}
}
}
//操作规则框架
void printInfo1(){
setColor(0x01);
setPos(31,9);
printf("操作规则");
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("按 空格 暂停");
setPos(31,16);
printf("按 q 加速");
setPos(31,17);
printf("按 e 减速");
setPos(31,18);
printf("按 z 变形");
setPos(31,19);
printf("按 x 进入炫彩模式");
}
void printInfoStandard(){
setColor(0x01);
setPos(31,9);
printf("操作规则");
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("按 空格 暂停");
}
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;
}
if(grade < 100){
level = 1;
}
else if(grade >= 100 && grade < 300){
level =2;
}
else if(grade >= 300 && grade < 500){
level =3;
}
else if(grade >= 500 && grade < 800){
level =4;
}
else if(grade >= 800 && grade < 1000){
level =5;
}
setColor(0x09);
setPos(3,6);
printf("分数:%d",grade);
setPos(3,7);
printf("等级:%d",level);
}
void gameTime(clock_t start_time){
setColor(0x0b);
setPos(3,3);
printf("本次游戏已运行 %d s",(clock()-start_time)/CLOCKS_PER_SEC);
}
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("■");
}
}
}
}
/**结构体:是一种集合,可以包含多个变量货值数组(成员)
模板:
struct 结构体名{
结构体包含的变量或者数组;
}; -->分号不能少
1.先定义结构体类型,在定义结构体变量
struct stu{
char *name;
int age;
float score;
};
struct stu stu1,stu2; //stu1,stu2是结构体变量
2.定义结构体类型的同时定义结构体变量
struct stu{
char *name;
int age;
float score;
}stu1,stu2;
struct stu stu3,stu4;
3.直接定义结构体变量
struct{
char *name;
int age;
float score;
}stu1,stu2;
没有结构体名称,后面无法定义结构体变量。
typedef struct stu{
char *name;
int age;
float score;
}STU;
STU stu1,stu2;
**/
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();
// lineClear();
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;
else cur_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;
else cur_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();
// lineClear();
updateGame();
copyBlock();
}
else if(crash(cur_block.x,cur_block.y+1,cur_block.shape,cur_block.status) == -2){
///游戏结束
}
}
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 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 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 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 赵敬轩");
}
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 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(24,18);
printf("-----/ \\------");
setPos(24,19);
printf("-----\\ /------");
setPos(22,20);
printf(" ■ 按2进入双人模式 ■");
setPos(24,21);
printf("-----------------");
setPos(50,30);
printf("author 赵敬轩");
}
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 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 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(24,18);
printf("-----/ \\------");
setPos(24,19);
printf("-----\\ /------");
setPos(22,20);
printf(" ■ 按2进入地狱模式 ■");
setPos(24,21);
printf("-----/ \\------");
setPos(24,22);
printf("-----\\ /------");
setPos(22,23);
printf(" ■ 按3进入作弊模式 ■");
setPos(24,24);
printf("-----------------");
setPos(50,30);
printf("author 程序猿");
}
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 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 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(25,15);
printf(">-红蓝对决-<");
setPos(24,16);
printf("-----------------");
setPos(22,17);
printf(" ■按1 标准赛 ■");
setPos(24,18);
printf("-----/ \\------");
setPos(24,19);
printf("-----\\ /------");
setPos(22,20);
printf(" ■按2 地狱存活赛 ■");
setPos(24,21);
printf("-----/ \\------");
setPos(24,22);
printf("-----\\ /------");
setPos(22,23);
printf(" ■按3 计时赛 ■");
setPos(24,24);
printf("-----------------");
}
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 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 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");
}
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(0x80);
printf(" ");
setColor(0x40);
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);
}
game.h
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <time.h>
/*游戏逻辑模块*/
#include <stdio.h>
///方块结构体
typedef struct{
int x;
int y;
int shape;
int status;
int color;
}BLOCK;
//绘制游戏池边框
void windowPrint2(int x,int y);
//游戏所有初始化
int gameInit(int mode);
int gameInit1(int mode);
//打印操作说明
void printInfo();
void printInfo1();
//打印分数等级
void printGradelevel1(int num);
void printGradelevel2(int num);
//游戏计时
void gameTime(clock_t start_time);
//打印方块
void printBlock1(int x,int y,int shape,int status,int color);
void printBlock2(int x,int y,int shape,int status,int color);
//删除方块
void deleteBlock1(int x,int y,int shape,int status);
void deleteBlock2(int x,int y,int shape,int status);
//产生游戏的第一个方块
void startBlock1();
void startBlock2();
//产生游戏的下一个方块
void nextBlock1();
void nextBlock2();
//拷贝方块
void copyBlock1();
void copyBlock2();
///方块下移
///返回值:标识方块是否到游戏池底部
int downBlock1();
int downBlock2();
///方块左移
///无返回值
void leftBlock1();
void leftBlock2();
///方块右移
///无返回值
void rightBlock1();
void rightBlock2();
///方块方向改变
void changeStatusBlock1();
void changeStatusBlock2();
///方块形状改变
void changeShapeBlock();
///方块炫彩效果
void coolColor();
///碰撞检测函数
int crash1(int x,int y,int shape,int status);
int crash2(int x,int y,int shape,int status);
///保存方块
void save1();
void save2();
///刷新游戏池
void updateGame1();
void updateGame2();
///消行
void removeLine1();
void removeLine2();
///暂停
void pause();
///方块直接落底
void bottomBlock();
///更改计时器
void setClock();
///消行检测
void lineClear();
///消行下移
void lineDown(int line);
///游戏结束动画
void printOver();
///重新开始提示
void printFinish();
///重新开始游戏
void againGame();
///打印开始图案
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 clearStart(int x,int y);
void clearStart1(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();
//打开音乐文件
void openMusic();
//关闭音乐文件
void closeMusic();
void ifHellMode();
//绘制双人对战游戏窗口
#endif // GAME_H_INCLUDED
博客数据:
被访问:735
原创:13
排名:第110392名
粉丝:3个
好了以上就是本期内容
下期再见