Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

MIC_DUARTE

[Código] Jogo TETRIS - feito em C

Recommended Posts

/***************************************************************************/
/* TETRIS	***************************************************************/
/***************************************************************************/

/*
  compilado com Borland Turbo C 2.0
*/

#include "defs.h"

#define QX 15
#define QY 20
#define P 4
#define CHARAPAGADOR 219
#define DESLIGADOCOLOR 0
#define LIGADOCOLOR	2
#define EFEITOBREAKCOLOR 4
#define VIRADIREITA	0
#define VIRAESQUERDA   1
#define EFEITODELAY	200
int BarSizeX, BarSizeY;
int BarzinhoSizeX, BarzinhoSizeY;
struct linesettingstype LineInfo;

int Grade[QX][QY];
int Peca[P][P];
int PosX, PosY;
int Rotacionador = VIRADIREITA;

#define INTERRUPT_BIOS_CLOCK  0x1c
void interrupt far (*rotina_original)();
int TimerContador = 0;
int TimerDelay = 10;
int TimerEvent = 0;
int TimerPlay = 1;
int TimerContadorColor = 0;
int TimerDelayColor = 3;
int TimerEventColor = 0;

int ContaPeca = 0;
int Pontos = 0;
int Fase = 1;
int Record = 0;

/***************************************************************************/
void interrupt far Timer(void)
{
 if(TimerPlay)
 {
  if (++TimerContador >= TimerDelay)
  {
   TimerEvent = 1;  TimerContador = 0;
  }
 }
 if (++TimerContadorColor == TimerDelayColor)
 {
  TimerEventColor = 1;  TimerContadorColor = 0;
 }
}
/***************************************************************************/
void Pause(void)
{
 TimerPlay = 0;
}
/***************************************************************************/
void Go(void)
{
 TimerPlay = 1;
}
/***************************************************************************/
void MostraPontos(void)
{
 int i;
 char Msg[16];
 for(i = 0; i < 15; i++) Msg[i] = CHARAPAGADOR; Msg[15] = NULL;

 setcolor(DESLIGADOCOLOR);
 outtextxy((((MaxX-BarSizeX)/2)),
			((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
			Msg);

 outtextxy((((MaxX-BarSizeX)/2)+BarSizeX)-textwidth(Msg),
			((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
			Msg);
 outtextxy(MaxX-30-textwidth(Msg), MaxY-(textheight(Msg)*2), Msg);

 setcolor(4);
 itoa(Fase,Msg,10);
 outtextxy((((MaxX-BarSizeX)/2)),
			((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
			Msg);
 itoa(Pontos,Msg,10);
 outtextxy((((MaxX-BarSizeX)/2)+BarSizeX)-textwidth(Msg),
			((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
			Msg);
 itoa(Record,Msg,10);
 outtextxy(MaxX-30-textwidth(Msg), MaxY-(textheight(Msg)*2), Msg);

}
/***************************************************************************/
void Close(char *msg)
{
 disable();
 setvect(INTERRUPT_BIOS_CLOCK, rotina_original);
 enable();
 closegraph();
 printf(msg);
 SaveRecord();
 exit(0);
}
/***************************************************************************/
void CalculaXY(void)
{
 MaxX = getmaxx();
 MaxY = getmaxy();
 MaxColors = getmaxcolor() + 1;
 BarSizeX = MaxX/3;
 BarSizeX = BarSizeX - (BarSizeX%QX);
 BarSizeY = MaxY-(MaxY/4);
 BarSizeY = BarSizeY - (BarSizeY%QY);
 BarzinhoSizeX = (BarSizeX/QX);
 BarzinhoSizeY = (BarSizeY/QY);
 getlinesettings( &LineInfo );
}
/***************************************************************************/
void ZeraGrade(void)
{
 int x, y;
 for(x = 0; x < QX; x++)
  for(y = 0; y < QY; y++)
   Grade[x][y] = 0;
}
/***************************************************************************/
void SorteiaPeca(void)
{
 int x, y;
 int sorteio;
 randomize();
 sorteio = rand()%(NUMERO_DE_PECAS);
 for(x = 0; x < P; x++)
  for(y = 0; y < P; y++)
   Peca[x][y] = XPeca[sorteio][x][y]; 
}
/***************************************************************************/
void DesenhaGrade(void)
{
 int x, y;
 for(x = 0; x < QX; x++)
  for(y = 0; y < QY; y++)
  {
   if(Grade[x][y])  { Quadrado(x,y); }
   else			 QuadradoOff(x,y);   
  }
}
/***************************************************************************/
void DesenhaPeca(int x, int y)
{
 int ix, iy;
 for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) Quadrado(x+ix,y+iy);
}
/***************************************************************************/
void LimpaPeca(int x, int y)
{
 int ix, iy;
 for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) QuadradoOff(x+ix,y+iy);
}
/***************************************************************************/
int Move(int Mov)
{
 if((Mov == DIREITA) && ValidaMov(Mov))
 {
  LimpaPeca(PosX,PosY);
  PosX++;
  DesenhaPeca(PosX,PosY); 
 }
 else if((Mov == ESQUERDA) && ValidaMov(Mov))
 {
  LimpaPeca(PosX,PosY);
  PosX--;
  DesenhaPeca(PosX,PosY);
 }
 else if((Mov == CIMA) && ValidaMov(Mov))
 {
  LimpaPeca(PosX, PosY);
  ViraPeca(Peca, Rotacionador);
  DesenhaPeca(PosX, PosY);
 }
 else if((Mov == BAIXO))
 {
  if(ValidaMov(Mov))
  {
   LimpaPeca(PosX,PosY);
   PosY++;
   DesenhaPeca(PosX,PosY);
  }
  else { NovaPeca(); return(0); }
 }
 else if(Mov == ESPACO)
 {
   while(Move(BAIXO))delay(EFEITODELAY);
 } 
 return(1);
}
/***************************************************************************/
int ValidaMov(int Mov)
{
 int ix, iy;
 int TempPeca[P][P];
 int TempPosX = PosX, TempPosY = PosY;
 
 memcpy(TempPeca, Peca, sizeof(int[P][P])); 
 if	 (Mov == DIREITA)  TempPosX++;
 else if(Mov == ESQUERDA) TempPosX--;
 else if(Mov == BAIXO)	TempPosY++;
 else if(Mov == CIMA)	 ViraPeca(TempPeca,Rotacionador);
 for(ix = 0; ix < P; ix++)
 {
  for(iy = 0; iy < P; iy++)
  {
   if(Grade[ix+TempPosX][iy+TempPosY]&&TempPeca[ix][iy]) return(0);
   if(TempPeca[ix][iy] && 
	 (((ix+TempPosX) > QX-1) ||
	 ((ix+TempPosX)  < 0)	||
	 ((iy+TempPosY)  > QY-1) ||
	 ((iy+TempPosY)  < 0)))
	return(0);
  }
 }
 return(1);
}
/***************************************************************************/
void MarcaGrade(void)
{
 int ix, iy;

 for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) Grade[ix+PosX][iy+PosY] = Peca[ix][iy];
 QuebraLinha();

}
/***************************************************************************/
void QuebraLinha(void)
{
 int x, y, yy;
 int LinhasBreak[QY];
 static int TempGrade[QX][QY];
 int ContaQuebra = 0;
 int Quebra = 1;
 int FaseSave;
 for(y = 0; y < QY; y++) LinhasBreak[y] = 1;

 for(y = 0; y < QY; y++)
  for(x = 0; x < QX; x++)
  {
   LinhasBreak[y] = LinhasBreak[y] && Grade[x][y];
   TempGrade[x][y] = Grade[x][y];
  }
 for(y = 0; y < QY; y++)
 {
  Quebra = (Quebra || LinhasBreak[y]);
  if(LinhasBreak[y]) ContaQuebra++;
 }
 if(Quebra)
 {
  for(yy = y = QY-1; y >= 1; y--)
  {
   if(!LinhasBreak[y])
   {
	for(x = 0; x < QX; x++)
	 Grade[x][yy] = TempGrade[x][y];
	yy--;
   }
   else
   {
	for(x = QX-1; x >= 0; x--)
	{
	 QuadradoColor(x,y,EFEITOBREAKCOLOR); delay(EFEITODELAY);
	}
	for(x = QX-1; x >= 0; x--)
	{
	 QuadradoOff(x,y); delay(EFEITODELAY);
	}
   }
  }
  DesenhaGrade();
  for(;ContaQuebra;ContaQuebra--) Pontos += (ContaQuebra*Fase);
  if(LinhasBreak[QY-1])
  {
   for(y = 0; y < QY; y++) for(x = 0; x < QX; x++)
	{
	 QuadradoColor(x,y,random(MaxColors-1)+1); delay(EFEITODELAY/3);
	}
   for(y = 0; y < QY; y++) for(x = 0; x < QX; x++)
	{
	 QuadradoOff(x,y); delay(EFEITODELAY/3);
	}
   FaseSave = Fase++;
   Pontos += Fase*50;
   TimerDelay = 10;
   ContaPeca = 0;
   ZeraGrade();
   Grade[(int)QX/2][QY-1] = 1;
   for(y = QY-1; (y >= 1)&&(FaseSave); y--,FaseSave--) for(x = QX-1; x >= 0; x--)
	 Grade[x][y-1] = random(2);
  }
  MostraPontos();
  DesenhaGrade();
 }
}
/***************************************************************************/
void ViraPeca(int PPeca[P][P], int Direcao)
{
 int x,y, vx, vy;
 int PecaVira[P][P];

 for(x = 0, vx = P-1; x < P; x++, vx--)
  for(y = P-1, vy = 0; y >= 0; y--, vy++)
   if(Direcao == VIRADIREITA)
	PecaVira[vy][x] = PPeca[x][y];
   else
	PecaVira[vx][vy] = PPeca[y][vx];
 for(x = P-1; x >= 0; x--)
  for(y = 0; y < P; y++)
   PPeca[y][x] = PecaVira[y][x];
}
/***************************************************************************/
void NovaPeca(void)
{
 ContaPeca++;
 if	 (ContaPeca > 200){ TimerDelay = 1; }
 else if(ContaPeca > 120){ TimerDelay = 3; }
 else if(ContaPeca > 70) { TimerDelay = 5; }
 else if(ContaPeca > 35) { TimerDelay = 7; }
 MarcaGrade();
 PosX = QX/2; PosY = 0;
 SorteiaPeca();
 DesenhaPeca(PosX,PosY);
 if(!ValidaMov(0)) Close("Game Over");
}
/***************************************************************************/
void Tabuleiro(void)
{
 int i;
 rectangle((MaxX-BarSizeX)/2,(MaxY-BarSizeY)/2,
		   ((MaxX-BarSizeX)/2)+BarSizeX,((MaxY-BarSizeY)/2)+BarSizeY);
 for(i = 0; i < QX; i++)
 {
  line(((MaxX-BarSizeX)/2)+(BarzinhoSizeX*i), (MaxY-BarSizeY)/2,
	  (((MaxX-BarSizeX)/2))+(BarzinhoSizeX*i),((MaxY-BarSizeY)/2) + BarSizeY);
 }
 for(i = 0; i < QY; i++)
 {
  line((MaxX-BarSizeX)/2,((MaxY-BarSizeY)/2)+(BarzinhoSizeY*i),
	  ((MaxX-BarSizeX)/2)+BarSizeX,((MaxY-BarSizeY)/2)+(BarzinhoSizeY*i));
 }
}
/***************************************************************************/
int Quadrado(int x, int y)
{
 int L = LineInfo.thickness+2;
 if((x>=QX)||(y>=QY)) Close("coordenadas invalidas ");
 setfillstyle(SOLID_FILL, LIGADOCOLOR); 
 bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
	  (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
	  ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
	  ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
int QuadradoOff(int x, int y)
{
 int L = LineInfo.thickness+1;
 if((x>=QX)||(y>=QY)) Close("coordenadas invalidas Off");
 setfillstyle(SOLID_FILL, DESLIGADOCOLOR); 
 bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
	  (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
	  ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
	  ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
int QuadradoColor(int x, int y, int Color)
{
 int L = LineInfo.thickness+1;
 if((x>=QX)||(y>=QY)) Close("coordenadas invalidas Off");
 setfillstyle(SOLID_FILL, Color); 
 bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
	  (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
	  ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
	  ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
void LoadRecord(void)
{
 int ind;
 ind = open("Record.dat", O_BINARY|O_RDONLY);
 if(ind != -1)
  read(ind, &Record, sizeof(int));
}
/***************************************************************************/
void SaveRecord(void)
{
 int ind;
 if(Record < Pontos) Record = Pontos;
 ind = open("Record.dat",O_BINARY|O_RDWR|O_CREAT,S_IWRITE|S_IREAD);
 if(ind != -1)
  write(ind, &Record, sizeof(int));
}

/***************************************************************************/
/**** main *****************************************************************/
/***************************************************************************/
void main(void)
{
 int i, tecla;
 int gdriver = DETECT, gmode, errorcode;

 initgraph(&gdriver, &gmode, "");

 rotina_original = getvect(INTERRUPT_BIOS_CLOCK);
 disable();
 setvect(INTERRUPT_BIOS_CLOCK, Timer);
 enable();

 LoadRecord();
/* setgraphmode(0); */
 CalculaXY();
 ZeraGrade();
 Grade[(int)QX/2][QY-1] = 1;
 rectangle(0,0,MaxX,MaxY); rectangle(4,4,MaxX-4,MaxY-4);
 Tabuleiro();
 DesenhaGrade();
 SorteiaPeca();
 DesenhaPeca(PosX = QX/2, PosY = 0);
 MostraPontos();

 Pause(); bioskey(0); Go();

 for(;;)
 {
  while(!bioskey(1))
  {
   if(TimerEventColor)
   {
	QuadradoColor(QX/2,QY-1,random(MaxColors-1)+1);
	TimerEventColor = 0;
   }
   if(TimerEvent)
   {
	Move(BAIXO);
	TimerEvent = 0;
   }
  }
  tecla = bioskey(0);
  Pause();
  if(tecla == ESC) break;
  else if(tecla == DIREITA)  Move(DIREITA);
  else if(tecla == ESQUERDA) Move(ESQUERDA);
  else if(tecla == BAIXO)	Move(BAIXO);
  else if(tecla == ESPACO)   Move(ESPACO);
  else if(tecla == CIMA)	 Move(CIMA);
  else if(tecla == ENTER)	Rotacionador = !Rotacionador;
  Go();
 }
 Close("Jogo finalizado corretamente");
}

 

________________________________________________________________________________

______

 

 

Biblioteca defs.h

/* defs.h */

#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<graphics.h>
#include<fcntl.h>
#include<io.h>
#include<sys/stat.h>
#include "pecas.def"

/* definicoes para bioskey */
#define ESC			 283
#define ESPACO		  14624
#define CIMA			18432
#define BAIXO		   20480
#define DIREITA		 19712
#define ESQUERDA		19200
#define ENTER		   7181


int	MaxX, MaxY;
int	MaxColors;

void interrupt far rotina(void);
void Pause(void);
void Go(void);
void MostraPontos(void);
void Close(char *msg);
void CalculaXY(void);
void ZeraGrade(void);
void SorteiaPeca(void);
void DesenhaGrade(void);
void DesenhaPeca(int x, int y);
void LimpaPeca(int x, int y);
int Move(int Mov);
int ValidaMov(int Mov);
void MarcaGrade(void);
void NovaPeca(void);
void Tabuleiro(void);
int Quadrado(int x, int y);
int QuadradoOff(int x, int y);
int QuadradoColor(int x, int y, int Color);
void ViraPeca(int Peca[][], int Direcao);
void QuebraLinha(void);
void LoadRecord(void);
void SaveRecord(void);
________________________________________________________________________________

_______

/*

Pecas do jogo

*/

#ifndef X_PECAS_DEF
#define X_PECAS_DEF

#define NUMERO_DE_PECAS 7
const int XPeca[NUMERO_DE_PECAS][4][4] =

							 {{{0,1,0,0},
							   {0,1,0,0},
							   {0,1,0,0},
							   {0,1,0,0}},

							  {{0,1,0,0},
							   {0,1,0,0},
							   {0,1,1,0},
							   {0,0,0,0}},

							  {{0,0,1,0},
							   {0,0,1,0},
							   {0,1,1,0},
							   {0,0,0,0}},

							  {{0,1,0,0},
							   {0,1,1,0},
							   {0,0,1,0},
							   {0,0,0,0}},

							  {{0,0,1,0},
							   {0,1,1,0},
							   {0,1,0,0},
							   {0,0,0,0}},

							  {{0,0,0,0},
							   {0,1,1,0},
							   {0,1,1,0},
							   {0,0,0,0}},

							  {{0,1,0,0},
							   {0,1,1,0},
							   {0,1,0,0},
							   {0,0,0,0}}};


#endif

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.