本人才疏学浅,代码属于入门级别,仅供互相交流学习,希望大佬指正错误与提供改进
废话不多说,直接展示效果图(vs编译器)
控制为A为左移,D为右移,S为快速下落,空格暂停,J旋转方块
下面为原创代码与解释
原创代码
#include<iostream>
#include<conio.h>
#include<windows.h>
#include<time.h>
using namespace std;
//数据控制台大小
#define LENGTH 22
#define WIDTH 24
//所需属性
int State = 0; int score = 0; bool gameover=true;
enum colour
{
BLACK, BLUE, GREEN, CYAN, RED, PURPLE, YELLOW, WHITE, STRONG
}FrameColor, BlockColora, BlockColorb, Charactercolor;//颜色选项
enum block
{
I, O, T, L, J, S, Z
}currentblocka, currentblockb;//方块选项
struct GRID
{
bool existence = true;
colour currentcolour = BLACK;
int X;
int Y;
}MainForm[(WIDTH - 4) / 2][LENGTH - 2], BlockLocation[4];//打印台结构体
//画图工具
void gotoxy(int x, int y)
{
COORD c = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void Setcolor(colour color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO
cursor_info = { 1,0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void GameInit()
{
for (int i = 0; i < (WIDTH - 4) / 2; i++)
{
for (int j = 0; j < LENGTH - 2; j++)
{
MainForm[i][j].X = i * 2 + 2;
MainForm[i][j].Y = j + 1;
}
}
currentblockb = (block)(rand() % 7);
BlockColorb = (colour)(rand() % 8 + 1);
for (int i = 0; i < 4; i++) { BlockLocation[i].currentcolour = BlockColora; }
switch (currentblocka)
{
case I: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 10; BlockLocation[1].Y = 0; BlockLocation[2].X = 12; BlockLocation[2].Y = 0; BlockLocation[3].X = 14; BlockLocation[3].Y = 0; break;
case O: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 12; BlockLocation[1].Y = 0; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case T: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case L: BlockLocation[0].X = 12; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case J: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case S: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 12; BlockLocation[1].Y = 0; BlockLocation[2].X = 8; BlockLocation[2].Y = 1; BlockLocation[3].X = 10; BlockLocation[3].Y = 1; break;
case Z: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 10; BlockLocation[1].Y = 0; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
}
State = 0;
}//游戏初始化
void DrawConsole()
{
for (int i = 0; i < (WIDTH - 4) / 2; i++)
{
for (int j = 0; j < LENGTH - 2; j++)
{
HideCursor(); gotoxy(MainForm[i][j].X, MainForm[i][j].Y); Setcolor(MainForm[i][j].currentcolour);
cout << "■";
}
}
}//控制台打印
void DrawFrame()
{
FrameColor = RED; Charactercolor = WHITE;
for (int i = 0; i < LENGTH; i++)
{
Setcolor(FrameColor);
if (i == 0 || i == LENGTH - 1)
{
for (int j = 0; j < WIDTH - 1; j += 2)
{
HideCursor(); gotoxy(j, i); cout << "■";
}
}
else
{
HideCursor();
gotoxy(0, i); cout << "■";
gotoxy(WIDTH - 2, i); cout << "■";
}
}
gotoxy(24, 4); Setcolor(Charactercolor);
cout << "当前得分:" << score;
gotoxy(24, 8); Setcolor(Charactercolor);
cout << "下一个方块:";
switch (currentblockb)
{
case I: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■■■"; break;
case O: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(26, 10); cout << "■■"; break;
case T: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(28, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case L: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(30, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case J: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case S: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(28, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(26, 10); cout << "■■"; break;
case Z: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(28, 10); cout << "■■"; break;
}
}//游戏区间打印
void Blockturning()
{
if (_kbhit())
{
switch (_getch())
{
case 's':
case 'S':
case 80:
while (BlockLocation[0].Y < 20 && BlockLocation[1].Y < 20 && BlockLocation[2].Y < 20 && BlockLocation[3].Y < 20 && MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y].existence)
{
DrawConsole();
for (int i = 0; i < 4; i++)
{
if (BlockLocation[i].Y > 0)
{
HideCursor(); gotoxy(BlockLocation[i].X, BlockLocation[i].Y); Setcolor(BlockLocation[i].currentcolour);
cout << "■";
}
}
BlockLocation[0].Y++;
BlockLocation[1].Y++;
BlockLocation[2].Y++;
BlockLocation[3].Y++;
}
break;
case 'a':
case 'A':
case 75:
if ((BlockLocation[0].X - 2) / 2 > 0 && (BlockLocation[1].X - 2) / 2 > 0 && (BlockLocation[2].X - 2) / 2 > 0 && (BlockLocation[3].X - 2) / 2 > 0 && MainForm[((BlockLocation[0].X - 2) / 2) - 1][BlockLocation[0].Y].existence&&MainForm[((BlockLocation[1].X - 2) / 2) - 1][BlockLocation[1].Y].existence&&MainForm[((BlockLocation[2].X - 2) / 2) - 1][BlockLocation[2].Y].existence&&MainForm[((BlockLocation[3].X - 2) / 2) - 1][BlockLocation[3].Y].existence)
{
for (int i = 0; i < 4; i++)
{
BlockLocation[i].X -= 2;
}
}
break;
case 'd':
case 'D':
case 77:
if ((BlockLocation[0].X - 2) / 2 < 10 && (BlockLocation[1].X - 2) / 2 < 10 && (BlockLocation[2].X - 2) / 2 < 10 && (BlockLocation[3].X - 2) / 2 < 10 && MainForm[((BlockLocation[0].X - 2) / 2) + 1][BlockLocation[0].Y].existence&&MainForm[((BlockLocation[1].X - 2) / 2) + 1][BlockLocation[1].Y].existence&&MainForm[((BlockLocation[2].X - 2) / 2) + 1][BlockLocation[2].Y].existence&&MainForm[((BlockLocation[3].X - 2) / 2) + 1][BlockLocation[3].Y].existence)
{
for (int i = 0; i < 4; i++)
{
BlockLocation[i].X += 2;
}
}
break;
case 'j':
case 'J'://旋转
switch (currentblocka)
{
case I:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2 - 1][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 2][BlockLocation[3].Y + 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X - 2; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X - 4; BlockLocation[3].Y = BlockLocation[3].Y + 2;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 + 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2 + 1][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 2][BlockLocation[3].Y - 3].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X + 2; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X + 4; BlockLocation[3].Y = BlockLocation[3].Y - 2;
State = 0;
}break;
}; break;
case O: break;
case T:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 1][BlockLocation[1].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 1][BlockLocation[3].Y].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X + 2; BlockLocation[1].Y = BlockLocation[1].Y - 1;
BlockLocation[3].X = BlockLocation[3].X - 2; BlockLocation[3].Y = BlockLocation[3].Y + 1;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 - 1][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 1][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 1][BlockLocation[3].Y - 2].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X + 2; BlockLocation[1].Y = BlockLocation[1].Y + 1;
BlockLocation[3].X = BlockLocation[3].X - 2; BlockLocation[3].Y = BlockLocation[3].Y - 1;
State++;
}break;
case 2:if (MainForm[(BlockLocation[0].X - 2) / 2 - 1][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y - 2].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 2; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y + 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y - 1;
State++;
}break;
case 3:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y - 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y + 1;
State = 0;
}break;
}; break;
case L:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 1][BlockLocation[1].Y - 3].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 1][BlockLocation[3].Y - 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X + 2; BlockLocation[1].Y = BlockLocation[1].Y - 2;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X - 2; BlockLocation[3].Y = BlockLocation[3].Y;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 - 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 1][BlockLocation[1].Y + 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 1][BlockLocation[3].Y - 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 4; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X + 2; BlockLocation[1].Y = BlockLocation[1].Y + 2;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X - 2; BlockLocation[3].Y = BlockLocation[3].Y;
State++;
}break;
case 2:if (MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y + 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y - 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y + 2;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y;
State++;
}break;
case 3:if (MainForm[(BlockLocation[0].X - 2) / 2 + 2][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y - 3].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y - 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 4; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y - 2;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y;
State = 0;
}break;
}; break;
case J:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[2].X - 2) / 2 - 1][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 2][BlockLocation[3].Y + 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X - 2; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X - 4; BlockLocation[3].Y = BlockLocation[3].Y + 2;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 2][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2 + 1][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y - 3].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X + 4; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X + 2; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X; BlockLocation[3].Y = BlockLocation[3].Y - 2;
State++;
}break;
case 2:if (MainForm[(BlockLocation[0].X - 2) / 2 - 2][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y - 3].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 4; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y - 2;
State++;
}break;
case 3:if (MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y + 1].existence)
{
BlockLocation[0].X = BlockLocation[0].X; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y + 2;
State = 0;
}break;
}; break;
case S:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2 + 1][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y + 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2 + 1][BlockLocation[2].Y - 2].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 2; BlockLocation[0].Y = BlockLocation[0].Y + 1;
BlockLocation[1].X = BlockLocation[1].X; BlockLocation[1].Y = BlockLocation[1].Y + 2;
BlockLocation[2].X = BlockLocation[2].X + 2; BlockLocation[2].Y = BlockLocation[2].Y - 1;
BlockLocation[3].X = BlockLocation[3].X; BlockLocation[3].Y = BlockLocation[3].Y;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 - 1][BlockLocation[0].Y - 2].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y - 1].existence&&MainForm[(BlockLocation[2].X - 2) / 2 - 1][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 2; BlockLocation[0].Y = BlockLocation[0].Y - 1;
BlockLocation[1].X = BlockLocation[1].X; BlockLocation[1].Y = BlockLocation[1].Y - 2;
BlockLocation[2].X = BlockLocation[2].X - 2; BlockLocation[2].Y = BlockLocation[2].Y + 1;
BlockLocation[3].X = BlockLocation[3].X; BlockLocation[3].Y = BlockLocation[3].Y;
State = 0;
}break;
}; break;
case Z:switch (State)
{
case 0:if (MainForm[(BlockLocation[0].X - 2) / 2 + 2][BlockLocation[0].Y - 1].existence&&MainForm[(BlockLocation[1].X - 2) / 2 + 1][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y - 1].existence&&MainForm[(BlockLocation[3].X - 2) / 2 - 1][BlockLocation[3].Y].existence)
{
BlockLocation[0].X = BlockLocation[0].X + 4; BlockLocation[0].Y = BlockLocation[0].Y;
BlockLocation[1].X = BlockLocation[1].X + 2; BlockLocation[1].Y = BlockLocation[1].Y + 1;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y;
BlockLocation[3].X = BlockLocation[3].X - 2; BlockLocation[3].Y = BlockLocation[3].Y + 1;
State++;
}break;
case 1:if (MainForm[(BlockLocation[0].X - 2) / 2 - 2][BlockLocation[0].Y - 1].existence&&MainForm[(BlockLocation[1].X - 2) / 2 - 1][BlockLocation[1].Y - 2].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y - 1].existence&&MainForm[(BlockLocation[3].X - 2) / 2 + 1][BlockLocation[3].Y - 2].existence)
{
BlockLocation[0].X = BlockLocation[0].X - 4; BlockLocation[0].Y = BlockLocation[0].Y;
BlockLocation[1].X = BlockLocation[1].X - 2; BlockLocation[1].Y = BlockLocation[1].Y - 1;
BlockLocation[2].X = BlockLocation[2].X; BlockLocation[2].Y = BlockLocation[2].Y;
BlockLocation[3].X = BlockLocation[3].X + 2; BlockLocation[3].Y = BlockLocation[3].Y - 1;
State = 0;
}break;
}; break;
}
break;
case ' ':
while (1)
{
if (_getch() == ' ')
return;
}
break;
}
}
}//方块转向与键盘控制
void BlockMove()
{
while (BlockLocation[0].Y < 20 && BlockLocation[1].Y < 20 && BlockLocation[2].Y < 20 && BlockLocation[3].Y < 20 && MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y].existence)
{
DrawConsole();
for (int i = 0; i < 4; i++)
{
if (BlockLocation[i].Y > 0)
{
HideCursor(); gotoxy(BlockLocation[i].X, BlockLocation[i].Y); Setcolor(BlockLocation[i].currentcolour);
cout << "■";
}
}
BlockLocation[0].Y++;
BlockLocation[1].Y++;
BlockLocation[2].Y++;
BlockLocation[3].Y++;
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
}
currentblocka = currentblockb;
BlockColora = BlockColorb;
for (int i = 0; i < 4; i++)
{
MainForm[(BlockLocation[i].X - 2) / 2][BlockLocation[i].Y - 1].currentcolour = BlockLocation[i].currentcolour;
MainForm[(BlockLocation[i].X - 2) / 2][BlockLocation[i].Y - 1].existence = false;
}
}//方块下落与处理打印台
void GetScore()
{
for (int i = 1; i < 20; i++)
{
if (MainForm[0][i].existence == false && MainForm[1][i].existence == false && MainForm[2][i].existence == false && MainForm[3][i].existence == false && MainForm[4][i].existence == false && MainForm[5][i].existence == false && MainForm[6][i].existence == false && MainForm[7][i].existence == false && MainForm[8][i].existence == false && MainForm[9][i].existence == false)
{
score += 10;
for (int j = i; j >= 0; j--)
{
for (int a = 0; a < 10; a++)
{
MainForm[a][j].currentcolour = MainForm[a][j - 1].currentcolour;
MainForm[a][j].existence = MainForm[a][j - 1].existence;
MainForm[a][0].existence = true; MainForm[a][0].currentcolour = BLACK;
}
}
}
}
}//游戏得分函数
void Gameover()
{
if (!MainForm[3][0].existence || !MainForm[4][0].existence || !MainForm[5][0].existence || !MainForm[6][0].existence)
{
gameover = false;
gotoxy(6, 9); Setcolor(BLACK);
cout << "■■■■■■";
gotoxy(6, 10); Setcolor(BLACK);
cout << "■■■■■■";
gotoxy(6, 11); Setcolor(BLACK);
cout << "■■■■■■";
gotoxy(6, 12); Setcolor(BLACK);
cout << "■■■■■■";
gotoxy(8, 10);
Setcolor(WHITE);
cout << "游戏结束";
gotoxy(8,11);
Setcolor(WHITE);
cout << "得分:" << score;
gotoxy(0, 22);
}
}//游戏死亡函数
int main()
{
srand((unsigned int)time(NULL));
currentblocka = (block)(rand() % 7);
BlockColora = (colour)(rand() % 8 + 1);
GameInit();
DrawFrame();
DrawConsole();
while (gameover)
{
BlockMove();
GameInit();
GetScore();
DrawFrame();
Gameover();
Sleep(100);
}
}
关于俄罗斯方块的实现方式,本人苦思良久,基于水平有限,只采用了最基本的实现方式
下面主要讲解实现方式与画图工具
首先是画图工具(学习了高人的window.h库的使用)
主要是这三个函数
void gotoxy(int x, int y)
{
COORD c = { x,y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void Setcolor(colour color)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO
cursor_info = { 1,0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
gotoxy()用于设置输出值的位置(将调试器看做xy坐标轴从左上角开始向左为x的正方向,向下为y的正方向)。
Setcolor(int color)用于设置输出值的颜色,传入参数为数字,我设置了9中不同颜色。
HideCursor()为关闭输出时闪烁的光标。
接下来为俄罗斯方块的实现机制与算法
首先定义了游戏区的结构体数组
struct GRID
{
bool existence = true;
colour currentcolour = BLACK;
int X;
int Y;
}MainForm[(WIDTH - 4) / 2][LENGTH - 2], BlockLocation[4];
MainForm为整个方块运行区的数组(用来处理是否该格已经被落下的方块所占(existence)与储存占据该格子的颜色信息)。
BlockLocation为存储落下方块的数组,他们由随机机制生成。
下面为初始化游戏设置与随机生成初始下落方块
void GameInit()
{
for (int i = 0; i < (WIDTH - 4) / 2; i++)
{
for (int j = 0; j < LENGTH - 2; j++)
{
MainForm[i][j].X = i * 2 + 2;
MainForm[i][j].Y = j + 1;
}
}
currentblockb = (block)(rand() % 7);
BlockColorb = (colour)(rand() % 8 + 1);
for (int i = 0; i < 4; i++) { BlockLocation[i].currentcolour = BlockColora; }
switch (currentblocka)
{
case I: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 10; BlockLocation[1].Y = 0; BlockLocation[2].X = 12; BlockLocation[2].Y = 0; BlockLocation[3].X = 14; BlockLocation[3].Y = 0; break;
case O: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 12; BlockLocation[1].Y = 0; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case T: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case L: BlockLocation[0].X = 12; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case J: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 8; BlockLocation[1].Y = 1; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
case S: BlockLocation[0].X = 10; BlockLocation[0].Y = 0; BlockLocation[1].X = 12; BlockLocation[1].Y = 0; BlockLocation[2].X = 8; BlockLocation[2].Y = 1; BlockLocation[3].X = 10; BlockLocation[3].Y = 1; break;
case Z: BlockLocation[0].X = 8; BlockLocation[0].Y = 0; BlockLocation[1].X = 10; BlockLocation[1].Y = 0; BlockLocation[2].X = 10; BlockLocation[2].Y = 1; BlockLocation[3].X = 12; BlockLocation[3].Y = 1; break;
}
State = 0;
}//游戏初始化
下面为两大打印函数
void DrawConsole()
{
for (int i = 0; i < (WIDTH - 4) / 2; i++)
{
for (int j = 0; j < LENGTH - 2; j++)
{
HideCursor(); gotoxy(MainForm[i][j].X, MainForm[i][j].Y); Setcolor(MainForm[i][j].currentcolour);
cout << "■";
}
}
}//控制台打印
void DrawFrame()
{
FrameColor = RED; Charactercolor = WHITE;
for (int i = 0; i < LENGTH; i++)
{
Setcolor(FrameColor);
if (i == 0 || i == LENGTH - 1)
{
for (int j = 0; j < WIDTH - 1; j += 2)
{
HideCursor(); gotoxy(j, i); cout << "■";
}
}
else
{
HideCursor();
gotoxy(0, i); cout << "■";
gotoxy(WIDTH - 2, i); cout << "■";
}
}
gotoxy(24, 4); Setcolor(Charactercolor);
cout << "当前得分:" << score;
gotoxy(24, 8); Setcolor(Charactercolor);
cout << "下一个方块:";
switch (currentblockb)
{
case I: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■■■"; break;
case O: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(26, 10); cout << "■■"; break;
case T: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(28, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case L: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(30, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case J: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■"; gotoxy(26, 10); cout << "■■■"; break;
case S: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(28, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(26, 10); cout << "■■"; break;
case Z: gotoxy(26, 9); Setcolor(BLACK); cout << "■■■■"; gotoxy(26, 10); cout << "■■■■"; gotoxy(26, 9); Setcolor(BlockColorb); cout << "■■"; gotoxy(28, 10); cout << "■■"; break;
}
}//游戏区间打印
下面为核心的方块移动与主函数
void BlockMove()
{
while (BlockLocation[0].Y < 20 && BlockLocation[1].Y < 20 && BlockLocation[2].Y < 20 && BlockLocation[3].Y < 20 && MainForm[(BlockLocation[0].X - 2) / 2][BlockLocation[0].Y].existence&&MainForm[(BlockLocation[1].X - 2) / 2][BlockLocation[1].Y].existence&&MainForm[(BlockLocation[2].X - 2) / 2][BlockLocation[2].Y].existence&&MainForm[(BlockLocation[3].X - 2) / 2][BlockLocation[3].Y].existence)
{
DrawConsole();
for (int i = 0; i < 4; i++)
{
if (BlockLocation[i].Y > 0)
{
HideCursor(); gotoxy(BlockLocation[i].X, BlockLocation[i].Y); Setcolor(BlockLocation[i].currentcolour);
cout << "■";
}
}
BlockLocation[0].Y++;
BlockLocation[1].Y++;
BlockLocation[2].Y++;
BlockLocation[3].Y++;
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
Sleep(100);
Blockturning();
}
currentblocka = currentblockb;
BlockColora = BlockColorb;
for (int i = 0; i < 4; i++)
{
MainForm[(BlockLocation[i].X - 2) / 2][BlockLocation[i].Y - 1].currentcolour = BlockLocation[i].currentcolour;
MainForm[(BlockLocation[i].X - 2) / 2][BlockLocation[i].Y - 1].existence = false;
}
}//方块下落与处理打印台
int main()
{
srand((unsigned int)time(NULL));
currentblocka = (block)(rand() % 7);
BlockColora = (colour)(rand() % 8 + 1);
GameInit();
DrawFrame();
DrawConsole();
while (gameover)
{
BlockMove();
GameInit();
GetScore();
DrawFrame();
Gameover();
Sleep(100);
}
}
方块移动函数处理了下落方块是否碰壁与到底,下落后将自身值赋给Mainform中的相应数组对象
本人水平有限,代码臃肿别扭,希望大佬指点修改