[Código] Jogo TETRIS - feito em C
/***************************************************************************/
/* 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}}};
#endifDiscussão (1)
Carregando comentários...