⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tetris.c

📁 在S3C2440上运行的“俄罗斯方块”源码 代码量小
💻 C
📖 第 1 页 / 共 2 页
字号:

//写一行

void	PutMapLine(U8 *pMap,int Line,U8 *pBuf)
{

	int	i,xx,yy;
	////
	
	i=0;
	yy=Line;
	for(xx=4;xx<(xGrids-4);xx++)
	{
			
			if(pBuf[i++])
			{
				SetMapDot(pMap,xx,yy);
			}
			else
			{
				ClrMapDot(pMap,xx,yy);
			}
	
	}

}

//检测一行是否已满

int	MapLineIsFull(U8 *pMap,int Line)
{

	int xx,yy;
	////
	yy=Line;
	///
	for(xx=4;xx<(xGrids-4-1);xx++)
	{
		if(!GetMapDot(pMap,xx,yy))	return 0;	//如果此行有任意一点为0,则表示此行没有满.
	
	}
	return 1;

}

/*============================================================================*/

int	CheckMap(U8 *pMap)
{
	int	i,j,xx,yy;
	int	states;
	////
	states=0;
st:
	for(yy=(yGrids-4-1);yy>0;yy--)	//从最后一行开始检测
	{
		if(MapLineIsFull(pMap,yy))
		{
			//如果此行已满.
			
			UserPoint+=(2*xGrids);
			
			states=1;
			for(i=yy;i>0;i--)
			{
				U8	buf[xGrids];
				////
				GetMapLine(pMap,i-1,buf);	//读上一行
				PutMapLine(pMap,i,buf);		//写到本行.	
				
			}
			
			goto st;					//重新开始检测
			
		}

		
	}
	
	return states;
}

/*============================================================================*/

//初始化背景

void	TetrisMapInit(U8 *pBuf)
{
	int xx,yy;
	////
	
	for(yy=0;yy<yGrids;yy++)
	{
		for(xx=0;xx<xGrids;xx++)
		{
			
			if(xx<4)
			{
				SetMapDot(pBuf,xx,yy);
				continue;
			}
			////
			if(xx>(xGrids-4-1))
			{
				SetMapDot(pBuf,xx,yy);
				continue;
			}
			////
			if(yy>(yGrids-4-1))
			{
				SetMapDot(pBuf,xx,yy);
				continue;
			}
			////
			
			ClrMapDot(pBuf,xx,yy);
			
			
			
		}
	
	}

}

/*============================================================================*/

/*============================================================================*/


/*============================================================================*/

void	ShowMap(U8 *pMap,int x,int y,int FrColor,int BkColor,int BorderColor)
{
	int xx,yy,dx,dy,x_offset,y_step;
	////
	
	dx			=((xGrids-(4*2))*7)+1;
	dy			=((yGrids-(1*4))*7)+1;
	x_offset	=((1*4)*7);
	y_step		=dy>>2;
	////
	
	if(BkColor!=RGB_TRANS)
	{
		GUI_FillRectangle(x,y,dx,dy,BkColor);
	}
	else
	{
		GUI_SetTrans(128);
		GUI_FillRectangle(x,y,dx,dy,RGB565(24,48,24));
		GUI_SetTrans(0);
	}
	////////
	
	for(yy=0;yy<(yGrids-4);yy++)
	{
		for(xx=4;xx<(xGrids-4);xx++)
		{
			
 			if(GetMapDot(pMap,xx,yy))
			{
				DrawBlockDot(x+(xx*7)-x_offset,y+(yy*7),FrColor);
			
			}
		
		}
	
	}
	////////
	
	GUI_Rectangle(x,y,dx,dy,BorderColor);
	////
	
}


/*============================================================================*/

/*============================================================================*/

void	GetNewBlock(struct BLOCK *block)
{
	
	block->Index	=(GUI_RandVal()%(16))*4;	//方块索引(随机生成)
	block->Rotate	=GUI_RandVal()%4;			//方块方向(随机生成)
				
}

/*============================================================================*/
/*============================================================================*/
/*============================================================================*/


int	Tetris(void *pdata)
{

	#define	GAME_START	USER_MSG+0
	#define	GAME_PAUSE	USER_MSG+1
	////
	
	HWND	wnd;
	int	i,key,game_states,xgrd,ygrd,xoffset;
	U8	TempMap[xGrids*yGrids];
	struct	GUI_BUTTON		button[]={
							
							{			0,0,0,0,	RGB565(00,00,00),RGB565(24,20,10),RGB565(05,10,05),		KEY_ID_ESC,			BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	"退出"},
							{			0,0,0,0,	RGB565(00,00,00),RGB565(10,50,10),RGB565(05,10,05),		KEY_ID_UP,			BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	"∧"},
							{			0,0,0,0,	RGB565(00,00,00),RGB565(10,20,24),RGB565(05,10,05),		'p',				BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	"暂停"},
						
							{			0,0,0,0,	RGB565(00,00,00),RGB565(10,50,10),RGB565(05,10,05),		KEY_ID_LEFT,		BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	"<"},
							{			0,0,0,0,	RGB565(00,00,00),RGB565(10,50,10),RGB565(05,10,05),		KEY_ID_DOWN,		BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	"∨"},
							{			0,0,0,0,	RGB565(00,00,00),RGB565(10,50,10),RGB565(05,10,05),		KEY_ID_RIGHT,		BN_3D,Up,	0,		FONT(ASCII8x16,HZ16x16),	">"},
						
								
																																								
							{			0,0,0,0,	0,0,0,	0,	0,	0,	0,	0,"--"},

					};
								
	////////

	struct	GUI_MATRIX_BN	m_button;

	////
	char	*s_Name[]={"Tetris","方块游戏","???"};
	
	/////////////	
	if(pdata)
	{
		struct	PGM_INFO *pInfo	=pdata;
		pInfo->Name			=(char*)GUI_Language(s_Name);
		pInfo->pIcon		=0;
		pInfo->pSmallIcon	=0;
		pInfo->ExtraInfo	="Version:1.0";
		return	1;
	
	}
	/////////////
	
	m_button.x	=(LCD_XSIZE-160);
	m_button.y	=LCD_YSIZE-80;
	m_button.dx	=160;
	m_button.dy	=72;
	
	m_button.xQty	=3;
	m_button.yQty	=2;
	m_button.xSpace	=8;
	m_button.ySpace	=8;
	m_button.ActObj	=-1;
	m_button.Enable	=1;
	m_button.pBN	=button;
	////
	
	GUI_MemdevEnable();
	TS_Free();
	Key_Free();
	/////
	
ReStart:

	TetrisMapInit(TetrisMap);
	
	UserPoint	=0;
	BlockCount	=0;
	
	key			=0;
	i			=0;
	xgrd		=xGrids>>1;					//x
	ygrd		=0;							//y
	xoffset		=0;							//水平偏移
	game_states	=GAME_START;
	
	GetNewBlock(&CurBlock);		//当前方块
	GetNewBlock(&NextBlock);	//下一个方块
	
	////
	
	while(1)
	{
		int a,block_states;
		
		////
st:	
		memcpy(TempMap,TetrisMap,(xGrids*yGrids));	
		
		block_states=CheckBlockInTray(TetrisMap,xgrd+xoffset,ygrd,CurBlock.Index+CurBlock.Rotate);
		////
		
		if(block_states)
		{
			//当前位置可以放下方块	
			
			GUI_Image(0,0,GUI_GetWallpaper());
			
			////
			
			GUI_PutMatrixButton(&m_button);
			DrawBlockInMap(TempMap,xgrd+xoffset,ygrd,CurBlock.Index+CurBlock.Rotate);
			ShowMap(TempMap,20,20,RGB565(00,00,00),RGB_TRANS,RGB565(00,00,00));	
			
			////////
			DrawBlock(LCD_XSIZE-96,40,RGB565(24,00,00),NextBlock.Index+NextBlock.Rotate);	//显示下一个方块	
			
			GUI_LabelPrintf(LCD_XSIZE-96,80,128,40,RGB565(31,50,00),RGB_TRANS,RGB_TRANS,LEFT,FONT(ASCII8x16,HZ16x16),"方块数:%d",BlockCount);
			GUI_LabelPrintf(LCD_XSIZE-96,120,128,40,RGB565(31,50,00),RGB_TRANS,RGB_TRANS,LEFT,FONT(ASCII8x16,HZ16x16),"得分数:%d",UserPoint);
			
			////////	
					
					
			GUI_DisplayUpdate(0,0,LCD_XSIZE,LCD_YSIZE);
			////
			if(!CheckBlockInTray(TetrisMap,xgrd+xoffset,ygrd+1,CurBlock.Index+CurBlock.Rotate))
			{
			
				//如果下一行不能放下该方块:
				
				if(CheckMap(TempMap))	//检测是否有满的行
				{
					Uart_Printf(0,"User Point=%d\n",UserPoint);
				}
				////////					
				
GoNextBlock:
				xgrd	=(GUI_RandVal()%(xGrids-(2*4)));
				if(xgrd<4)	xgrd=4;
					
				ygrd	=0;
				xoffset	=0;
				
			
				BlockCount++;
				
				CurBlock.Index	=NextBlock.Index;
				CurBlock.Rotate	=NextBlock.Rotate;
				
				GetNewBlock(&NextBlock);
				
				memcpy(TetrisMap,TempMap,(xGrids*yGrids));			
				////////
				Uart_Puts(0,"Next Block!\n");
				////
				goto st;

			}
			
		
		}
		else
		{
			//当前位置不能放下方块
				
			if(ygrd==0)
			{
			
				
				Delay_n15ms(500/15);
				////
				TS_Free();
				Key_Free();
				
				Tick1000msDecCnt=20;		//20秒钟后将自动重新运行
				while(Tick1000msDecCnt)
				{
					
					if(Tick250msCnt&0x01)
					{
						GUI_LabelPrintf(LCD_XSIZE-128,160,128,32,RGB565(00,00,00),RGB565(24,48,00),RGB565(10,20,10),CENTER,FONT(ASCII8x16,HZ16x16),"游戏结束 %d",Tick1000msDecCnt);
						GUI_DisplayUpdate(LCD_XSIZE-128,160,128,32);
					}
					////
					if(TS_Press_100ms())	break;
					if(GetKeyValue())		break;
				}
				/////
				
				Uart_Puts(0,"Tetris ReStart!\n");
				goto ReStart;
				////////
			}
			else
			{
				goto GoNextBlock;
			}
			

		}
		
		////////////////////////////////
				
		a=Tick500msCnt;
		while(1)
		{
			
			
			if(!pGUI_TS->IsDown())
			{
				//触摸屏没有按下.
				GUI_FreeButton(m_button.pBN);
				key=GetKeyValue();
				GUI_MatrixButtonEnable(&m_button);
				GUI_GetMatrixButton(&m_button);
				
			}
			else
			{
				//触摸屏按下.						
			
				key=GUI_GetMatrixButton(&m_button);
															
				if(TS_GetDownTime()>500)
				{
					GUI_MatrixButtonEnable(&m_button);
				}
				////
				
				if(key)
				{
					GUI_MatrixButtonDisable(&m_button);
				}
				
				////
				
			}
		
			GUI_DisplayUpdate(m_button.x,m_button.y,m_button.dx,m_button.dy);			
			///////////////////
			
			if(key)
			{
				int	i;
				////
				
				switch(key)
				{
				
					case	'a':
					case	KEY_ID_LEFT:
							
							if(CheckBlockInTray(TetrisMap,xgrd+xoffset-1,ygrd,CurBlock.Index+CurBlock.Rotate))
							{
								xoffset--;
								goto	st;
							}
							
							break;
							////////////////////
							
					case	'd':
					case	KEY_ID_RIGHT:
					
							if(CheckBlockInTray(TetrisMap,xgrd+xoffset+1,ygrd,CurBlock.Index+CurBlock.Rotate))
							{
								xoffset++;
								goto st;
							}
							
							break;
							/////////////////////
							
					case	's':
					case	KEY_ID_DOWN:
					
							ygrd+=1;
							goto	st;
							break;
							//////////////////////
					
					case	KEY_ID_ENTER:
					case	KEY_ID_UP:
					
							TS_Free();
							
							i=CurBlock.Rotate;
							
							CurBlock.Rotate++;
							if(CurBlock.Rotate>=4)
							{
								CurBlock.Rotate=0;
							}
							////

							if(CheckBlockInTray(TetrisMap,xgrd+xoffset,ygrd,CurBlock.Index+CurBlock.Rotate))
							{
								//如果旋转后可以放下该方块.
								goto st;
							}
							
							////不能放下该方块
							CurBlock.Rotate=i;
							break;
							///////////////////////
							
					case	KEY_ID_ESC:
							goto	ret;
							break;
							///////////////////////
							
					case	'p':
					
							if(game_states==GAME_START)
							{
								m_button.pBN[2].Text="开始";
								game_states=GAME_PAUSE;
								
							}
							else
							{
								m_button.pBN[2].Text="暂停";
								game_states=GAME_START;
							}
							
							TS_Free();
							goto st;
							break;
							///////////////////
							
							
				}
				
			}
			////
			
			if((a!=Tick500msCnt) && (game_states!=GAME_PAUSE))	
			{
				ygrd+=1;
				goto	st;
			}
			////
			
		}
		
		////////////////////////////////

		
		
	}
	////
	
ret:
	TS_Free();
	Key_Free();


}

/*============================================================================*/
/*============================================================================*/
/*============================================================================*/
/*============================================================================*/
/*============================================================================*/
/*============================================================================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -