Código fuente del juego móvil Tetris
# include & lttime.h & gt//Contiene funciones relacionadas con temporizadores como SetTimer() y KillTimer().
# include & ltstdlib.h & gt
#Definir celda 15 //La longitud lateral de la cuadrícula (pix)
#Definir W 20 // Ancho del área de juego (12 bloques, se utilizan 8 bloques para dibujar el "siguiente" bloque)
#Definition H 26 //Altura del área de juego (26 bloques)
# Definir ms_new blockm_user+1//El ID del mensaje genera un nuevo bloque.
#Define MS_DRAW WM_USER+2 //ID de mensaje, utilizado para dibujar un cuadro.
#Define MS_NEXTBLOCK WM_USER+3 //ID del mensaje, utilizado para mostrar la siguiente forma de Tetris.
// - Descripción de la función de la ventana.
Devolución de llamada LRESULT WndProc (HWND, UINT, WPARAM, LPARAM
// -
int WINAPI WinMain(h instancia h instancia,
);HINSTANCE hPrevInstance,
PSTR Shenzhen National Line,
int iCmdShow)
{
Caracteres estáticos AppName[]= " ladrillo de juguete ";//Nombre de clase de ventana
HWND hwnd
MSG MSG;//Estructura del mensaje
WNDCLASSEX wndclass//Clase de ventana
int es iScreenWide//Defina una variable entera para obtener el ancho de la ventana.
clase wnd. Tamaño CB = sizeof(clase wnd);
clase wnd = CS _ HREDRAW | CS _ VREDRAW; //CS_HREDRAW: Si ocurre movimiento o tamaño
// el ajuste cambia el ancho del área de trabajo.
//CS_VREDRAW: Si ocurre movimiento o tamaño
//El ajuste cambia la altura del área de trabajo.
wndclass.lpfnWndProc = WndProc//La función de procesamiento de ventanas es WndProc.
wnd class .cbclsextra = 0; //La clase de ventana no tiene extensión.
wnd class .cbwndextra = 0; //La instancia de ventana no tiene extensión.
wnd class .h instancia = h instancia; //Manejador de la instancia actual
wndclass.hIcon = LoadIcon (NULL, IDI_Application); p>wnd class. hcursor = load cursor(NULL, IDC _ ARROW); //Flecha cursor
wnd class. HBR background = (HBRUSH)GetStockObject(BLACK _ BRUSH);
wndclass.lpszMenuName = NULL // No hay menú en la ventana.
wnd class .lpsz class name = AppName; //El nombre de la clase es "ToyBrick"
wndclass.hIconSm = LoadIcon (NULL, IDI_APP); // -Registrar clase de ventana.
If (!register classex(& wnd class)//Si el registro falla, sonará una alarma y se devolverá FALSE.
{
mensaje bip (0);
Return FALSE
}
//Obtenga el valor x de la resolución de pantalla iScreenWide y coloque la ventana del programa en el centro de la pantalla.
es la pantalla ancha = getsystem metrics(SM _ CX pantalla completa);
hwnd =CreateWindow(
AppName, //Nombre de clase de ventana
"Asediado por todos lados", //El nombre del título de la instancia de la ventana
WS_MINIMIZEBOX|WS_SYSMENU, //Estilo de la ventana
Istreenwide/2-w * celda/2, //La línea horizontal en la esquina superior izquierda de la ventana Coordenada (x)
Celda, //La coordenada vertical (y) de la esquina superior izquierda de la ventana
w *Cell, //El ancho de la ventana
h *Cell, //La altura de la ventana
NULL, //La ventana no tiene ventana principal.
NULL, //La ventana no tiene menú principal. HInstance, //El identificador actual de la aplicación que creó esta ventana
NULL //No utilice este valor.
Si (!hwnd) devuelve FALSO
//Mostrar ventana
Mostrar ventana (hwnd, icmd show);
//Dibujar área de usuario
Ventana de actualización ( hwnd);
MessageBox(hwnd, "Iniciar el juego\n\nOh, sí", "Iniciar", MB_OK);
SendMessage(hwnd, MS_NEWBLOCK, 0, 0 );
SetTimer (hwnd, 1, 100, NULL);
//Bucle de mensajes
while( GetMessage(& msg, NULL, 0 , 0))
{
Traducir mensaje(&MSG);
enviar mensaje(&MSG);
}
//Cuando finaliza el ciclo del mensaje, es decir, cuando finaliza el programa, el mensaje se devuelve al sistema
Devuelve msg.wParam.
}
//Parámetros: identificador de entorno del dispositivo y las cuatro coordenadas de las esquinas del cuadrado. .
void DrawRect (HDC hdc, int l, int t, int r, int b)
{
MoveToEx (hdc, l, t, NULL) ;//Mueve el cursor a (l, t)
LineTo (hdc, r, t
LineTo (hdc, r, b
LineTo (hdc, l, b);
LineTo (hdc, l, t
}
//Función DrawCell: Dibujar un cuadrado - (Rojo■)
//Parámetros: identificador del entorno del dispositivo y coordenadas de las cuatro esquinas de la cuadrícula.
void DrawCell (HDC hdc, int l, int t, int r, int b)
{
HBRUSH hbrush
HB rush = CreateSolidBrush(RGB(255, 0, 0)); //Pincel rojo
SelectObject(hdc, HB rush);
Rectángulo (hdc, l, t, r, b);
eliminar objeto(HB rush);
}
//Dibuja los bloques del área de juego, incluidos "espacio de juego" y "mostrar next Espacio cuadrado"
//Esta función está incluida en la función Portada. Parámetros: identificador del entorno del dispositivo
void DrawGamePlace(HDC hdc)
{
int i, j;
HPEN hpen1, hpen2
hpen1=CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
hpen2=CreatePen(PS_DASHDOTDOT, 3, RGB(0, 0, 255)); /p>
//Dibuja una línea divisoria
SelectObject(hdc, hpen 2);
MoveToEx(hdc, (W-8)*CELL, 0, NULL) ;
LineTo(hdc, (W-8)*CELL, H * CELL);
//Dibuja las líneas de cuadrícula (verde) del área de juego
SelectObject(hdc,hpen 1);
for(I = 1;i<h-1;i++)
for(j=1;j<=W-8 ;j++)
DrawRect (hdc, (j-1)*cell, (I-1)*cell, j*cell, I*cell);
//Dibuja una línea de cuadrícula en el área "Mostrar siguiente".
for(I = 5;i<9;i++) // 5≤i≤8
for(j = W-5;j <w-1;j++) / / 15≤ j≤18
DrawRect (hdc, (j-1)*celda, (I-1)*celda, j*celda, I*celda);
eliminar objeto(hpen 2);
eliminar objeto(hpen 1);
}
//Función DrawBlock: Dibuja Rusia que aparece en los bloques del juego.
//Parámetros: identificador del entorno del dispositivo y posición de los cuatro bloques de Tetris en el área de juego.
//Cada Tetris consta de cuatro bloques de siete formas diferentes.
Bloque estirado vacío(HDC hdc, int block[4][2])
{
int I;
for ( I = 0;i<4;i++)
DrawCell (hdc, (bloque[I][0]-1)*celda, (bloque[I][1]-1)*celda celda, // ....
bloque[I][0]*celda, bloque[I][1]*celda);
}
//Función Portada: Completa el Tetris en su posición original.
//Parámetros: identificador del entorno del dispositivo y Tetris a borrar.
//Función (1) Limpiar Tetris, es decir, dibujar un cuadrado blanco en cada bloque de Tetris.
// (2) Vuelve a dibujar los bloques en el área de juego.
Sobrescritura no válida(HDC hdc, int org[4][2])
{
int I;
HBRUSH hbrush
//Redibujar área de juego
dibujar lugar de juego(hdc);
HBRUSH =(HBRUSH)GetStockObject(BLACK _ BRUSH);
SeleccionarObjeto (hdc, HB rush);
for(I = 0;i<4;i++)
Rectángulo (hdc, (org[I][0]-1 )*celda , (org[I][1]-1)*celda, //.....
org[i][0]*CELDA, org[I][1 ]* CELDA);
eliminar objeto(HB rush);
}
// - función de proceso de ventana wndproc.
Devolución de llamada LRESULT WndProc (HWND hwnd,
UINT iMsg,
WPARAM wParam,
LPARAM lParam)
{
int i, j, k, líneas, r;
static int top, sel, flag
static int celda [W-6] [ H]; //Controla la matriz de cuadrícula del área de juego
Static int org[4][2], block[4][2], org 2[4][2];
HDC hdc
HPEN hpen;
PAINTSTRUCT ps
interruptor (iMsg)
{
Caso WM_CREATE:
//Cuando la aplicación utiliza la función CreateWindow o CreateWindowEx para crear una ventana,
//El sistema envía este mensaje al proceso de nueva ventana. Este mensaje se mostrará después de crear la ventana.
//El mensaje se enviará antes de que regrese la función CreateWindow o CreateWindowEx.
top = H-1;
//Coloca la primera y última columna de bloques en 1, y el marco de control no debe exceder el área de juego.
for(I = 0;i<h;i++)
{
Celda[0][I]= 1;
Celda [W-7][I]= 1;
}
//Establece la fila inferior de bloques en 1 y la caja de control no excederá el área de juego.
for(I = 0;i<w-6;i++)
celdas[I][H-1]= 1;
//Otros El cuadrado está establecido en 0 y el marco del juego solo se puede mover aquí.
for(I = 1;i & lt= W-8;i++)
for(j = 0;j & lth-1;j++)
Celda[I][j] = 0;
Devuelve 0;
Caso MS_NEWBLOCK:
flag = 0 //La bandera indica que el cuadrado es girado cuantas veces.
for(I = top;i<h-1;i++)
{
lines = 0;
instrucción de bucle verificar si La fila está completamente llena de cuadrados.
for(j = 1;j & lt= W-7;j++)
if (!cell[j][i])
{
lines = 1;
Break;
}
//Si esta línea está completa, cambie el estado de llenado de la línea anterior Copie en esta línea, y así sucesivamente.
//Es decir, a partir de esta línea, todos los bloques bajan una línea.
if (! línea)
{ for(j = 1; j & ltw-7; j++)
for(k = I; k & gt = topk -)
Cell[j][k]=cell[j][k-1];
top++;
//Esta función agrega un rectángulo en el área de usuario de la ventana especificada fuera del área de actualización de la ventana.
//Invalidar el rectángulo. Reciba el rectángulo no válido y actualice el resto del área.
//Se volverá a dibujar el mensaje WM_PAINT. Se han acumulado áreas no válidas en el área de actualización hasta
//Cuando aparezca el siguiente mensaje WM_PAINT, el área se procesará.
invalidate erupter(hwnd, NULL, TRUE);
}
}
// Genera números aleatorios 0 ~ 7, respectivamente. Siete formas que representan cuadrados.
srand((unsigned) time(empty));
sel = rand()% 7;
//Inicialización de la forma del cuadro
//La forma del cuadrado está determinada por la posición de cada cuadrado.
//Ancho del área de juego W=20, bloque[? ][0]=4/5/6/7,bloque[? ][1]=0/1/2
//La posición inicial de este bloque es en la parte superior central del área de juego.
Interruptor (selección)
{
Caso 0:
// ▓▓
// ▓ ▓
Organización[0][0] = bloque[0][0]= 5; org[0][1]= bloque[0][1]=
org[1][0]= bloque[1][0]= 6; org[1][1]= bloque[1][1]= 0;
Organización[2][0 ] = bloque[2][0]= 5; org[2][1]= bloque[2][1]= 1;
org[3][0] = bloque[3][ 0]= 6; org[3][1]= bloque[3][1]= 1;
for(I = 0;i<4;i++)
{ p>
org 2[I][0]= org[I][0]+11;
org 2[I][1]= org[I][1]+ 5;
}
Rotura;
Caso 1:
//▓▓▓▓
Organización [0 ][0] = bloque[0][0]= 4; org[0][1]= bloque[0][1]= 0
org[1][0]= bloque[; 1][0]= 5; org[1][1]= bloque[1][1]= 0;
org[2][0]= bloque[2][0] = 6 ;org[2][1]= bloque[2][1]= 0;
org[3][0] = bloque[3][0]= 7;org[3] [1 ]= bloque[3][1]= 0;
for(I = 0;i<4;i++)
{
org 2 [I][ 0]= org[I][0]+11;
org 2[I][1]= org[I][1]+5;
}
Rotura;
Caso 2:
//▓
//▓▓
// ▓
Organización[0][0] = bloque[0][0]= 5; org[0][1]= bloque[0][1]=
org[1; ][0]= bloque[1][0]= 5; org[1][1]= bloque[1][1]= 1;
org[2][0 ]= bloque[ 2][0]= 6; org[2][1]= bloque[2][1]= 1;
org[3][0] = bloque[3][ 0]= 6 org[3][1]= bloque[3][1]= 2;
for(I = 0;i<4;i++)
{
org 2[I][0]= org[I][0]+11;
org 2[I][1]= org[I][1]+ 5;
}
Descanso;
Caso 3:
// ▓
//▓▓
//▓
org[0][0]= bloque[0][0]= 6; org[0][1]= bloque[0][1] = 0;
org[1][0]= bloque[1][0]= 6; org[1][1]= bloque[1][1]= 1;
Organización[2] ][0] = bloque[2][0]= 5; org[2][1]= bloque[2][1]= 1;
Organización[3] [0] = bloque[ 3][0]= 5; org[3][1]= bloque[3][1]= 2
para(I = 0;i<4;i++ )
{
org 2[I][0]= org[I][0]+11;
o
g 2[I][1]= org[I][1]+5;
}
Descanso;
Caso 4:
//▓
//▓
//▓▓
org[0][0] = bloque[0][0]= 5;org[0][1]= bloque[0][1]= 0;
org[1][0]= bloque[1][0]= 5;org[1][ 1]= bloque[1][1]= 1;
Organización[2][0]=bloque[2][0]= 5;org[2][1]= bloque[2] [1]= 2;
org[3][0]=bloque[3][0]= 6;org[3][1]= bloque[3][1]= 2;
for(I = 0;i<4;i++)
{
org 2[I][0]= org[I][0]+ 11;
org 2[I][1]= org[I][1]+5;
}
Descanso;
Caso 5:
// ▓
// ▓
//▓▓
Organización[0][0] =bloque [0][0]= 5;org[0][1]= bloque[0][1]= 0;
org[1][0]= bloque[1][0 ]= 5;org[1][1]= bloque[1][1]= 1;
org[2][0]=bloque[2][0]= 5;org[2 ][ 1]= bloque[2][1]= 2;
Organización[3][0]=bloque[3][0]= 4;org[3][1]= bloque[ 3] [1]= 2;
for(I = 0;i<4;i++)
{
org 2[I][0] = org[I ][0]+11;
org 2[I][1]= org[I][1]+5;
}
Romper;
Caso 6:
// ▓
//▓▓▓
Organización[0][0] =bloque[0 ][0]= 5;org[0][1]= bloque[0][1]= 0;
org[1][0]= bloque[1][0 ]= 4; org[1][1]= bloque[1][1]= 1;
Organización[2][0]=bloque[2][0]= 5;org[2 ][1] = bloque[2][1]= 1;
Organización[3][0]=bloque[3][0]= 6;org[3][1]= bloque[ 3][1 ]= 1;
for(I = 0;i<4;i++)
{
org 2[I][0] = org[I][ 0]+11;
org 2[I][1]= org[I][1]+5;
}
Enviar mensaje (hwnd, MS_NEXTBLOCK, 0, 0);
Interrupción;
Valor predeterminado:
Enviar mensaje (hwnd, MS_NEWBLOCK, 0, 0); >EnviarMensaje (hwnd, MS_NEXTBLOCK, 0, 0);
Interrupción
}
Devuelve 0
Caso WM_TIMER:
//El beat box baja automáticamente una línea cada vez.
for(I = 0;i<4;i++)
block[I][1]++;
//Marque la casilla para moverse hacia abajo Si está bloqueado, es decir, determina si hay un cuadro en la nueva posición después de moverse hacia abajo.
for(I = 0;i<4;i++)
if(celda[bloque[i][0]][bloque[i][1]])
{
Enviar mensaje (hwnd, MS_NEXTBLOCK, 0, 0,
para (I = 0; i<4;i++)
celdas[org[); I][0]][org[I][1]]= 1;
if(arriba & gt;org[0][1]-2)
arriba = org[0][1]-2;
if(top & lt;1)
{
KillTimer (hwnd, 1 ;
}
EnviarMensaje (hwnd, MS_NEWBLOCK, 0, 0
Devuelve 0;
}
EnviarMensaje (hwnd, MS_DRAW, 0); , 0);
Devuelve 0;
//Respuesta al control del teclado
Caso WM_KEYDOWN:
r = 0 ; p>
switch((int)wParam)
{
Caso VK_left:
for(I = 0;i& lt4;i++) p>
Bloque[I][0]-;
Romper;
Keith VK_Right:
for (i = 0;i<4;i++)
bloque[I][0]++;
romper;
caso vk_tang:
for(I = 0;i<4 ;i++)
block[I][1]++;
break;
//Presiona [Flecha arriba] para rotar el bloque en el sentido de las agujas del reloj.
//La rotación del cuadrado no es una rotación real, sino una rotación basada en diferentes formas y cuadrados de cuadrados.
//Mueve uno o varios cuadrados dos veces para conseguir el efecto de rotación. Esto es complejo y el algoritmo no es ideal
//Pero puede mantener el centro de gravedad del cuadrado relativamente estable durante la rotación.
Kes VK_UP:
r = 1;
flag++; // Rotación cuadrada más 1
Switch(sel) // sel representa la forma del cuadrado actual.
{
Caso 0: roto
Caso 1:
bandera = bandera % 2; for(I = 0;i<4;i++)
{
bloque[I][(bandera+1)% 2]= org[2][(bandera+1 )% 2];
bloque[I][bandera]= org[2][bandera]-2+I;
}
Romper;
Caso 2:
bandera =bandera % 2;
if (bandera)
{ block[0][1]+= 2; bloque[3][0]-= 2;}
Otro
{ bloque[0][1]-= 2; bloque[3][0]+= 2; }
Pausa;
Caso 3:
bandera = bandera % 2;
si (bandera)
{ bloque[0][1]+= 2; bloque[3][0]+= 2;}
Otros
{ bloque[0][1] -= 2; bloque[3][0]-= 2;}
Romper;
Caso 4:
bandera = bandera % 4;
p>
Interruptor (bandera)
{
Caso 0:
bloque[2][0]+= bloque[; 3][ 0]+= 2;
bloque[2][1]+= 1; bloque[3][1]+= 1;
Romper;
Caso 1:
bloque[2][0]+= 1; bloque[3][0]+= 1;
bloque[2][1] -= 2 ;bloque[3][1]-= 2;
Romper;
Caso 2:
bloque[2][0]-= 2; bloque [3][0]-= 2;
bloque[2][1]-= 1; bloque[3][1]-= 1;
Romper ;
p>Caso 3:
bloque[2][0]-= 1; bloque[3][0]-= 1;
bloque [2][1 ]+= 2; bloque[3][1]+= 2;
Romper
}
Romper; >
Caso 5:
bandera = bandera % 4;
Cambiar (bandera)
{
Caso 0:
bloque[2][0]+= 1; bloque[3][0]+= 1
bloque[2][1]+= 2; [1]+= 2;
Romper;
Caso 1:
bloque[2][0]+= 2; ]+= 2;
bloque[2][1]-= 1; bloque[3][1]-=
Romper; Caso 2:
p>bloque[2][0]-= 1; bloque[3][0]-=
bloque[2][1]-=; 2; bloque[3][ 1]-= 2;
Romper;
Caso 3:
bloque[2][0]-= 2; bloque[3][0] -= 2;
bloque[2][1]+= 1; bloque[3][1]+= 1;
Romper;
}
Pausa;
Caso 6:
bandera = bandera % 4;
Cambiar (bandera)
{
Caso 0:
bloque[0][0]++;
bloque[0][1]-;
bloque[1][0]-;bloque[1][1]-;
bloque[3][0]++ ;bloque[3][1]++;
Romper;
Caso 1:
bloque[1][0]++;bloque[1 ][1]++;Romper;
Caso 2:
Bloque[0][0]-;bloque[0][1]++;Romper;
Caso 3:
Bloque[3][0]-;bloque[3][1]-;Romper;
}
Romper ;
}
Romper;
}
//Determinar si hay un bloque en la nueva posición después de rotar el bloque , y si es así, cancelar la rotación.
for(I = 0;i<4;i++)
if(celda[bloque[i][0]][bloque[i][1]])
{
if(r)flag+= 3;
for(I = 0;i<4;i++)
for( j = 0; j & lt2; j++)
bloque[I][j]= org[I][j];
Devuelve 0;
}
SendMessage(hwnd, MS_DRAW, 0, 0);;
Return 0;
//Borrar el cuadro actual y dibujar y mostrar el "cuadro siguiente" el cuadro siguiente .
Caso MS_NEXTBLOCK:
hdc = GetDC(hwnd);
Cubierta(hdc, org 2); hdc, org 2);
Return 0;
//Borrar el cuadro actual y volver a dibujar el cuadro en la nueva ubicación.
Caso MS_DRAW:
hdc = GetDC(hwnd);
Cubierta(hdc, org);
Dispositivo de tracción(hdc, org 2);
for(I = 0;i<4;i++)
for(j = 0;j<2;j++)
org [I][ j]= block[I][j];
Bloque de tracción (hdc, block);
ReleaseDC (hwnd, hdc);
Devuelve 0;
//Vuelve a dibujar los bloques del área de juego según la matriz de la cuadrícula.
Caso WM_PAINT:
hdc = comenzar pintura(hwnd & PS);
dibujar lugar del juego(hdc); (hdc, 15*CELL, 12*CELL, " Puntuación ", lstrlen(" Puntuación "));
TextOut(hdc, 15*CELL, 13*CELL, " I ", lstrlen(" I "));
TextOut(hdc, 15*CELL, 15*CELL, " Nivel ", lstrlen(" Nivel "));
Textout (HDC, 15 * celda - 5, 19 * celda, "Fortaleza asediada", lstrlen("Fortaleza asediada"));
hpen =CreatePen (PS_SOLID, 1, RGB (0, 255, 0)); p >SelectObject (hdc, hpen);
for(I = top;i<h-1;i++)
for(j=1;j<=W-8; j++)
if(celda[j][i])
DibujarCélula (hdc, (j-1)*CELDA, (i-1)*CELDA, j*CELDA , I * CELDA );
eliminar objeto(hpen);
capa superior(hwnd&PS);
devolver 0;
Caso WM_DESTROY:
KillTimer (hwnd, 1);
PostQuitMessage(0);
Devuelve 0
}
Devuelve DefWindowProc (hwnd, iMsg, wParam, lParam
}
);