螢幕截圖:
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include"SDL/SDL.h"
#define height 400
#define width 400
#define speed 20
struct brick
{
SDL_Rect a;
int appearance;//the number of box
struct brick *next;
};
typedef struct brick BRICK;
//方塊初始座標
int O[8]={80,100,100,80,20,20,0,0};
int I[8]={80,80,80,80,60,40,20,0};
int J[8]={100,80,80,80,0,40,20,0};
int L[8]={100,80,80,80,40,40,20,0};
int S[8]={100,100,80,80,40,20,20,0};
int Z[8]={80,80,100,100,40,20,20,0};
int T[8]={100,80,80,80,20,40,20,0};
void Create(int R[],int c);
void Button(void);
void Overlapping(void);
void Boundary(void);
void Correct(void);
void GameOver(void);
void JudgePositionAfterCorrect(void);
void Rotation(void);
void MoveToDown(BRICK *deliver);
void LeftAndRight(void);
void Drop(void);
void Cancellation(void);
BRICK *first,*current,*previous,*temp;
bool running=true,move=false,correcting=false,DN=false,LR=false,dropping=false;
int dx=20,dy=speed,number=0,acount=0,cycle=0,i,j,p,Cx,Cy,J1,I1,J2,I2,ee=0;
int main()
{
printf("=======================\n");
printf("= SPACE - high down =\n");
printf("= UP - rotate =\n");
printf("= DOWN - slow down =\n");
printf("= LEFT - left =\n");
printf("= RIGHT - right =\n");
printf("=======================\n");
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen;
screen=SDL_SetVideoMode(width,height,32,SDL_SWSURFACE);
SDL_WM_SetCaption("---Tetris---",NULL);
Uint32 bg=SDL_MapRGB(screen->format,0xff,0xff,0xff);//the color of background
Uint32 bg1=SDL_MapRGB(screen->format,240,240,240);//the color of bacdground-1
Uint32 color[7];//the color of box
color[0]=SDL_MapRGB(screen->format,240,0,0);
color[1]=SDL_MapRGB(screen->format,0,240,0);
color[2]=SDL_MapRGB(screen->format,0,0,240);
color[3]=SDL_MapRGB(screen->format,240,240,0);
color[4]=SDL_MapRGB(screen->format,0,240,240);
color[5]=SDL_MapRGB(screen->format,240,0,240);
color[6]=SDL_MapRGB(screen->format,200,200,0);
SDL_Rect ss[20][10];//the box of background
for(i=0;i<20;i++)//set the value to the box of background
{
for(j=0;j<10;j++)
{
ss[i][j].x=j*20;
ss[i][j].y=i*20;
ss[i][j].w=20;
ss[i][j].h=20;
}
}
srand(time(NULL));
//printf("Now Loading.......\n");
//SDL_Delay(1000);
while(running)
{
if(cycle>0)Cancellation();
if(move==false)//increase the box
{
p=rand()%7;
if(p==0)Create(O,p);
if(p==1)Create(I,p);
if(p==2)Create(J,p);
if(p==3)Create(L,p);
if(p==4)Create(S,p);
if(p==5)Create(Z,p);
if(p==6)Create(T,p);
GameOver();
acount=0;
}
//Button();
if(cycle%8==0)MoveToDown(first);
if(LR)LeftAndRight();//if left or right was pushed
if(DN)MoveToDown(first);//if down was pushed
if(dropping)Drop();//if space was pushed
//check the condition
Overlapping();
Boundary();
if(correcting)Correct();
//------------------------
Overlapping();
Boundary();
//increase the box
if(correcting)Correct();
//------------------------
JudgePositionAfterCorrect();
//Display all box
SDL_FillRect(screen,&screen->clip_rect,bg1);//background
for(i=0;i<20;i++)//background
for(j=0;j<10;j++)
if(i%2==0&&j%2==1)
SDL_FillRect(screen,&ss[i][j],bg);
else if(i%2==1&&j%2==0)
SDL_FillRect(screen,&ss[i][j],bg);
else
SDL_FillRect(screen,&ss[i][j],bg1);
current=first;//the box
while(current!=NULL)
{
if(current->appearance==0)SDL_FillRect(screen,¤t->a,color[0]);
if(current->appearance==1)SDL_FillRect(screen,¤t->a,color[1]);
if(current->appearance==2)SDL_FillRect(screen,¤t->a,color[2]);
if(current->appearance==3)SDL_FillRect(screen,¤t->a,color[3]);
if(current->appearance==4)SDL_FillRect(screen,¤t->a,color[4]);
if(current->appearance==5)SDL_FillRect(screen,¤t->a,color[5]);
if(current->appearance==6)SDL_FillRect(screen,¤t->a,color[6]);
current=current->next;
}
SDL_Flip(screen);
SDL_Delay(120);//Delay
cycle++;
Button();
}
SDL_Quit();
}
void Button(void)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE://Quit
running=false;
break;
case SDLK_SPACE://Drop
dropping=true;
break;
case SDLK_UP://rotation
Rotation();
break;
case SDLK_DOWN:
dy=20;
DN=true;
break;
case SDLK_LEFT:
dx=-20;
LR=true;
break;
case SDLK_RIGHT:
dx=20;
LR=true;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym)
{
case SDLK_DOWN:
dy=speed;
DN=false;
break;
case SDLK_LEFT:
LR=false;
break;
case SDLK_RIGHT:
LR=false;
break;
}
break;
}
}
}
void Create(int R[],int c)
{
//printf("-create-%d\n",number);
int i;
for(i=0;i<4;i++)
{
current=(BRICK *)malloc(sizeof(BRICK));
current->a.x=R[i];
current->a.y=R[i+4];
current->a.w=20;
current->a.h=20;
current->appearance=c;
if(number==0&&i==0)
{
first=current;
current->next=NULL;
//previous=current;
}
else
{
current->next=first;
first=current;
}
}
number++;
move=true;
}
void Overlapping(void)
{
//printf("-Overlapping\n");
current=first;
i=0;
while(i<4)
{
temp=first;
for(j=0;j<4;j++)temp=temp->next;
while(temp!=NULL)
{
if(current->a.y==temp->a.y)
{
if(current->a.x==temp->a.x)correcting=true;
}
temp=temp->next;
}
current=current->next;
i++;
}
}
void Boundary(void)
{
//printf("--BottomAndBoundary\n");
current=first;
i=0;
while(i<4)
{
if(current->a.x<0)correcting=true;
if(current->a.x>200-current->a.w)correcting=true;
current=current->next;
i++;
}
}
void Correct(void)
{
//printf("Correct\n");
current=first;
for(j=0;j<4;j++)
{
current->a.x=current->a.x-dx;
current=current->next;
}
correcting=false;
}
void GameOver(void)
{
//Game over
current=first;
i=0;
while(i<4)
{
temp=first;
for(j=0;j<4;j++)temp=temp->next;
while(temp!=NULL)
{
if(current->a.x==temp->a.x)
{
if(current->a.y==temp->a.y)running=false;
}
temp=temp->next;
}
current=current->next;
i++;
}
if(running==false)printf("Game Over!!\n");
}
void JudgePositionAfterCorrect(void)
{
current=first;
i=0;
while(i<4)
{
temp=first;
for(j=0;j<4;j++)temp=temp->next;
while(temp!=NULL)
{
if(current->a.x==temp->a.x)
{
if(current->a.y==temp->a.y-20)move=false;
}
temp=temp->next;
}
if(current->a.y>=400-current->a.h)
{
current->a.y=400-current->a.h;
move=false;
}
current=current->next;
i++;
}
}
void Rotation(void)
{
current=first;
J1=current->a.x;
I1=current->a.y;
switch(p)//find the center(Cx,Cy) of box
{
case 1:
if(acount==0)
{
Cx=((J1+20)+J1)/2;
Cy=((I1+80)+I1)/2;
}
if(acount==1)
{
Cx=((J1-60)+(J1+20))/2;
Cy=((I1+20)+I1)/2;
}
if(acount==2)
{
Cx=((J1+20)+J1)/2;
Cy=((I1-60)+(I1+20))/2;
}
if(acount==3)
{
Cx=((J1+80)+J1)/2;
Cy=((I1+20)+I1)/2;
}
break;
case 2:
case 3:
case 4:
case 6:
if(acount==0)
{
Cx=((J1+40)+J1)/2;
Cy=((I1+60)+I1)/2;
}
if(acount==1)
{
Cx=((J1-40)+(J1+20))/2;
Cy=((I1+40)+I1)/2;
}
if(acount==2)
{
Cx=J1;
Cy=((I1-40)+(I1+20))/2;
}
if(acount==3)
{
Cx=((J1+60)+J1)/2;
Cy=I1;
}
break;
case 5:
if(acount==0)
{
Cx=J1;
Cy=((I1+60)+I1)/2;
}
if(acount==1)
{
Cx=((J1-40)+(J1+20))/2;
Cy=I1;
}
if(acount==2)
{
Cx=((J1+40)+J1)/2;
Cy=((I1-40)+(I1+20))/2;
}
if(acount==3)
{
Cx=((J1+60)+J1)/2;
Cy=((I1+40)+I1)/2;
}
break;
}
i=0;//(J1,I1)->(J2,I2)
while(i<4)
{
if(p==0)break;
J1=current->a.x;
I1=current->a.y;
//J2=(J1-Cx)*cos(Theta)-(I1-Cy)*sin(Theta)+Cx
//I2=(J1-Cx)*sin(Theta)+(I1-Cy)*cos(Theta)+Cy
J2=(0-(I1-Cy)*1)+Cx;
I2=((J1-Cx)*1)+Cy;
//------------------------------
if(acount>=2)current->a.x=J2-30;
else
current->a.x=J2-10;
if(acount%2==0)current->a.y=I2-10;
else
current->a.y=I2+10;
current=current->next;
i++;
}
if(acount==3)acount=0;
else
acount++;
}
void MoveToDown(BRICK *deliver)
{
i=0;
while(i<4)
{
deliver->a.y=deliver->a.y+dy;
deliver=deliver->next;
i++;
}
}
void LeftAndRight(void)
{
current=first;
i=0;
while(i<4)
{
current->a.x=current->a.x+dx;
current=current->next;
i++;
}
}
void Drop(void)
{
while(1)
{
MoveToDown(first);
JudgePositionAfterCorrect();
if(move==false)break;
}
dropping=false;
}
void Cancellation(void)
{
i=0;
while(i<=380)
{
current=first;
for(j=0;j<4;j++)current=current->next;
while(current!=NULL)
{
if(current->a.y==i)ee++;
current=current->next;
}
if(ee==10)
{
current=first;
//for(j=0;j<4;j++)current=current->next;
while(current!=NULL)//delete the node
{
if(current->a.y!=i)
{
temp=current;
current=current->next;
}
else
{
temp->next=current->next;
previous=current;
current=current->next;
free(previous);
}
}
current=first;
//for(j=0;j<4;j++)current=current->next;
while(current!=NULL)
{
if(current->a.y<i)current->a.y=current >a.y+20;
current=current->next;
}
}
ee=0;
i=i+20;
}
}