好吧我承认旋转费了些劲
/*
time:2011/2/6
by:cloud
about: 上下左右:wsad控制,p退出游戏,l暂停
*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <bios.h>
#include <time.h>
#include <graphics.h>
/*定义键盘*/
#define TAB 'w'
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
#define PAUSE 'l'
#define EXIT 'p'
/*定义SHAPE的类型*/
#define SHAPE0 0
#define SHAPE1 1
#define SHAPE2 2
#define SHAPE3 3
#define SHAPE4 4
#define SHAPE5 5
#define SHAPE6 6
/*定义图框*/
#define MaxX 14
#define MaxY 26
#define XOFFSET 200
#define YOFFSET 60
#define NODELENGTH 15
#define NODEWIDTH 15
#define PATH "d://tc201e//bgi"
/*结构体*/
struct Point
{
int x,y; /*记录坐标*/
};
struct Shape
{
struct Point Node[4];
int ShapeMode;
int Rotation; /*旋转状态:0,1,2,3*/
int Color;
};
/*全局变量*/
struct Shape Shape;
struct Shape OldShape;
struct Shape NextShape;
int World[MaxX][MaxY]; /*方块的有无........................纵坐标1为顶端*/
int WorldTop;
int Score;
/*图形绘制*/
int DrawPoint(int x,int y,int color) /*x,y为world里的坐标,color为填充颜色*/
{
setfillstyle(SOLID_FILL, color); /*设置作图颜色*/
bar(XOFFSET+x*NODEWIDTH+1,YOFFSET+y*NODELENGTH+1,XOFFSET+(x+1)*NODEWIDTH-1,YOFFSET+(y+1)*NODELENGTH-1);
return 0;
}
int WipePoint(int x,int y) /*x,y为world里的坐标*/
{
setfillstyle(EMPTY_FILL, 0);
bar(XOFFSET+x*NODEWIDTH+1,YOFFSET+y*NODELENGTH+1,XOFFSET+(x+1)*NODEWIDTH-1,YOFFSET+(y+1)*NODELENGTH-1);
return 0;
}
int DrawLine(int x) /*x为要处理的行*/
{
int i;
for(i=0;i<MaxX;i++)
{
if(World[i][x])
DrawPoint(i,x,DARKGRAY);
else
WipePoint(i,x);
}
return 0;
}
int DrawWorld()
{
int i;
for(i=WorldTop;i<MaxY;i++)
DrawLine(i);
return 0;
}
int DrawShape(struct Shape *a)
{
int i;
for(i=0;i<4;i++)
DrawPoint((*a).Node[i].x,(*a).Node[i].y,(*a).Color);
return 0;
}
int WipeShape(struct Shape *a)
{
int i;
for(i=0;i<4;i++)
WipePoint((*a).Node[i].x,(*a).Node[i].y);
return 0;
}
int DrawScreen() /*框架及作者信息之类的*/
{
char *str;
setcolor(BLUE); /*设置作图颜色*/
rectangle(XOFFSET-1,YOFFSET-1,XOFFSET+MaxX*NODEWIDTH+1,YOFFSET+MaxY*NODELENGTH+1);
setcolor(BLACK);
line(XOFFSET-1,YOFFSET-1,XOFFSET+MaxX*NODEWIDTH+1,YOFFSET-1);
setcolor(YELLOW);
outtextxy(0,30,"Time:");
outtextxy(0,40,"2010/2/6");
outtextxy(0,80,"By:");
outtextxy(0,90,"Cloud");
outtextxy(0,130,"About:");
outtextxy(0,140,"Press W:TAB");
outtextxy(0,160,"Press S:DOWN");
outtextxy(0,180,"Press A:LEFT");
outtextxy(0,200,"Press D:RIGHT");
outtextxy(0,220,"Press L:PAUSE");
outtextxy(0,240,"Press P:EXIT");
outtextxy(0,310,"My E-mail:");
outtextxy(0,320,"hu_jun@yeah.net");
outtextxy(0,410,"Last:");
outtextxy(0,420,"Happy Play~ :)");
outtextxy(XOFFSET+MaxX*NODEWIDTH+40,YOFFSET+7*NODELENGTH,"Next One:");
sprintf(str, "YOUR SCORE: %d.",Score);
outtextxy(XOFFSET+MaxX*NODEWIDTH+20,YOFFSET+15*NODELENGTH,str);
return 0;
}
/*图形相关,World处理函数*/
int SwapLine(int x,int y) /*x,y为交换的两行数据*/
{
int i,temp;
for(i=0;i<MaxX;i++)
{
temp=World[i][x];
World[i][x]=World[i][y];
World[i][y]=temp;
}
return 0;
}
int DestoryLine(int x) /*要毁坏的行*/
{
int i;
for(i=x;i>WorldTop;i--) /*将x行移到顶端*/
SwapLine(i,i-1);
for(i=0;i<MaxX;i++) /*将其清0*/
World[i][WorldTop]=0;
DrawLine(WorldTop); /*清除顶端*/
WorldTop++;
return 0;
}
int AddLine() /*隔一段时间增加一行*/
{
int i;
WorldTop--;
srand((unsigned int)time(NULL));
for(i=0;i<MaxX;i++)
World[i][WorldTop]=rand()%2;
for(i=WorldTop;i<MaxY-1;i++) /*将x行移到顶端*/
SwapLine(i,i+1);
}
/*分数相关及判断结束*/
int GetScore() /*计算分数*/
{
int i,j,h=0,k=0; /*i,j循环k计算得分行数*/
for(i=GetShapeTop(&Shape);i<=GetShapeBottom(&Shape);i++)
{
for(j=0;j<MaxX;j++)
h+=World[j][i];
k=k+(h==MaxX);
if(h==MaxX)
DestoryLine(i);
h=0;
}
if(k>3)
k++;
Score=Score+k*10;
return 0;
}
int GetShapeTop(struct Shape *a) /*返回Shape的最高纵坐标*/
{
int i,shapetop=(*a).Node[0].y;
for(i=1;i<4;i++)
if(shapetop>(*a).Node[i].y)
shapetop=(*a).Node[i].y;
return shapetop;
}
int GetShapeBottom(struct Shape *a) /*返回Shape的最高纵坐标*/
{
int i,shapebottom=(*a).Node[0].y;
for(i=1;i<4;i++)
if(shapebottom<(*a).Node[i].y)
shapebottom=(*a).Node[i].y;
return shapebottom;
}
int CalcWorldTop() /**/
{
if(WorldTop>GetShapeTop(&Shape))
WorldTop=GetShapeTop(&Shape);
return 0;
}
int Dead() /*判断死亡与否*/
{
if(WorldTop<=0)
GameOver(); /*结束游戏*/
return 0;
}
/*shape 的初始化及行动*/
int SetShape(int x,int y,struct Shape *a) /*放置shape的Node[0]*/
{
(*a).Node[0].x=x;
(*a).Node[0].y=y;
InitShape(a);
return 0;
}
int InitShape(struct Shape *a)
{
int i;
for(i=1;i<4;i++)
CopyPoint(&((*a).Node[i]),&((*a).Node[0]));
if((*a).ShapeMode<=4)
{
(*a).Node[1].x++;
(*a).Node[2].x++;(*a).Node[2].y++;
(*a).Node[3].y++;
}
else
{
(*a).Node[1].x++;(*a).Node[1].y--;
(*a).Node[2].x+=2;
(*a).Node[3].y++;(*a).Node[3].x++;
}
return 0;
}
int CreatShape(struct Shape *a)
{
srand((unsigned int)time(NULL));
(*a).ShapeMode=rand()%7;
(*a).Rotation=rand()%4;
SetShapeColor(a);
return 0;
}
int ChangeShape(struct Shape *a)
{
switch((*a).ShapeMode)
{
case SHAPE0:
break;
case SHAPE1:
(*a).Node[(*a).Rotation%2].x+=2*( (*a).Node[(((*a).Rotation)%2+1)%4].x == (*a).Node[(((*a).Rotation)%2+2)%4].x );
(*a).Node[(*a).Rotation%2].y+=2*( (*a).Node[(((*a).Rotation)%2+1)%4].y == (*a).Node[(((*a).Rotation)%2+2)%4].y );
break;
case SHAPE2:
(*a).Node[(*a).Rotation%2].x-=2*( (*a).Node[(((*a).Rotation)%2+3)%4].y == (*a).Node[(((*a).Rotation)%2+4)%4].y );
(*a).Node[(*a).Rotation%2].y+=2*( (*a).Node[(((*a).Rotation)%2+3)%4].x == (*a).Node[(((*a).Rotation)%2+4)%4].x );
break;
case SHAPE3:
if( (*a).Node[((*a).Rotation)%4].y == (*a).Node[((*a).Rotation+1)%4].y )
{
(*a).Node[((*a).Rotation+1)%4].y=(*a).Node[((*a).Rotation+2)%4].y;
(*a).Node[((*a).Rotation+1)%4].x=2*(*a).Node[((*a).Rotation+2)%4].x - (*a).Node[((*a).Rotation+3)%4].x;
}
else
{
(*a).Node[((*a).Rotation+1)%4].x=(*a).Node[((*a).Rotation+2)%4].x;
(*a).Node[((*a).Rotation+1)%4].y=2*(*a).Node[((*a).Rotation+2)%4].y - (*a).Node[((*a).Rotation+3)%4].y;
}
break;
case SHAPE4:
if( (*a).Node[((*a).Rotation)%4].y == (*a).Node[((*a).Rotation+1)%4].y )
{
(*a).Node[((*a).Rotation)%4].x=(*a).Node[((*a).Rotation+2)%4].x;
(*a).Node[((*a).Rotation)%4].y=2*(*a).Node[((*a).Rotation+1)%4].y - (*a).Node[((*a).Rotation+2)%4].y;
}
else
{
(*a).Node[((*a).Rotation)%4].y=(*a).Node[((*a).Rotation+2)%4].y;
(*a).Node[((*a).Rotation)%4].x=2*(*a).Node[((*a).Rotation+1)%4].x - (*a).Node[((*a).Rotation+2)%4].x;
}
break;
case SHAPE5:
(*a).Node[((*a).Rotation)%4].x= ( (*a).Node[((*a).Rotation+2)%4].x+(*a).Node[((*a).Rotation)%4].x ) /2;
(*a).Node[((*a).Rotation)%4].y= ( (*a).Node[((*a).Rotation+2)%4].y+(*a).Node[((*a).Rotation)%4].y ) /2;
break;
case SHAPE6:
(*a).Node[((*a).Rotation)%4].x= ( (*a).Node[((*a).Rotation+2)%4].x+(*a).Node[((*a).Rotation)%4].x ) /2;
(*a).Node[((*a).Rotation)%4].y= ( (*a).Node[((*a).Rotation+2)%4].y+(*a).Node[((*a).Rotation)%4].y ) /2;
if((*a).Node[((*a).Rotation+2)%4].x == (*a).Node[((*a).Rotation)%4].x)
{
(*a).Node[((*a).Rotation+2)%4].x = (*a).Node[((*a).Rotation)%4].x+2;
(*a).Node[((*a).Rotation+2)%4].y = (*a).Node[((*a).Rotation)%4].y;
}
else
{
(*a).Node[((*a).Rotation+2)%4].x = (*a).Node[((*a).Rotation)%4].x;
(*a).Node[((*a).Rotation+2)%4].y = (*a).Node[((*a).Rotation)%4].y+2;
}
break;
default:
break;
}
}
int SetShapeColor(struct Shape *a)
{
switch((*a).ShapeMode)
{
case SHAPE0:
(*a).Color=YELLOW;break;
case SHAPE1:
(*a).Color=GREEN;break;
case SHAPE2:
(*a).Color=BROWN;break;
case SHAPE3:
(*a).Color=BLUE;break;
case SHAPE4:
(*a).Color=LIGHTCYAN;break;
case SHAPE5:
(*a).Color=CYAN;break;
case SHAPE6:
(*a).Color=RED;break;
default:
break;
}
return 0;
}
/*Point的行为*/
int CopyPoint(struct Point *a,struct Point *b)
{
(*a).x=(*b).x;
(*a).y=(*b).y;
return 0;
}
int EqualPoint(struct Point *a,struct Point *b)
{
if((*a).x==(*b).x && (*a).y==(*b).y)
return 1;
return 0;
}
int SwapPoint(struct Point *a,struct Point *b)
{
struct Point temp;
CopyPoint(&temp,a);
CopyPoint(a,b);
CopyPoint(b,&temp);
return 0;
}
int TwoPointThere(struct Point *a)
{
return World[(*a).x][(*a).y];
}
/*Shape的行为*/
int CopyShape(struct Shape *a,struct Shape *b)
{
int i;
(*a).ShapeMode=(*b).ShapeMode;
(*a).Rotation=(*b).Rotation;
(*a).Color=(*b).Color;
for(i=0;i<4;i++)
CopyPoint(&((*a).Node[i]),&((*b).Node[i]));
return 0;
}
int EqualShape(struct Shape *a,struct Shape *b)
{
int i;
if((*a).ShapeMode!=(*b).ShapeMode)
return 0;
for(i=0;i<4;i++)
if(!EqualPoint(&((*a).Node[i]),&((*b).Node[i])))
return 0;
return 1;
}
/*辅助过程*/
int MoveOut() /*返回1表示有重叠*/
{
int i;
for(i=0;i<4;i++)
{
if(Shape.Node[i].x<0 || Shape.Node[i].x>=MaxX || Shape.Node[i].y>=MaxY)
return 1;
else if(TwoPointThere(&(Shape.Node[i])) && (Shape.Node[i].y>0))
return 1;
else
;
}
return 0;
}
int ShapeToWorld()
{
int i;
for(i=0;i<4;i++)
World[Shape.Node[i].x][Shape.Node[i].y]=1;
return 0;
}
int PrintScore()
{
char *str;
setviewport(XOFFSET+MaxX*NODEWIDTH+20,YOFFSET+15*NODELENGTH,XOFFSET+MaxX*NODEWIDTH+160,YOFFSET+16*NODELENGTH,1);
clearviewport();
setviewport(0,0,639,479,1);
sprintf(str, "YOUR SCORE: %d.",Score);
outtextxy(XOFFSET+MaxX*NODEWIDTH+20,YOFFSET+15*NODELENGTH,str);
return 0;
}
int Difficulty() /*返回难度*/
{
if(Score<500)
return 10;
if(Score<1000)
return 8;
if(Score<1500)
return 6;
else
return 4;
}
int Rotate()
{
WipeShape(&Shape);
CopyShape(&Shape,&OldShape);
Shape.Rotation=(Shape.Rotation+1) %4;
ChangeShape(&Shape);
if(MoveOut())
{
Shape.Rotation=(Shape.Rotation+3) % 4;
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
DrawShape(&Shape);
return 0;
}
OldShape.Rotation=(OldShape.Rotation+1) %4;
DrawShape(&Shape);
return 0;
}
int NextShapeCome()
{
WipeShape(&NextShape);
CopyShape(&OldShape,&NextShape);
SetShape(5,-1,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
CreatShape(&NextShape);
SetShape(MaxX+5,9,&NextShape);
ChangeShape(&NextShape);
DrawShape(&NextShape);
return 0;
}
int MoveDown()
{
WipeShape(&Shape);
SetShape(OldShape.Node[0].x,OldShape.Node[0].y+1,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
if(MoveOut())
{
SetShape(OldShape.Node[0].x,OldShape.Node[0].y-1,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
ShapeToWorld();
CalcWorldTop();
GetScore();
PrintScore();
DrawWorld();
Dead();
NextShapeCome();
}
DrawShape(&Shape);
return 0;
}
int MoveLeft()
{
WipeShape(&Shape);
SetShape(OldShape.Node[0].x-1,OldShape.Node[0].y,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
if(MoveOut())
{
SetShape(OldShape.Node[0].x+1,OldShape.Node[0].y,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
}
DrawShape(&Shape);
return 0;
}
int MoveRight()
{
WipeShape(&Shape);
SetShape(OldShape.Node[0].x+1,OldShape.Node[0].y,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
if(MoveOut())
{
SetShape(OldShape.Node[0].x-1,OldShape.Node[0].y,&OldShape);
CopyShape(&Shape,&OldShape);
ChangeShape(&Shape);
}
DrawShape(&Shape);
return 0;
}
/*主进程*/
int Init()
{
int gdriver=DETECT,gmode;
int i,j; /*i,j为循环变量*/
for(i=0;i<MaxX;i++)
for(j=0;j<MaxY;j++)
World[i][j]=0;
Score=0;
WorldTop=MaxY-1;
registerbgidriver(EGAVGA_driver);
initgraph(&gdriver,&gmode,PATH);
CreatShape(&NextShape);
NextShapeCome();
DrawScreen();
}
int PlayGame()
{
char key;
int StartTime1,StartTime2,EndTime;
EndTime=clock();
StartTime1=clock();
StartTime2=clock();
while(1)
{
while(bioskey(1))
{
key=bioskey(0);
switch(key)
{
case TAB:
Rotate(); break;
case DOWN:
MoveDown(); break;
case LEFT:
MoveLeft(); break;
case RIGHT:
MoveRight(); break;
case PAUSE:
getch();break;
case EXIT:
exit(0);
default:
break;
}
}
if(EndTime-StartTime1>Difficulty())
{
MoveDown();
StartTime1=clock();
}
if(EndTime-StartTime2>1000)
{
AddLine();
StartTime2=clock();
}
EndTime=clock();
}
}
int GameOver()
{
getch();
closegraph();
exit(0);
}
int main()
{
Init();
PlayGame();
return 0;
}