Buscando un código de juego pequeño escrito en lenguaje C
#include lt;graphics.hgt;
#include lt;conio.hgt;
#include lt;time.hgt;
/////////////////////////////////////////////////
// Definir constantes, enumeraciones, estructuras, variables globales
///////////////////////// / //////////////////////
#define WIDTH 10 // Ancho del área de juego
#define HEIGHT 22 // Altura de la zona de juego
#define TAMAÑO 20 // Píxeles reales por unidad de zona de juego
// Definir tipo de operación
enum CMD
{
CMD_ROTATE, // Rotar el bloque
CMD_LEFT, CMD_RIGHT, CMD_DOWN, // Mover el bloque hacia la izquierda, derecha y abajo
CMD_SINK, / / Hundir el bloque Abajo
CMD_QUIT //Salir del juego
};
//Definir el método para dibujar bloques
enum DIBUJAR
{
MOSTRAR, //Mostrar el bloque
OCULTAR, //Ocultar el bloque
FIX //Reparar el bloque
};
// Definir siete tipos de Tetris
struct BLOCK
{
WORD dir[ 4]; // Cuatro de los bloques Estado de rotación
COLORREF color; // Color de los bloques
} g_Blocks[7] = { {0x0F00, 0x4444, 0x0F00, 0x4444, RED }, // I
{0x0660, 0x0660, 0x0660, 0x0660, AZUL}, // puerto
{0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA}, // L
{0x2260, 0x0E20, 0x0644, 0x0470, AMARILLO}, // L inverso
{0x0C60, 0x2640, 0x0C60, 0x2640, CIAN}, // Z
{0x0360, 0x4620, 0x0360, 0x4620 , VERDE}, // Anti-Z
{0x4E00, 0x4C40, 0x0E40, 0x4640, MARRÓN}} // T
// Defina la información del bloque actual y del siguiente bloque
struct BLOCKINFO
{
byte id // ID de bloque
char; x, y; // Bloquear en el área del juego Coordenadas
byte dir: 2; // Dirección
} g_CurBlock, g_NextBlock
// Definir juego área
BYTE g_World[ ANCHO][ALTO] =
{0};
/////////////////////////////////////// // //////
// Declaración de función
//////////////////////// //// ////////////////////
void Init() // Inicializa el juego
void Salir (); // Salir del juego
void NewGame(); // Iniciar un nuevo juego
void GameOver() // Finalizar el juego
CMD GetCmd(); // Obtener comando de control
void DispatchCmd(CMD _cmd); // Enviar comando de control
void NewBlock() // Generar nuevo bloque
bool CheckBlock(BLOCKINFO _block); // Comprobar si el bloque especificado se puede eliminar
void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW // Dibujar el bloque
); void OnRotate(); // Gira el bloque
void OnLeft(); // Mueve el bloque hacia la izquierda
void OnRight() // Mueve el bloque hacia la derecha
void OnDown(); // Mueve el bloque hacia abajo
void OnSink(); // bloque que se hunde
///////////// ////////////// ////////////////////
// Definición de función
////////////// /////////////////////////////////// // Función principal
void main()
{
Init()
CMD
while(true)
{
c = GetCmd();
DispatchCmd(c);
// Al presionar salir; , se mostrará un cuadro de diálogo para preguntar al usuario si desea salir
if (c == CMD_QUIT)
{
HWND wnd = GetHWnd();
if (MessageBox(wnd, _T("¿Quieres salir del juego? "), _T("Recordatorio"), MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
Salir();
}
}
}
//Inicializa el juego
void Init()
{
initgraph(640, 480); p >
srand((unsigned)time(NULL));
// Mostrar instrucciones de operación
setfont(14, 0, _T("宋体"));
p>tú
ttextxy(20, 330, _T("Instrucciones de operación"));
outtextxy(20, 350, _T("Arriba: Rotación")); , _T("Izquierda: Desplazar a la izquierda"));
outtextxy(20, 390, _T("Derecha: Desplazar a la derecha"));
outtextxy(20, 410, _T ("Abajo: bajar"));
outtextxy(20, 430, _T("Espacio: hundirse hasta el fondo"));
outtextxy(20, 450, _T (" ESC: Salir "));
// Establece el origen de las coordenadas
setorigin(220, 20);
// Dibuja el límite; del área de juego
rectángulo(-1, -1, ANCHO * TAMAÑO, ALTO * TAMAÑO);
rectángulo((ANCHO 1) * TAMAÑO - 1, -1, ( ANCHO 5) * TAMAÑO, 4 * TAMAÑO);
// Iniciar un nuevo juego
NewGame();
}
//Salir del juego
void Quit()
{
closegraph();
exit(0);
}
// Iniciar un nuevo juego
void NewGame()
{
// Limpiar el área de juego
setfillstyle(NEGRO);
bar(0, 0, ANCHO * TAMAÑO - 1, ALTO * TAMAÑO - 1); * HEIGHT);
// Genera el siguiente bloque
g_NextBlock.id = rand()
g_NextBlock.dir = rand() 4; /p>
g_NextBlock.x = ANCHO 1 ;
g_NextBlock.y = ALTURA - 1;
// Obtener nuevo bloque
NewBlock() ;
}
//Fin del juego
void GameOver()
{
HWND wnd = GetHWnd ();
if ( MessageBox(wnd, _T("Juego terminado.
\n¿Quieres jugar de nuevo? "), _T("Juego terminado"), MB_YESNO | MB_ICONQUESTION) == IDYES)
NewGame();
else
Salir();
}
// Obtener comando de control
DWORD m_oldtime;
CMD GetCmd()
{ p>
// Obtener el valor de control
while(true)
{
// Si se agota el tiempo de espera, descarta automáticamente un fotograma
DWORD newtime = GetTickCount();
if (newtime - m_oldtime gt; = 500)
{
m_oldtime = newtime;
return CMD_DOWN;
}
// Si hay un botón, devuelve la función correspondiente al botón
if (kbhit())
{
switch(getch())
{
caso 'w':
caso ' W': devuelve CMD_ROTATE;
caso 'a':
caso 'A': devuelve CMD_LEFT
caso 'd':
caso 'D': devuelve CMD_RIGHT;
caso 's':
caso 'S': devuelve CMD_DOWN
caso 27: devuelve CMD_QUIT;
caso ' ': devolver CMD_SINK
caso 0:
caso 0xE0:
switch(getch())
{
caso 72: devolver CMD_ROTATE;
caso 75: devolver CMD_LEFT
caso 77: devolver CMD_RIGHT; > caso 80: return CMD_DOWN ;
}
}
}
// Retraso (reduce el uso de CPU)
Dormir (20);
}
}
// Comando de control de despacho
void DispatchCmd(CMD _cmd)
{
switch(_cmd)
{
caso CMD_ROTATE: OnRotate();
caso; CMD_LEFT: OnLeft( );
caso CMD_RIGHT: OnRight();
caso CMD_DOWN: OnDown();
p>
caso CMD_SINK: OnSink(); romper
caso CMD_QUIT: romper
}
}
/ / Generar nuevo bloque
void NewBlock()
{
g_CurBlock.id = g_NextBlock.id, g_NextBlock.id = rand() 7;
p>g_CurBlock.dir = g_NextBlock.dir, g_NextBlock.dir = rand() 4;
g_CurBlock.x = (ANCHO - 4) / 2; . y = HEIGHT 2;
// Mueve el nuevo bloque hacia abajo hasta que se muestre parcialmente
WORD c = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];
while((c amp; 0xF) == 0)
{
g_CurBlock.y--;
c gt; ; = 4 ;
}
//Dibuja un nuevo bloque
DrawBlock(g_CurBlock);
//Dibuja el siguiente bloque
setfillstyle(NEGRO);
bar((ANCHO 1) * TAMAÑO, 0, (ANCHO 5) * TAMAÑO - 1, 4 * TAMAÑO - 1
);DrawBlock (g_NextBlock);
// Establece un temporizador para determinar el paradero automático
m_oldtime = GetTickCount();
}
// Dibujar bloque
void DrawBlock(BLOCKINFO _block, DRAW _draw)
{
WORD b = g_Blocks[_block.id].dir[_block .dir ];
int x, y
int color = NEGRO
cambiar(_draw)
{
caso MOSTRAR: color = g_Blocks[_block.id].color; romper;
caso OCULTAR: color = NEGRO
caso FIJAR: color = g_Blocks[ _block.id].color / 3; romper;
}
setfillstyle(color);
for(int i=0; ilt; 16; i )
{
if (b amp; 0x8000)
{
x = _block.x i 4; p> y = _block.y - i / 4;
if (y lt; ALTURA)
{
if (_draw != HIDE) p>
bar3d(x * TAMAÑO 2, (ALTO - y - 1) * TAMAÑO 2, (x 1) * TAMAÑO - 4, (ALTO - y) * TAMAÑO - 4, 3, verdadero);
else
bar(x * TAMAÑO, (ALTO - y - 1) * TAMAÑO, (x 1) * TAMAÑO - 1, (ALTO - y) * TAMAÑO - 1);
}
}
b lt; = 1;
}
}
// Comprobar si el bloque especificado se puede eliminar
bool CheckBlock(BLOCKINFO _block)
{
WORD b = g_Blocks[_block.id].dir[ _block. dir];
int x, y;
for(int i=0; ilt; 16; i)
{
if (b amp; 0x8000)
{
x = _block.x i 4
y = _block.y - i / 4; p>
if ((x lt; 0) || (x gt; = ANCHO) || (y lt; 0))
devuelve falso;
if ( (y lt; ALTURA) amp; (g_World[x][y]))
devuelve falso
}
b lt; = 1 ;
}
return true;
}
// Girar el bloque
void OnRotate ()
{
// Obtenga el desplazamiento x que se puede rotar
int dx;
BLOCKINFO tmp = g_CurBlock;
tmp.dir; if (CheckBlock(tmp)) { dx = 0; ir a rotar }
tmp.x = g_CurBlock.x - 1; { dx = -1; ir a rotar; }
tmp.x = g_CurBlock.x 1; if (CheckBlock(tmp)) { dx = 1; .x = g_CurBlock.x - 2; if (CheckBlock(tmp)) { dx = -2; ir a rotar }
tmp.x = g_CurBlock.x 2; dx = 2 ; ir a rotar; }
regresar;
rotar:
// Rotar
DrawBlock(g_CurBlock, HIDE);
g_CurBlock.dir;
g_CurBlock.x = dx;
DrawBlock(g_CurBlock);
}
// Mueve el bloque hacia la izquierda
void OnLeft ()
{
BLOCKINFO tmp = g_CurBlock;
tmp.x--;
{
DrawBlock(g_CurBlock, HIDE);
g_CurBlock.x--
DrawBlock(g_CurBlock
}
}
// Mover el bloque hacia la derecha
void OnRight()
{
BLOCKINFO tmp = g_CurBlock;
tmp.x;
if (CheckBlock(tmp))
{
DrawBlock(g_CurBlock , OCULTAR );
g_CurBlock.x
DrawBlock(g_CurBlock
}
}
// Mover bloque hacia abajo
void OnDown()
{
BLOCKINFO tmp = g_CurBlock;
tmp.y--;
if (CheckBlock(tmp))
{
DrawBlock(g_CurBlock, HIDE);
g_CurBlock.y--; p>
DrawBlock(g_CurBlock);
}
else
OnSink() // Cuando no se puede mover hacia abajo, realiza el "hundimiento". operación de bloqueo
}
//Bloque de hundimiento
void OnSink()
{
int i , x, y;
// Mueve continuamente el bloque hacia abajo
DrawBlock(g_CurBlock, HIDE
BLOCKINFO tmp = g_CurBlock
<); p> tmp. y--;mientras (CheckBlock(tmp))
{
g_CurBlock.y--;
tmp.y- -;
}
DrawBlock(g_CurBlock, FIX);
// Bloqueo fijo en el área de juego
PALABRA b = g_Blocks[ g_CurBlock.id].dir[g_CurBlock.dir];
for(i = 0; i lt; 16; i )
{
if (b amp; 0x8000)
{
if (g_CurBlock.y - i/4 gt; = ALTURA)
{ // Si el la posición fija del bloque excede la altura, finaliza el juego
GameOver();
return;<
/p>
}
else
g_World[g_CurBlock.x i 4][g_CurBlock.y - i / 4] = 1
}<; /p>
b lt; = 1;
}
// Comprueba si es necesario eliminar la fila y márcala
int fila[ 4] = {0};
bool bRow = false;
for(y = g_CurBlock.y; y gt; = max(g_CurBlock.y - 3, 0) ; y --)
{
i = 0
for(x = 0; x lt; ANCHO; x )
if (g_World[x][y] == 1)
i ;
if (i == ANCHO)
{
bRow = verdadero;
fila[g_CurBlock.y - y] = 1;
setfillstyle(WHITE, DIAGCROSS2_FILL);
bar(0, ( ALTO - y - 1) * TAMAÑO TAMAÑO / 2 - 2, ANCHO * TAMAÑO - 1, (ALTO - y - 1) * TAMAÑO TAMAÑO / 2 2); }
if (bRow)
{
// Retraso 200 milisegundos
Sleep(200);
// Borra la línea recién marcada
IMAGEN img
for(i = 0; i lt; 4; i )
{
if (fila[i])
{
for(y = g_CurBlock.y - i 1; y lt; ALTURA; y)
for(x = 0; x lt; ANCHO; x)
{
g_Mundo[x][y - 1] = g_Mundo[x][y];
g_World[x][y] = 0;
}
getimage(amp; img, 0, 0, ANCHO * TAMAÑO, (ALTO - (g_CurBlock.y - i 1)) * TAMAÑO);
putimage(0, TAMAÑO, amp; img);
}
}
}
// Generar nuevo bloque
NewBlock();
}