1. Enquadramento geral
É o mesmo que o jogo escrito antes. A estrutura geral é assim (há um breve diretório). Nós encapsulamos principalmente a função play().
Como referenciamos nosso próprio arquivo de cabeçalho "game.h", podemos colocar as instruções de pré-processamento das funções da biblioteca que queremos referenciar no arquivo de cabeçalho "game.h".
Se você for cuidadoso, descobrirá que a matriz que definimos tem 20 linhas e 40 colunas, porque quando projetamos o mapa, o mapa estava cercado por '-' e '|'. Você pode descobrir que o último tem o dobro do comprimento do primeiro. Para formar um mapa quadrado, o número de linhas deve ser o dobro do número de colunas.
2. Inicialização do mapa
Esta é a inicialização do array. Se quisermos imprimir '-', então armazene 1 no array. Da mesma forma, '|' armazena 2 no array e armazena 0 em outras posições. A cabeça da cobra é 3 e a comida é 4. 0 1 2 3 4 é armazenado na matriz aqui para a conveniência de imprimir o mapa posteriormente. Quando percorremos o array, imprimimos '-' quando encontramos 1, imprimimos um espaço quando encontramos 0 e assim por diante.
3. Impressão de mapas
Conforme mencionado acima, 1 representa '-', 2 representa '|', 0 representa espaço, 3 representa cabeça de cobra e 4 representa comida.
4. O movimento das cobras
O movimento da cobra é na verdade um efeito visual. Se mudarmos continuamente as coordenadas da cabeça da cobra e depois limparmos a tela, obteremos o efeito de movimento.
Duas funções também são introduzidas aqui:
1. kbhit: (Arquivo de cabeçalho: conio) Sua função é retornar um valor verdadeiro quando os dados são inseridos. Quando jogamos com Snake, se a direção do corpo da cobra não for alterada, ela continuará avançando. Isso está relacionado ao kbhit.
Quando não inserimos, ele não entra nesta declaração.
2. getch: (Arquivo de cabeçalho: conio) Esta função não precisa pressionar Enter ao ler os dados, ela concluirá automaticamente a próxima etapa. Se usarmos getchar aqui, será muito embaraçoso. Ainda precisamos pressionar Enter ao entrar um personagem. , caso contrário a cobra não se moveria.
Inserimos wsad no teclado, que é convertido na atribuição de diferentes valores à direção, para que as coordenadas da cabeça da cobra mudem. Algumas pessoas aqui podem se perguntar por que duas instruções switch são usadas, uma para receber ch e outra para receber direção, porque quando não inserimos wsad, a cobra se moverá em uma direção. Isso ocorre porque definimos uma variável de direção no início e atribuiu-o ao valor inicial.
5. Como tornar o corpo da cobra gradualmente mais longo
É quando as coordenadas da cabeça da cobra coincidem com as coordenadas da comida, redefinimos as coordenadas da comida e marcamos +1; e nossa contagem também está relacionada ao comprimento do corpo da cobra. Este
código pode não ser fácil de entender, sua função é atribuir a coordenada anterior da estrutura à próxima coordenada.
Aqui você pode ver que quando a cabeça da cobra continua avançando, o corpo da cobra também avança, mas precisamos limpar a última seção do corpo da cobra.
6. Exibição do código final
//
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
void initmap(int arr[20][40]);
void printmap(int arr[20][40]);
void playmap(int arr[20][40]);
jogo.c
//
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
typedef struct Snake
{
int x;
int y;
}S;
S snake[800] = { {15,20} };
int arr[20][40] = { 0 };
int food_x = 2;
int food_y = 6;
int count = 0;
int i = 0;
void initmap(int arr[20][40])
{
int i = 0;
int j = 0;
for (i = 0; i < 20; i++)
{
for (j = 0; j < 40; j++)
{
if (0 == i || 19 == i)//1,-, 2,|, 0,打印空格 3,打印蛇头'*'
arr[i][j] = 1;
if (0 == j || 39 == j)
arr[i][j] = 2;
}
}
}
void printmap(int arr[20][40])
{
int i = 0;
int j = 0;
for (i = 0; i < 20; i++)
{
for (j = 0; j < 40; j++)
{
switch (arr[i][j])
{
case 1:printf("-"); break;
case 2:printf("|"); break;
case 0:printf(" "); break;
case 3:printf("*"); break;
case 4:printf("$"); break;
}
}
printf("\n");
}
}
void playmap(int arr[20][40])
{
int direction = 1;
while (1)
{
arr[food_x][food_y] = 4;
arr[snake[count].x][snake[count].y] = 0;//最后一节不断消失
char ch = 0;
if (_kbhit())
{
ch = _getch();
switch (ch)
{
case 'w':direction = 1 ;break;
case 's':direction = 2; break;
case 'a':direction = 3; break;
case 'd':direction = 4; break;
default:break;
}
}
for (i = count; i > 0; i--)
{
snake[i].x = snake[i - 1].x;
snake[i].y = snake[i - 1].y;
arr[snake[i].x][snake[i].y] = 3;
}
switch (direction)
{
case 1:snake[0].x--; break;
case 2:snake[0].x++; break;
case 3:snake[0].y--; break;
case 4:snake[0].y++; break;
default:break;
}
arr[snake[0].x][snake[0].y] = 3;
Sleep(50);
system("cls");
if (snake[0].x == 0 || snake[0].x == 19 || snake[0].y == 0 || snake[0].y == 39)
exit(0);
if (snake[0].x == food_x && snake[0].y == food_y)
{
arr[food_x][food_y] = 0;
food_x = rand() % 18+1;
food_y = rand() % 38+1;
arr[food_x][food_y] = 4;
count++;
}
printmap(arr);
printf("\ncount=%d",count);
}
}
teste.c
//
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("**********************************\n");
printf("*********** 1.play ***************\n");
printf("*********** 0.exit ***************\n");
printf("**********************************\n");
}
void play()
{
int snake_x = 10;
int snake_y = 15;
int arr[20][40]={0};
initmap(arr);
printmap(arr);
playmap(arr);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:play(); break;
case 2:printf("退出游戏\n"); break;
default:printf("输入错误,请重新输入\n"); break;
}
} while (input);
return 0;
}
Obrigado por assistir! ! !