好吧我承认旋转费了些劲
/*time:2011/2/6by:cloudabout: 上下左右: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; }