如何制作俄罗斯方块(作业第二部分)

上接Maketetris继续:
在Maketetris里,一共有19个case,第一个case是田字格的形态,田字格有且只有一种形态,我们在Printtetris里面,已经将b数组,也就是方块数组全部赋值为1,而且中心方块一直是4X4大方块里第三行第二个方块,它的xy坐标不用动,所以不需要在写代码的时候再写19次,所以一开始即可对a[80][80] 定位数组赋值了,a数组具体怎么用这里还讲不清楚,后面用到的函数会讲到。每个case 都会有b1,b2,b3数组来赋值,赋值为1

void CleanTetris(struct Tetris*tetris)void CleanTetris(struct Tetris*tetris)
{
	
	for(i=0;i<4;i++)
	{
		b[i]=0;
	}
	
	MakeTetris(tetris);
	
	for(i=tetris->x-2;i<=tetris->x+4;i+=2)
	{
		
		for(j=tetris->y-2;j<=tetris->y+1;j++)
		{
			
			if(a[i][j]==0&&j>FrameY)
			{
				gotoxy(i,j);
				printf("  ");
			}
	
		}
	}
}

与Printtetris类似,不过Clean函数里将b数组全部赋值为0,因为是要清除上一时间点方块的痕迹,不然看起来会很糟糕,同样里面调用了MakeTetris函数,因为具体需要如何清除痕迹,需要由每个链表节点(方块)的flag(方块的形态共19种)来判定,与Printtetris很类似。

int ifMove(struct Tetris*);
int ifMove(struct Tetris*tetris)
{
	if(a[tetris->x][tetris->y]!=0)
	{
		return 0;
	}
	else 
	{
		if((tetris->flag==1&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x+2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==2&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0&&a[tetris->x+4][tetris->y]==0) ) ||
		(tetris->flag==3&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y-2]==0&&a[tetris->x][tetris->y+1]==0) ) ||
		(tetris->flag==4&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0&&a[tetris->x][tetris->y+1]==0) ) ||
		(tetris->flag==5&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y]==0) ) ||
		(tetris->flag==6&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==7&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==8&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y+1]==0) ) ||
		(tetris->flag==9&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x-2][tetris->y+1]==0) ) ||
		(tetris->flag==10&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==11&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x-2][tetris->y]==0) ) ||
		(tetris->flag==12&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y-1]==0) ) ||
		(tetris->flag==15&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x-2][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==14&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x+2][tetris->y+1]==0) ) ||
		(tetris->flag==13&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==16&&(a[tetris->x][tetris->y+1]==0&&a[tetris->x][tetris->y-1]==0&&a[tetris->x+2][tetris->y-1]==0) ) ||
		(tetris->flag==19&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x-2][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0) ) ||
		(tetris->flag==18&&(a[tetris->x][tetris->y-1]==0&&a[tetris->x][tetris->y+1]==0&&a[tetris->x-2][tetris->y+1]==0) ) ||
		(tetris->flag==17&&(a[tetris->x-2][tetris->y]==0&&a[tetris->x+2][tetris->y+1]==0&&a[tetris->x+2][tetris->y]==0) ))
		{
			return 1;
		}   		
	}
	return 0;
}

ifMove 需要说的一点是,每当调用ifMove之前,方块的xy坐标都会先发生改变,向左向右,或是加速向下,然后用ifMove判断,已经改变的中心坐标,是否在以中心方块坐标为中心方块的4X4方块里面,是否符合相应的flag形态,如果符合 return1,如果不符合return 0,可以看到先判断的是:

if(a[tetris->x][tetris->y]!=0)
	{
		return 0;
	}

先判断的是中心方块,同理,不需要19个形态一次一次判断,如果连中心方块都不能放入,肯定不可能放入,a数组在这里的作用就是去判断是否在已经改变的中心坐标位置上,是否有方块,a数组就是一个定位作用。(以上代码的xy坐标都是被提前“试着改过”的,如果ifMove返回0,都会进行还原)。

为了方便理解,用flag1 作为例子:

在这里插入图片描述

void Del_Fullline(struct Tetris*tetris);
void Del_Fullline(struct Tetris*tetris)
{

	int k,del_rows=0;
	for(j=FrameY+Frame_height-1;j>=FrameY+1;j--)//定位于下边框至上边框
	{
		k=0;
		for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2)//定位于左边框至右边框
		{
			if(a[i][j]==1)
			{
				
				k++;
				if(k==Frame_width-2)//如果满行
				{
					for(k=FrameX+2;k<FrameX+2*Frame_width-2;k+=2)//进行清行操作
					{
						a[k][j]=0;
						gotoxy(k,j);
						printf("  ");
					}
					
					for(k=j-1;k>FrameY;k--)//清完一行,被清行上面一行或N行需要集体落下
					{
						for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2)
						{
							if(a[i][k]==1)
							{
								a[i][k]=0;
								gotoxy(i,k);
								printf("  ");
								a[i][k+1]=1;
								gotoxy(i,k+1);
								printf("▇");
								
							}
						}
					}
					j++;
					del_rows++;//用来计算分数
				}
			    }
		}
	}
	score+=100*del_rows;//每清一行,加100分
	if(del_rows>0&&(score%1000==0||score/1000>level-1))
	{
		speed-=30;//当每满1000分的时候,延迟速度减少30毫秒
		level++;//恭喜你升级1级
	}
}

这是判断是否满行的函数,也是每个方块落定以后需要判定的,照着注释很好理解。

void Regulation();
void explantion();
void Replay();
void welcome();
void title();
void flower();
void closer();
int  color();
void explantion();

以上几个函数,几乎没有用到任何参数,基本上都是定位和打印,以下是图片和源代码:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void Regulation()
{
	int i,j=1;
	system("cls");
	color(13);
	gotoxy(34,3);
	printf("Regulation");
	color(2);
	for(i=6;i<=18;i++)
	{
		for(j=12;j<=70;j++)
		{
			gotoxy(j,i);
			if(i==6||i==18) printf("=");
			else if(j==12||j==69) printf("=");
		}
	}
	color(12);
	gotoxy(16,7);
	printf("tip1:不同形状的小方块从屏幕上方落下,玩家通过调整");
	gotoxy(22,9);
	printf("方块的位置和方向,使他们在屏幕拼出完整的");
	gotoxy(22,11);
	printf("一条或者几条");
	color(14);
	gotoxy(16,13);
	printf("tip2:每消除一行,积分涨100");
	color(11);
	gotoxy(16,15);
	printf("tip3:每累计1000分,会提升一个等级");
	color(10);
	gotoxy(16,17);
	printf("tip4:提升等级会使方块下落速度加快,游戏难度加大");
	getch();
	system("cls");
	welcome();
}
void explantion()
{
   	int i,j=1;
	system("cls");
	color(13);
	gotoxy(32,3);
	printf("explanation");
	color(2);
	for(i=6;i<=16;i++)
	{
		for(j=15;j<=60;j++)
		{
			gotoxy(j,i);
			if(i==6||i==16) printf("=");
			else if(j==15||j==59) printf("||");
		}
	}
	color(3);
	gotoxy(18,7);
	printf("tip1:玩家可以通过方向键来移动方块");
	color(10);
	gotoxy(18,9);
	printf("tip2:通过向上键旋转方块");
	color(14);
	gotoxy(18,11);
	printf("tip3:通过向下键加速方块下落");
	color(11);
	gotoxy(18,13);
	printf("tip4:按空格键暂停游戏");
	color(4);
	gotoxy(18,15);
	printf("tip5:按ESC键退出游戏");
	getch();
	system("cls");
	main();

}
void Replay()
{
	system("cls");
	memset(a,0,6400*sizeof(int));
	DrawGameframe();
	Gameplay();
}
void welcome()
{
	int n;
	int i,j=1;
	color(14);
	for(i=9;i<=20;i++)
	{
		 for(j=15;j<=60;j++)
		 {
		 	 gotoxy(j,i);
		 	 if(i==9||i==20)
		 	 printf("=");
		 	 else if(j==15||j==59)
		 	 printf("||");
		 }
	}
	
	color(12);
	gotoxy(25,12);
	printf("1.开始游戏");
	gotoxy(40,12);
	printf("2.按键说明");
	gotoxy(25,17);
	printf("3.游戏规则");
	gotoxy(40,17);
	printf("4.退出");
	gotoxy(21,22);
	color(3);
	printf("请选择【1 2 3 4】:[ ]\b\b");
	color(14);
	scanf("%d",&n);
	
	switch(n)
	{	
		case 1:
			system("cls");
	        DrawGameframe();
	        Gameplay();
			break;
		case 2:
			explantion();
			break;
		case 3:
			Regulation(); 
			break;
		case 4:
			closer();
			break;
	 } 
}
void title()
{
	color(15);
	gotoxy(28,3);
	printf("俄  罗  斯  方  块\n");
	color(11);
	gotoxy(18,5);
	printf("▇");
	gotoxy(18,6);
	printf("▇▇");
	gotoxy(18,7);
	printf("▇");
	
	color(14);
	gotoxy(26,6);
	printf("▇▇");
	gotoxy(28,7);
	printf("▇▇");
	
	color(10);
	gotoxy(36,6);
	printf("▇▇");
	gotoxy(36,7);
	printf("▇▇");
	
	color(13);
	gotoxy(45,5);
	printf("▇");
	gotoxy(45,6);
	printf("▇");
	gotoxy(45,7);
	printf("▇");
	gotoxy(45,8);
	printf("▇");
	
	color(12);
	gotoxy(56,6);
	printf("▇");
	gotoxy(52,7);
	printf("▇▇▇");
}
void flower()
{
		gotoxy(66,11);
	color(12);
	printf("(_)");
	
	gotoxy(64,12);
	printf("(_)");
	
	gotoxy(68,12);
	printf("(_)");
	
	gotoxy(66,13);
	printf("(_)");
	
	gotoxy(67,12);
	color(6);
	printf("@");
	
	gotoxy(72,10);
	color(13);
	printf("(_)");
	
	gotoxy(76,10);
	printf("(_)");
	
	gotoxy(74,9);
	printf("(_)");
	
	gotoxy(74,11);
	printf("(_)");
	
	gotoxy(75,10);
	color(6);
	printf("@");
	
	gotoxy(71,12);
	printf("|");
	
	gotoxy(72,11);
	printf("/");
	
	gotoxy(70,13);
	printf("\\|");
	
	gotoxy(70,14);
	printf("^|/");
	
	gotoxy(70,15);
	printf("\\|");
	
	gotoxy(71,16);
	printf("|/");
	
	gotoxy(71,17);
	printf("|");
	
	gotoxy(67,17);
	color(10);
	printf("\\\\\\\\");
	
	gotoxy(73,17);
	printf("//");
	
	gotoxy(67,18);
	color(2);
	printf("^^^^^^^^");
}
void closer()
{
	exit(0);
}
int color(int c)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
	return 0;
}

第三部分是最关键的 CreateFlag和Gameplay函数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python可以使用Pygame库来制作俄罗斯方块游戏。Pygame是一个专门用于游戏开发的Python库,提供了丰富的功能和工具来创建游戏界面、处理用户输入和实现游戏逻辑。 要制作俄罗斯方块游戏,你可以按照以下步骤进行: 1. 安装Pygame库:在开始之前,你需要先安装Pygame库。可以使用pip命令来安装,命令如下: ``` pip install pygame ``` 2. 创建游戏窗口:使用Pygame创建一个窗口来显示游戏界面。你可以设置窗口的大小、标题等属性。 3. 绘制游戏界面:使用Pygame提供的绘图函数来绘制游戏界面,包括方块、背景等元素。 4. 处理用户输入:使用Pygame提供的事件处理函数来监听用户的键盘输入,根据用户的操作来移动和旋转方块。 5. 实现游戏逻辑:编写代码来实现俄罗斯方块游戏逻辑,包括方块的生成、移动、碰撞检测等。 6. 更新游戏状态:在每一帧中更新游戏状态,包括方块的位置、消除行等。 7. 渲染游戏界面:在每一帧中重新绘制游戏界面,显示更新后的游戏状态。 8. 循环运行游戏:使用一个主循环来不断更新游戏状态和渲染游戏界面,以实现游戏的连续运行。 这只是一个简单的概述,实际上制作一个完整的俄罗斯方块游戏还需要考虑更多的细节和功能。你可以在网上搜索相关的教程和示例代码来更详细地学习和了解如何使用Pygame制作俄罗斯方块游戏

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值