参考链接: Java中的静态块static block
制作一个简易的俄罗斯方块,未调用graphics库(装了半天不成功),完全的黑框操作 基本思路: 1.利二维数组表示地图(也可以利用一维数组,此处利用的是一维数组) 0.表示没有方格,1.表示正在下落的方格 2.表示墙壁 2.共有七种俄罗斯方块,但是有19种状态 (绘制方块处,总共有7种俄罗斯方块,旋转之后可以形成19种方块) 3.每个方块需设置一个中心方块 ,尽量与其他的方块有联系。中心方块用B[0]表示,其他的方块由1,2,3表示
必要的几个实用的函数 1.定位光标函数
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
using namespace std;
//设置文字的显示位置 方法一:空格 t n
//可以利用坐标 x axis y axis
//控制文字显示位置
void gotoxy(int x,int y)
{
COORD pos;//COORD结构体
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
int main()
{
gotoxy(30,10);//横坐标30,纵坐标10
printf("this is a test");
return 0;
}
2.颜色调用函数
#include <stdio.h>
#include<windows.h>
#include <conio.h>
#include<time.h>
using namespace std;
//HANDLE hOut;//控制台的句柄
//color
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
//只能用在windows系统,且不能改变控制台的颜色
return 0;
}
int main()
{
color(14);//0-15号色 ,超过15之后就是改变文本的背景色
// 14号黄色 13号粉色 10号绿色 15白色 6棕色 12红色 11 亮蓝色 2绿色
printf("this is a testn"); //改变了一次之后下面所有的文字都是此种颜色
//要每种颜色则只需要在每个字体前加上相应的颜色代码即可
return 0;
}
3._getch()函数 用于读入按键进行操作 4.函数名:kbhit() //功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
完整的程序:
#include <stdio.h>
#include<windows.h>
#include <conio.h>
#include<time.h>
using namespace std;
int map[250];//地图数组
int nextblock[2];//下一个方块
int endgame;//游戏结束标志 1为游戏进行中,0为游戏失败
int xblock[2];//记录行进中方块形状和位置,xblock[0]记录形状,0为I型,1为其他型,2为O型 xblock[1]为位置
int score;//计分
int speed=20000;//当前速度
//7种俄罗斯方块
int blockI[4] = { 1,1,1,1};//I型方块 xblock[0] = 0
int blockO[9] = { 0,0,0,0,1,1,0,1,1 };//O型方块 2
int blockT[9] = { 0,0,0,1,1,1,0,1,0 };//T型方块 1
int blockL[9] = { 0,1,0,0,1,0,0,1,1 };//L型方块 1
int blockS[9] = { 0,0,0,0,1,1,1,1,0};//S型方块 1
int blockZ[9] = { 0,0,0,1,1,0,0,1,1};//Z型方块 1
int blockJ[9] = { 0,1,0,0,1,0,1,1,0 };//J型方块 1
int color(int c);//颜色
void init();//初始化数据
void gotoxy(int x, int y);//将光标移动到指定位置
void drawborder();//绘制边框
void drawmap();//绘制地图
int ranblock();//方块生成
void drawblock(int block[9]);//绘制方块
void drawnextblock(int x);//绘制下一个方块
void drawmapblock(int block[9]);//向地图上绘制方块
void downblock();//方块下落
void run();//核心逻辑
void heart();//画心形
void welcom();//欢迎界面
void title();//
void regulation();
void me();
void regulation()
{
color(13);
printf("1,上键旋转方块n");
printf("2,0分:废铁 n100分:青铜 n500分:白银 n1000分:黄金 n依次500分递增,最高王者n");
printf("3,空格键暂停,回车键继续游戏");
}
void me()
{
color(13);
printf("t*****************************************************");
printf("ttttt t .----. n");
printf(" tt _.'__ `. n ");
printf(" tt .--(#)(##)---/#\ n");
printf(" tt .' @ /###\ n");
printf("tt1 ------------------略略略略略略 : , ##### n");
printf("tt* ------------------★★★★★★ `-..__.-' _.-\###/ n");
printf("tt2 ------------------略略略略略略 `;_: `"' n ");
printf("tt* ------------------★★★★★★ .'"""""`. n");
printf("tt3 ------------------略略略略略略 /, Main ,\ n");
printf("tt* ------------------★★★★★★ // Menu \\ n");
printf("tt4 ------------------略略略略略略 `-._______.-' n");
printf("tt* ------------------★★★★★★ _ __`. | .'___ n");
printf("tt0 ------------------略略略略略略 (______|______) n");
}
void heart()
{
//打印心形
color(13);
int i = 0, j = 0;
int a = 3;
char c = 3;//心形的ASCII代码是3
for (i = 0; i < 3;i )//行数 3行
{
gotoxy(10,9 i);
for (j = 0; j < 5- 2*i;j )//空格, 5,3,1个空格
{
printf(" ");
}
for (j = 0; j < 5 4 * i;j )//打印符号
{
printf("%c", c);
}
for (j = 0; j < 9- 4 * i;j )//打印空格
{
printf(" ");
}
for (j = 0; j < 5 4 * i;j )//打印符号
{
printf("%c", c);
}
printf("n");
}
for (i = 0; i < 3; i )//打印行数3行
{ gotoxy(10,12 i);
for (j = 0; j < 29;j )//打印符号
printf("%c", c);
printf("n");//打印空格
}
color(12);
for (i = 0; i < 6 1; i )// 打印6行
{
gotoxy(10,15 i);
for (j = 0; j < 2 * i 1; j )//打印空格
printf(" ");
for (j = 0; j < 27-4 * i; j )
printf("%c", c);
printf("n");
}
for (i = 0; i <1; i )//打印行数1行
{
gotoxy(10,22);
for (j = 0; j < 14; j )//打印空格
printf(" ");
for (j = 0; j < 1; j )//打印符号
printf("%c", c);
printf("n");
}
color(14);
gotoxy(24,14);
printf("L");
}
void welcom()
{
heart();
int n;
color(6);
gotoxy(-20,12);
printf("1.Play game");
gotoxy(-8,12);
printf("2.The regulations");
gotoxy(-20,17);
printf("3.Exit");
gotoxy(-8,17);
printf("4.About me");
gotoxy(13,25);
color(4);
printf("Please enter {1,2,3,4}:[ ]bb");//b退格符
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");//清屏
init();
run();
break;
case 2:
system("cls");//清屏
regulation();
getchar();
getchar();
system("cls");//清屏
title();
welcom();
break;
case 3:
exit(0);
break;
case 4:
system("cls");//清屏
me();
getchar();
getchar();
system("cls");//清屏
title();
welcom();
break;
}
}
void title()
{
color(14);
gotoxy(12,3);
printf("JELLY 的 俄 罗 斯 方 块");// 若是显示不成功,则看编译的位数,
//若电脑是32位,则上面编译要用32位编译
color(11);
gotoxy(6,5);
printf("■"); //汉字在x横轴上占用两个位置 ,y轴上占用一个位置
gotoxy(6,6);
printf("■■");
gotoxy(6,7);
printf("■");
color(14);
gotoxy(14,6);
printf("■■"); //汉字在x横轴上占用两个位置 ,y轴上占用一个位置
gotoxy(14,7);
printf("■■");
color(10);
gotoxy(24,6);
printf("■■");
gotoxy(24,7);
printf("■■");
color(13);
gotoxy(33,5);
printf("■");
gotoxy(33,6);
printf("■");
gotoxy(33,7);
printf("■");
gotoxy(33,8);
printf("■");
color(12);
gotoxy(45,6);
printf("■");
gotoxy(41,7);
printf("■■■");
printf("nn");
}
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
//只能用在windows系统,且不能改变控制台的颜色
return 0;
}
//将光标移动到指定位置
void gotoxy(int x,int y)
{
COORD c;
c.X = x 23 ;
c.Y = y 2;
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(handle, c);
CONSOLE_CURSOR_INFO CursorInfo;
//获取控制台光标信息
GetConsoleCursorInfo(handle, &CursorInfo);
//隐藏控制台光标,设置控制台光标状态
CursorInfo.bVisible = false;
SetConsoleCursorInfo(handle, &CursorInfo);
}
//初始化数据
void init()
{
//map数组初始化赋值,0-239赋值为0,240-249赋值为2
for (int i = 0; i < 240; i )
map[i] = 0;
for (int i = 240; i < 250; i )
map[i] = 2;
endgame = 1;
nextblock[0] = 0;//
nextblock[1] = ranblock();///
xblock[0] = 0;//故开始第一个必为I型
xblock[1] = 24;//
score = 0;
drawborder();
}
//绘制边框
void drawborder()
{
//绘制地图边框
color(12);
gotoxy(-2,-1);
printf("┏");
gotoxy(20,-1);
printf("┓");
gotoxy(-2,20);
printf("┗");
gotoxy(20,20);
printf("┛");
for (int i = 0; i < 20; i =2)
{
gotoxy(i, -1);
printf("━");
gotoxy(i, 20);
printf("━");
}
for (int i = -1; i < 21; i )
{
if (i < 19) {
gotoxy(-2, i 1);
//全角竖线
printf("┃");
gotoxy(20, i 1);
printf("┃");
}
}
//绘制预览方块边框
for (int i = 0; i < 10; i )
{
gotoxy(i 30, 2);
printf("-");
}
for (int i = 0; i < 10; i )
{
gotoxy(i 30, 7);
printf("-");
// if (i < 4)
// {
// gotoxy(29,i 2);
// printf("丨");
// gotoxy(39, i 2);
// printf("丨");
// }
}
// color(12);
// gotoxy(25, 1);
// printf("下一个方块:");
// gotoxy(25, 19);
// printf("制作者:jelly");
// gotoxy(25,15);
// printf("当前等级:") ;
}
//随机方块生成
int ranblock() {
int x;
srand((int)time(0));
x = rand() % 7;
return x;
}
//绘制地图
void drawmap()
{
for(int i=1;i<=15;i )
{
color(i);
gotoxy(-10,1);
printf("俄");
gotoxy(-10,3);
printf("罗");
gotoxy(-10,5);
printf("斯");
gotoxy(-10,7);
printf("方");
gotoxy(-10,9);
printf("块");
}
color(12);
gotoxy(25, 1);
printf("下一个方块:");
gotoxy(25, 19);
printf("制作者:jelly");
gotoxy(25,15);
printf("当前等级:") ;
// gotoxy(25, 14);
// printf(" ");
gotoxy(25, 14);
printf("游戏得分: %d",score);
gotoxy(25,13);
printf("当前速度: %d",(21000-speed)/1000);
for (int i = 40; i < 240; i )
{
gotoxy(i*2, i/10 - 4);
//map数组中0为空
if (map[i] == 0)
printf(" ");
//1为移动中方块
if (map[i]== 1)
printf("■");
//2为停止的方块
if (map[i] == 2)
printf("■");
}
gotoxy(35,15);
if(score==0) printf("废铁");
}
//绘制下一个方块
void drawnextblock(int x)
{//下一个方块显示 区域清空,中文图形占用两个字节
for (int i = 0; i < 4; i )
{
gotoxy(i * 2 31, 2);
printf(" ");
gotoxy(i * 2 31, 3);
printf(" ");
gotoxy(i * 2 31, 4);
printf(" ");
gotoxy(i * 2 31, 5);
printf(" ");
}
switch (x)//随机数x进行选择
{
case 0:
color(8);
gotoxy(31, 4);
printf("■");
gotoxy(33, 4);
printf("■");
gotoxy(35, 4);
printf("■");
gotoxy(37, 4);
printf("■");
break;
case 1://在next框中绘制不同的除了I型之外的方块
color(14);
drawblock(blockT);
break;
case 2:
color(11);
drawblock(blockL);
break;
case 3:
color(13);
drawblock(blockO);
break;
case 4:
color(2);
drawblock(blockS);
break;
case 5:
color(6);
drawblock(blockZ);
break;
case 6:
color(15);
drawblock(blockJ);
break;
}
}
//绘制方块(除了I型的其他方块)
void drawblock(int block[9]) {
for (int i = 0; i < 3; i )
{
gotoxy(i * 2 31, 3);
if (block[i] == 0)
printf(" ");
else
printf("■");
gotoxy(i * 2 31, 4);
if (block[i 3] == 0)
printf(" ");
else
printf("■");
gotoxy(i * 2 31, 5);
if (block[i 6] == 0)
printf(" ");
else
printf("■");
}
}
//方块下落
void downblock()
{
//碰撞检测标识//touch为1则为未碰撞
int touch = 1;
for (int i = 239; i >= 0; i--)
{
if (map[i] == 1 && map[i 10] == 2)
touch = 0;
}
if (touch == 1)
{
for (int i = 239; i >= 0; i--)
{
if (map[i] == 1)//向下移动,每行10个元素
{
map[i 10] = map[i];
map[i] = 0;
}
}
xblock[1] = xblock[1] 10;///
}
else if (touch == 0)//在碰撞的基础上将1改为2,即也就是将方块改为固定不动的方块
{
for (int i = 0; i < 240; i )
{
if (map[i] == 1)
map[i] = 2;
}
}
}
//向地图上绘制方块
void drawmapblock(int block[9])
{
for (int i = 0; i < 3; i )
{
map[i 13] = block[i];
map[i 23] = block[i 3];
map[i 33] = block[i 6];
}
//记录方块坐标和类型
xblock[0] = 1;//1为除i和o型其他的形状
xblock[1] = 24;//
}
//核心逻辑
void run()
{
while (endgame)
{
//游戏结束
for (int i=20; i < 30; i )
{
if (map[i] == 2||map[i 10]==2)
{
gotoxy(8, 7);
printf(" 游戏结束,按任意键退出 ");
_getch();
endgame = 0;
}
}
//方块消除
for (int i = 0; i < 24; i )
{
int sign = 0;
for (int j = 0; j < 10; j )
{
if (map[i * 10 j] == 2)
sign ;
}
if (sign == 10)//记录每行的2数即固定的不能动的方块
{
for (int j = 0; j < 10; j )
{
map[i * 10 j] = 0;
}
for (int z = i*10 9; z >=0; z--)//消除一行后其他的向下移动
{
if (map[z] == 2)
{
map[z 10] = 2;
map[z] = 0;
}
}
score=score 100;
//
gotoxy(35,15);
switch(score)
{
case 100: printf("青铜");break;
case 500: printf("白银");speed=speed-1000;break;
case 1000:printf("黄金");break;
case 1500:printf("白金");speed=speed-3000;break;
case 2000:printf("钻石");break;
case 2500:printf("大师");speed=speed-5000;break;
case 3000:printf("王者");break;
}
drawmap();
}
}
//新方块生成标识
int newblock = 1;
for (int i = 0; i < 240; i )
{
if (map[i] == 1)
newblock = 0;
}
//生成新方块
if (newblock == 1)
{
switch (nextblock[0])
{
case 0://i型
map[23] = 1;
map[24] = 1;
map[25] = 1;
map[26] = 1;
xblock[0] = 0;
xblock[1] = 24;
break;
case 1:
color(14);
drawmapblock(blockT);
break;
case 2:
color(11);
drawmapblock(blockL);
break;
case 3:
color(13);
drawmapblock(blockO);//o型
xblock[0] = 2;
break;
case 4:
color(2);
drawmapblock(blockS);
break;
case 5:
color(6);
drawmapblock(blockZ);
break;
case 6:
color(15);
drawmapblock(blockJ);
break;
}
nextblock[0] = nextblock[1];
drawnextblock(nextblock[0]);
nextblock[1] = ranblock();
}
else if (newblock == 0)
{
//方向控制,形态变换
int t = speed,t1=0;
while (t>0)
{
int ch;
if (t1<10&&_kbhit())//函数名:kbhit()
//功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。
{
//需要调用两次,因为功能键第一次返回0或224
ch = _getch();
ch = _getch();
//按下左键,判断左边是否有已经下落的方块和是否已到达左边界,如果没有将正在下落的方块左移
if (ch == 75)//左键
{
for (int i = 0; i < 24; i )
{
if (map[i * 10] == 1)
ch = 0;
}
if (ch!=0&&xblock[0] == 0&&map[xblock[1] 1]==1)
{
if (map[xblock[1] - 2] == 2)
ch = 0;
}
if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1)
{
if (map[xblock[1] - 1] == 2)
ch = 0;
}
if (ch != 0 && xblock[0] != 0)
{
for (int i = xblock[1] - 11; i < xblock[1] - 8; i )
{
if ((map[i] == 1 && map[i - 1] == 2)|| (map[i 10] == 1 && map[i 9] == 2)||( map[i 20] == 1 && map[i 19] == 2))
ch = 0;
}
}
if (ch != 0)
{
for (int i = 0; i < 240; i )
{
if (map[i] == 1)
{
map[i - 1] = map[i];
map[i] = 0;
}
}
xblock[1] = xblock[1] - 1;//
drawmap();
}
}
//按下上按键,判断形态变换后是否重叠已经停止的方块,如没有形态变换
if (ch == 72)//上键
{
for (int i = 0; i < 24; i )
{
if (i * 10 == xblock[1] || (i * 10 9) == xblock[1])
ch = 0;
}
if (ch != 0 && xblock[0] == 0 && map[xblock[1] 1] == 1 && map[xblock[1] 10] != 2 && map[xblock[1] - 10] != 2 && map[xblock[1] - 20] != 2)
{
map[xblock[1] 1] = 0;
map[xblock[1] 2] = 0;
map[xblock[1] - 1] = 0;
map[xblock[1] 10] = 1;
map[xblock[1] - 10] = 1;
map[xblock[1] - 20] = 1;
ch = 0;
}
if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1 && map[xblock[1] 1] != 2 && map[xblock[1] 2] != 2 && map[xblock[1] - 1] != 2)
{
map[xblock[1] 1] = 1;
map[xblock[1] 2] = 1;
map[xblock[1] - 1] = 1;
map[xblock[1] 10] = 0;
map[xblock[1] - 10] = 0;
map[xblock[1] - 20] = 0;
}
if (xblock[0] == 2)
ch = 0;
int tempblock[3][3];
if (ch != 0 && xblock[0] == 1)
{
for (int i = 0; i < 3; i )
{
for (int j = 0; j < 3; j )
{
if (map[xblock[1] - 11 j i*10] != 2)
tempblock[i][j] = map[xblock[1] - 11 j i * 10];
else
tempblock[i][j] = 0;
}
}
for (int i = 0; i < 3; i )
{
for (int j = 0; j < 3; j )
{
if (tempblock[j][2 - i] == 1 && map[xblock[1] - 11 j i * 10] == 2)
ch = 0;
}
}
}
if (ch != 0 && xblock[0] == 1)
{
for (int i = 0; i < 3; i )
{
for (int j = 0; j < 3; j )
{
if ( map[xblock[1] - 11 j i * 10] != 2)
map[xblock[1] - 11 j i * 10] = tempblock[j][2-i];
}
}
}
drawmap();
t1 = t1 1;
}
//按下右键,判断右边是否有已经下落的方块和是否已到达右边界,如果没有将正在下落的方块右移
if (ch == 77)//右键
{
for (int i = 0; i < 24; i )
{
if (map[i * 10 9] == 1)
ch = 0;
}
if (ch != 0 && xblock[0] == 0 && map[xblock[1] 1] == 1)
{
if (map[xblock[1] 3] == 2)
ch = 0;
}
if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1)
{
if (map[xblock[1] 1] == 2)
ch = 0;
}
if (ch != 0 && xblock[0] != 0)
{
for (int i = xblock[1] - 11; i < xblock[1] - 8; i )
{
if ((map[i] == 1 && map[i 1] == 2) || (map[i 10] == 1 && map[i 11] == 2) || (map[i 20] == 1 && map[i 21] == 2))
ch = 0;
}
}
if (ch != 0)
{
for (int i = 239; i >= 0; i--)
{
if (map[i] == 1)
{
map[i 1] = map[i];
map[i] = 0;
}
}
xblock[1] = xblock[1] 1;
}
drawmap();
}
//按下按键,方块下落
if (ch == 80)
{
downblock();
drawmap();
break;
}
//空格 暂停
if(ch==32) system("pause");
}
t = t - 1;//t用来控制速度最开始循环20000次
}
//自动下落
if (t <= 0)
{
downblock();
drawmap();
}
}
}
}
//入口函数
int main()
{
title();
welcom();
return 0;
}