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

📄 pushboxs.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 3 页
字号:
{
	U8	Xspace;
	U8      Yspace;
	U8      unitLen,unitWid;
	
	U32 pGC;
	pGC = GetGC();

	PositiontoXY(&unitx,&unity);
	unitLen=GetunitLength();
	unitWid=GetunitWidth();
	//unitLen=GetunitLength();
	//unitWid=GetunitWidth();
	Xspace=unitLen/2;
	Yspace=unitWid/2-1;
	DrawRec(pGC, GPC_RED,unitx,unity,unitx+unitLen-1,unity+Yspace,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
	DrawRec(pGC, GPC_RED,unitx,unity+Yspace+1,unitx+Xspace,unity+unitWid-1,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
	DrawRec(pGC, GPC_RED,unitx+Xspace+1,unity+Yspace+1,unitx+unitLen-1,unity+unitWid-1,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
//	SetPatternFill(6,WHITE,0,2);
	DrawRec(pGC, GPC_RED,unitx+1,unity+1,unitx+unitLen-1-1,unity+Yspace-1,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
	DrawRec(pGC, GPC_RED,unitx,unity+Yspace+1+1,unitx+Xspace-1,unity+unitWid-1-1,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
	DrawRec(pGC, GPC_RED,unitx+Xspace+1+1,unity+Yspace+1+1,unitx+unitLen-1,unity+unitWid-1-1,GPC_SOLID_LINE,GPC_REPLACE_STYLE);
//	SetPatternFill(0,WHITE,0,2);
	//DrawLine(WHITE,unitx,unity+Yspace+1+1,unitx,unity+unitWid-1-1,0,GPC_REPLACE_STYLE);
	//DrawLine(WHITE,unitx+unitLen-1,unity+Yspace+1+1,unitx+unitLen-1,unity+unitWid-1-1,0,GPC_REPLACE_STYLE);
	
}
void DrawBox(U8 unitX,U8 unitY,U8 style)
{
	U8	bleftX,bleftY;
	U8      brightX,brightY;
	U8      unitLen,unitWid;
	
	U32 pGC;
	pGC = GetGC();

	PositiontoXY(&unitX,&unitY);
	unitLen=GetunitLength();
	unitWid=GetunitWidth();

	//unitLen=GetunitLength();
	//unitWid=GetunitWidth();
	DrawRec(pGC, GPC_RED,unitX,unitY,unitX+unitLen-1,unitY+unitWid-1,GPC_SOLID_LINE,style);	
	DrawRec(pGC, GPC_RED,unitX+2,unitY+2,unitX+unitLen-1-2,unitY+unitWid-1-2,GPC_SOLID_LINE,style);	
	bleftX=unitX+2;
	bleftY=unitY+2;
	brightX=unitX+unitLen-1-2;
	brightY=unitY+unitWid-1-2;
	//draw the bar from lefttop to right bottom
	DrawLine(pGC, GPC_RED,bleftX+1,bleftY+2,brightX-2,brightY-1,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,bleftX+2,bleftY+1,brightX-1,brightY-2,GPC_SOLID_LINE,style);
	//DrawLine(GPC_RED,bleftX,bleftY+2,bleftX+2,bleftY,0,style);
	//DrawLine(GPC_RED,brightX-2,brightY,bleftX+2,bleftY,0,style);
	//draw the bar from righttop to left bottom
	DrawLine(pGC, GPC_RED,bleftX+1,brightY-2,brightX-2,bleftY+1,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,bleftX+2,brightY-1,brightX-1,bleftY+2,GPC_SOLID_LINE,style);
	//DrawLine(GPC_RED,bleftX,brightY-2,bleftX+2,brightY,0,style);
	//DrawLine(GPC_RED,brightX-2,bleftY,brightX,bleftY+2,0,style);
}
U8   Getsmallone(U8 fir,U8 sec)
{
	return ((fir>sec) ? sec : fir);
}	
void DrawBoxposition(U8 unitX,U8 unitY,U8 style)	
{
	U8	centerX;
	U8 	centerY;
	U8      radius;
	U8      cleftX,cleftY;
	U8      ctopX,ctopY;
	U8      unitLen,unitWid;

	U32 pGC;
	pGC = GetGC();

	PositiontoXY(&unitX,&unitY);
	unitLen=GetunitLength();
	unitWid=GetunitWidth();
	//unitLen=GetunitLength();
	//unitWid=GetunitWidth();
	centerX=unitX+unitLen/2;
	centerY=unitY+unitWid/2;
	radius=(U8)(Getsmallone(unitWid,unitLen)/2*3.0/4);
//	SetPatternFill(1,WHITE,0,0);
	DrawCircle(pGC, GPC_DARKGREY,centerX,centerY,radius,style);
//	SetPatternFill(0,WHITE,0,0);
	cleftX=centerX-radius+1;
	cleftY=centerY;
	ctopX=centerX;
	ctopY=centerY-radius+1;
	DrawLine(pGC, GPC_WHITE,ctopX,ctopY+1,cleftX+1,cleftY,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_WHITE,ctopX,ctopY+2,cleftX+2,cleftY,GPC_SOLID_LINE,style);
	
}

void DrawMan(U8 unitX,U8 unitY,U8 style)
{
	U8	centerX;
	U8	neckX,neckY;
	U8      space;
	U8      legspace;
	U8      bodyLen,bodyWid;
	U8      legX,legY;
	U8      armLen;
	U8      unitLen,unitWid;
	
	U32 pGC;
	pGC = GetGC();

	PositiontoXY(&unitX,&unitY);
	unitLen=GetunitLength();
	unitWid=GetunitWidth();
	bodyLen=unitLen/2-1;
	bodyWid=unitWid/2-1;
	space=unitWid/6;
	legspace=(U8)(unitWid*2.0/3/3);
	centerX=unitX+unitLen/2;
	//draw the man's head
	DrawCircle(pGC, GPC_RED,centerX,unitY+unitWid/6,unitWid/6,style);
	neckX=centerX;
	neckY=unitY+unitWid/6+unitWid/6;
//   DrawDot(pGC, GPC_WHITE,neckX,neckY,style);      //modified by renshh 2002/06/26 12:00
	// draw the man's arms
	armLen=(U8)(unitLen/2*2.0/3);
	DrawLine(pGC, GPC_RED,neckX-2,neckY+1,neckX-armLen,neckY+space-1,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,neckX+2,neckY+1,neckX+armLen,neckY+space-1,GPC_SOLID_LINE,style);
	//draw the man's body
	DrawLine(pGC, GPC_RED,neckX-1,neckY+1,neckX-bodyLen/2,neckY+bodyWid,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,neckX+1,neckY+1,neckX+bodyLen/2,neckY+bodyWid,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,neckX-bodyLen/2+1,neckY+bodyWid,neckX+bodyLen/2-1,neckY+bodyWid,GPC_SOLID_LINE,style);
	legX=centerX;
	legY=neckY+bodyWid;
	//draw the man's legs
	DrawLine(pGC, GPC_RED,legX-bodyLen/6,legY+1,legX-bodyLen/6,legY+legspace,GPC_SOLID_LINE,style);
	DrawLine(pGC, GPC_RED,legX+bodyLen/6,legY+1,legX+bodyLen/6,legY+legspace,GPC_SOLID_LINE,style);
//	SetPatternFill(1,WHITE,0,0);
	DrawRec(pGC, GPC_RED,legX-bodyLen/6-bodyLen/3,legY+legspace-legspace/2,legX-bodyLen/6-1,legY+legspace,GPC_SOLID_LINE,style);
	DrawRec(pGC, GPC_RED,legX+bodyLen/6+1,legY+legspace-legspace/2,legX+bodyLen/6+bodyLen/3,legY+legspace,GPC_SOLID_LINE,style);
//	SetPatternFill(0,WHITE,0,0);
}
void DrawSpace(U8 unitX,U8 unitY)	
{
		
}	
	
U8 Drawroom(const P_U8 ptr)
{
	//variable for the size and position of the unit to be displayed
//	U8		unitLen;
//	U8		unitWid;
	U8      	unitX;
	U8      	unitY;
	register U8     i,j;

	//To draw the room,the first thing is to calculate the length and width of every
	//unit.Then given the x,y coordinate,the unit may be displayed in proportion to 
	//the Wid ang Len in the right place. 

	for(i=0;i<gameroom[gStageNow].Ynumber;i++)
	    for(j=0;j<gameroom[gStageNow].Xnumber;j++)
	        {
	        	unitX=j;//Xbase+j*unitLen;
	                unitY=i;//Ybase+i*unitWid;
	                switch(*(ptr+i*gameroom[gStageNow].Xnumber+j))
	                      {
	                      	case 0:
	                      	       DrawBrick(unitX,unitY);
	                      	       break;
							case 1:
	                      	       DrawBox(unitX,unitY,GPC_EXOR_STYLE);
	                      	       break;
	                      	case 2:
	                      	       DrawBoxposition(unitX,unitY,GPC_REPLACE_STYLE);
	                      	       break;
	                      	case 3:
	                      	       DrawMan(unitX,unitY,GPC_EXOR_STYLE);
	                      	       break;
	                      	case 4:
				       DrawSpace(unitX,unitY);		                      	
	                      	       break;
	                      	default:
	                      	       break;
	                      }	              
		}

		return 0;
}
//this function is used to change the attributes when moving event occurs	
void ChangePosition(U8 oldPosX,U8 oldPosY,U8 oldAttr,U8 newPosX ,U8 newPosY,U8 newAttr)
{
	*(mapPtr+oldPosY*gameroom[gStageNow].Xnumber+oldPosX)=oldAttr;
	*(mapPtr+newPosY*gameroom[gStageNow].Xnumber+newPosX)=newAttr;
}
// this function is used to judge if there is a way ahead
int judge(char x,char y)
{
  U8 i=0;
  U8 up,down,left,right;
  
  up=*(animationPtr+(y+1)*gameroom[gStageNow].Xnumber+x);
  down=*(animationPtr+(y-1)*gameroom[gStageNow].Xnumber+x);
  left=*(animationPtr+y*gameroom[gStageNow].Xnumber+x+1);
  right=*(animationPtr+y*gameroom[gStageNow].Xnumber+x-1);
  if ((up==SPACE)||(up==BOXPOSITION))  i++;
  if ((down==SPACE)||(down==BOXPOSITION))  i++;
  if ((right==SPACE)||(right==BOXPOSITION))  i++;
  if ((left==SPACE)||(left==BOXPOSITION))  i++;
  return (i==0) ? 0 : 1 ;
}
// this function is used to judge if there is a way ,even back
int judgeagain(char x,char y)
{
  U8 i=0;
  U8 up,down,left,right;
  
  up=*(animationPtr+(y+1)*gameroom[gStageNow].Xnumber+x);
  down=*(animationPtr+(y-1)*gameroom[gStageNow].Xnumber+x);
  left=*(animationPtr+y*gameroom[gStageNow].Xnumber+x+1);
  right=*(animationPtr+y*gameroom[gStageNow].Xnumber+x-1);
    
  if ((up==SPACE)||(up==BOXPOSITION)||(up==MOVEPATH))  		  i++;
  if ((down==SPACE)||(down==BOXPOSITION)||(down==MOVEPATH))	  i++;
  if ((right==SPACE)||(right==BOXPOSITION)||(right==MOVEPATH))    i++;
  if ((left==SPACE)||(left==BOXPOSITION)||(left==MOVEPATH))       i++;
  return (i==0) ? 0 : 1 ;
}

//this function is designed to go in the right direction
/* This func has the same name with LM's , we rename it from go to Wang_go. LM 12/15/1999*/
void Wang_go(U8 *xscr,U8 *yscr,U8 xdest,U8 ydest)
{
	int  DirectionY=0;
 	int  DirectionX=0;
 	U8 up,down,left,right;
 	

    
	DirectionY=(*yscr>ydest) ? -1 : 1 ;
	DirectionX=(*xscr>xdest) ? -1 : 1 ;
	
	up=*(animationPtr+(*yscr+DirectionY)*gameroom[gStageNow].Xnumber+*xscr);
  	down=*(animationPtr+(*yscr-DirectionY)*gameroom[gStageNow].Xnumber+*xscr);
  	right=*(animationPtr+*yscr*gameroom[gStageNow].Xnumber+*xscr+DirectionX);
  	left=*(animationPtr+*yscr*gameroom[gStageNow].Xnumber+*xscr-DirectionX);
  	
	if  ((up==SPACE)||(up==BOXPOSITION))
	    {
	    	*yscr=*yscr+DirectionY;
	    	*(animationPtr+(*yscr)*gameroom[gStageNow].Xnumber+*xscr)=MOVEPATH;
	    	//arr[*xscr][*yscr]=MOVEPATH;
	    	where++;
	    	pos[where].x=*xscr;
	    	pos[where].y=*yscr;
		return;
	    }
	if  ((right==SPACE)||(right==BOXPOSITION))
	    {
	    	*xscr=*xscr+DirectionX;
	    	*(animationPtr+(*yscr)*gameroom[gStageNow].Xnumber+*xscr)=MOVEPATH;
	    	//arr[*xscr][*yscr]=MOVEPATH;
	    	where++;
	    	pos[where].x=*xscr;
	    	pos[where].y=*yscr;
		return;
	    }
	if  ((down==SPACE)||(down==BOXPOSITION))
	    {
	    	*yscr=*yscr-DirectionY;
	    	*(animationPtr+(*yscr)*gameroom[gStageNow].Xnumber+*xscr)=MOVEPATH;
	    	//arr[*xscr][*yscr]=MOVEPATH;
	    	where++;
	    	pos[where].x=*xscr;
	    	pos[where].y=*yscr;
		return;
	    }

	if  ((left==SPACE)||(left==BOXPOSITION))
	    {
	    	*xscr=*xscr-DirectionX;
	    	*(animationPtr+(*yscr)*gameroom[gStageNow].Xnumber+*xscr)=MOVEPATH;
	    	where++;
	    	pos[where].x=*xscr;
	    	pos[where].y=*yscr;
		return;
	    }
}
// man move animation	
U8 ManmoveAnimation(U8 xscr, U8 yscr, U8 xdest, U8 ydest)
{
	U8 	i,j;
	U8	cannotmove=0;
	U8	Width;
	U8	Length;
	P_U8	aniptr,ptrmap;
	U8	val;
	
	if (!(animationPtr=Stageinit())) return 0;
	aniptr=animationPtr;
	ptrmap=mapPtr;
	
	Width=gameroom[gStageNow].Ynumber;
	Length=gameroom[gStageNow].Xnumber;
	
	for(i=0;i<Width;i++)
	    for(j=0;j<Length;j++)
	        *aniptr++=*ptrmap++; 
	        
	for (i=0;i<maxstep;i++)
    	    {
      	     pos[i].x=0;
     	     pos[i].y=0;
    	    }
  	//arr[xscr][yscr]=MOVEPATH;
  	*(animationPtr+yscr*gameroom[gStageNow].Xnumber+xscr)=MOVEPATH;
  	where=0;
  	pos[where].x=xscr;
  	pos[where].y=yscr;
  	while (!((xscr==xdest)&&(yscr==ydest)))
 	  {
		if (judge(xscr,yscr))//there is a way
		   {
	    		Wang_go(&xscr,&yscr,xdest,ydest);
		   }
		else//there is no way except to go back
           	   {
			*(animationPtr+pos[where].y*gameroom[gStageNow].Xnumber+pos[where].x)=CANNOTMOVE;
			//arr[pos[where].x][pos[where].y]=CANNOTMOVE;
           		where--;
           		xscr=pos[where].x;
           		yscr=pos[where].y;
			if (!judgeagain(xscr,yscr))//there is no way
           	   	{
           	    	cannotmove=1;
           	    	break;
           	   	}	
           	   }
   	  }
   	  if (!(cannotmove))
   		{
   		 	for (i=0;i<where;i++)
       		    	{
       		     		DrawMan(pos[i+1].x,pos[i+1].y,GPC_EXOR_STYLE);
       		     		DrawMan(pos[i].x,pos[i].y,GPC_EXOR_STYLE);
       		    	}
       		 	val=1;
       		 	
       		 }
       	 else  val=0;
         Lfree(animationPtr);  
         return val ;  
       		     
}	
//the function below is designed for undo use
//addone : add one step into the chain
void addone(U8 who,U8 oldx,U8 oldy,U8 newx,U8 newy)
{
   struct chain  *ptr;
   if (ptr=(struct chain *)Lmalloc(LEN)) 
      {
   	ptr->who=who;
   	ptr->oldx=oldx;
   	ptr->oldy=oldy;
   	ptr->newx=newx;
   	ptr->newy=newy;
      }
      else
        return;
   if (gamechain !=NULL) /*if it is not the first one*/
      {
       ptr->next=gamechain;
       gamechain=ptr;
      }
   else /*if it is the first one*/
      {
       gamechain=ptr;
       gamechain->next=NULL;
      }
}
//delete one step fron chain.when it is the box-moving 
//  step,deleteone function should called twice
int deleteone()
{
   struct chain  *ptr;
   ptr=gamechain; 
   if (gamechain)
      {
       gamechain=gamechain->next ;
       Lfree(ptr);
       return 1;
      } 
   else
      return 0;
}
// if the touched space is space,it can be falled in two categories
// One is that the man is in space, another is that the man is in boxposition
void SpaceTouch(P_U8 manX,P_U8 manY,U8 xPos,U8 yPos)
{
//	U8 manoldX,manoldY;
//	U8 mannewX,mannewY;
	
	switch(GetWho(*manX,*manY))
	      {
		case MAN://the man is on space
			//First, erase the man at the old place and draw it at the new place.
			//Second,modify the information in the map matrix.
			if (ManmoveAnimation(*manX,*manY,xPos,yPos))
			   {
			   	addone(MAN,*manX,*manY,xPos,yPos);
			   	ChangePosition(*manX,*manY,SPACE,xPos,yPos,MAN);
			   	*manX=xPos;
				*manY=yPos;	      				
			  	gcandelete=CANDELETE;
			   }	
		
			break;
		case MANINPOSITION://the man is on boxposition
			//first erase the man at the old place and at the same time redraw the
			//boxposition at the same place.Then draw a man at the new place.
			//the follwing is the same as above.
			if (ManmoveAnimation(*manX,*manY,xPos,yPos) )
			   {
			   	addone(MAN,*manX,*manY,xPos,yPos);
			   	ChangePosition(*manX,*manY,BOXPOSITION,xPos,yPos,MAN);
			   	*manX=xPos;
				*manY=yPos;
				gcandelete=CANDELETE;
		          }
			
			break;
		default:
			break;
	      } 
	//change the man's position

}
void BoxPositionTouch(P_U8 manX,P_U8 manY,U8 xPos,U8 yPos)
{
//	U8 manoldX,manoldY;
//	U8 mannewX,mannewY;
	
	switch(GetWho(*manX,*manY))
	      {
		case MAN://the man is on space
			//First, erase the man at the old place and draw it at the new place.
			//Second,modify the information in the map matrix.
			//ClearRec(WHITE,manoldX,manoldY,GetunitLength(),GetunitWidth(),GPC_REPLACE_STYLE);
			if (ManmoveAnimation(*manX,*manY,xPos,yPos))
			   {
		   		addone(MAN,*manX,*manY,xPos,yPos);//add one into the undo chain
		   		ChangePosition(*manX,*manY,SPACE,xPos,yPos,MANINPOSITION);
		   		*manX=xPos;
				*manY=yPos;
			   	gcandelete=CANDELETE;
			   }	
			
			break;
		case MANINPOSITION://the man is on boxposition
			//first erase the man at the old place and at the same time redraw the
			//boxposition at the same place.Then draw a man at the new place.
			//the follwing is the same as above.
			//ClearRec(WHITE,manoldX,manoldY,GetunitLength(),GetunitWidth(),GPC_REPLACE_STYLE);
			if (ManmoveAnimation(*manX,*manY,xPos,yPos))
			   {
			  	addone(MAN,*manX,*manY,xPos,yPos);
			  	ChangePosition(*manX,*manY,BOXPOSITION,xPos,yPos,MANINPOSITION);
			  	*manX=xPos;
				*manY=yPos;
				gcandelete=CANDELETE;
			   }
			break;
		default:
			break;
	      } 
	//change the man's position
	      	
}
//Judge whether the box can be moved or not and in which direction
U8  JudgeBoxMove(U8 manX,U8 manY,U8 boxX,U8 boxY)
{
	if (manX==boxX) 
	   {
	   	if ((manY-boxY)==1)
	   	   {
	   	   	if ((GetWho(boxX,(U8)(boxY-1))==SPACE)||(GetWho(boxX,(U8)(boxY-1))==BOXPOSITION))
	   	   	return MANDOWNBOXUP;
	   	   }
	   
		if ((manY-boxY)==-1)
	   	   {
	   		if ((GetWho(boxX,(U8)(boxY+1))==SPACE)||(GetWho(boxX,(U8)(boxY+1))==BOXPOSITION))   	
	   	   	return MANUPBOXDOWN;
	           }
	   }
	
	if (manY==boxY)
	   {
	   	if ((manX-boxX)==1)
	   	   {	
	   	   	if ((GetWho((U8)(boxX-1),boxY)==SPACE)||(GetWho((U8)(boxX-1),boxY)==BOXPOSITION))   	
	   	   	return MANRIGHTBOXLEFT;
	   	   }
	   	if ((manX-boxX)==-1)
	   	   {
	   	   	if ((GetWho((U8)(boxX+1),boxY)==SPACE)||(GetWho((U8)(boxX+1),boxY)==BOXPOSITION))   	
	   	   	return MANLEFTBOXRIGHT;
	   	   }
	   }     
	return NOMOVE;   	   
}	
void BoxTouch(P_U8 manX,P_U8 manY,U8 xPos,U8 yPos,U8 attr)
{
	U8	boxnewX,boxnewY;
	U8	manoldAttr,mannewAttr,boxoldAttr,boxnewAttr;
	
	if (GetWho(*manX,*manY)==MAN)
	   manoldAttr=SPACE;
	else 
	   if (GetWho(*manX,*manY)==MANINPOSITION)
	      manoldAttr=BOXPOSITION;
	      
        if (attr==BOX) 	

⌨️ 快捷键说明

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