📄 pushboxs.c
字号:
{
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 + -