Minijuego: El primer minijuego que escribí en mi vida: Snake (lenguaje C)

        El editor abrió una columna sobre juegos, que utilizan principalmente la biblioteca de gráficos easyx.


Índice de contenidos de series de artículos:     

       Capítulo 1: El primer minijuego escrito en la vida: Snake (lenguaje C)


        He publicado el código de este juego en gitee. Si no te importa, puedes ir a este sitio web para verlo y copiarlo: https://gitee.com/rising-sun-1 .

       Hoy, usemos la biblioteca de gráficos easyx y el lenguaje C para escribir código. En primer lugar, tenemos que analizar la idea general de este pequeño juego y luego escribir el código.


Tabla de contenido

análisis de idea:

ventana:

Serpiente codiciosa:

alimento:

Otras funciones:

Escritura de código:

Preparación antes de escribir código:

Preparación inicial:

Creación de Serpiente: 

Creación de alimentos:

Condiciones de finalización del juego:

Inicialización del juego:

Dentro de la función principal:


análisis de idea:

ventana:

       Primero, cree una ventana de píxeles y use la función initgraph para crearla (el uso básico de esta función se puede ver en este sitio web: https://docs.easyx.cn/zh-cn/intro ).

       Después de crearlo, empieza a pensar en los elementos básicos del juego: serpientes y comida . El siguiente es un análisis de las serpientes codiciosas y la comida:

Serpiente codiciosa:

       Para una serpiente codiciosa, se necesitan varias rejillas, entonces, ¿cómo se conectan estas rejillas? Debido a que las matrices requieren que datos del mismo tipo se almacenen juntos, pero almacenar el cuerpo de la serpiente en un espacio bidimensional requiere coordenadas, el uso de matrices es relativamente problemático. Podemos usar estructuras para representar los nodos de la serpiente. Como la serpiente quiere moverse, podemos mover el nodo de la cabeza y luego eliminar el nodo de la cola para que la serpiente pueda moverse. La serpiente necesita cambiar de dirección al moverse ¿Cómo cambiar de dirección? Las coordenadas se pueden considerar, por ejemplo, si se mueve hacia abajo, la coordenada vertical aumentará en uno, etc.

alimento:

       Los alimentos deben distribuirse aleatoriamente , por lo tanto, para seleccionar números aleatorios, use la función rand (use cplusplus.com para ver el propósito de la función), para que los números aleatorios sean más aleatorios, necesitamos usar la función de tiempo ( necesita para llamar al archivo de encabezado #include <time.h>). 

Otras funciones:

       Otras características incluyen comida para comer serpientes, alargamiento del cuerpo de la serpiente, condición de fin del juego, reinicialización después del fin del juego, discutidas mientras se escribe el código.

La idea general es la anterior, escribamos el código a continuación:

Escritura de código:

Preparación antes de escribir código:

        En primer lugar, debe descargar la biblioteca de gráficos easyx ( https://easyx.cn/ ), después de la descarga, opere de acuerdo con la imagen, ingrese VS para crear un proyecto, seleccione la aplicación de consola e ingrese para escribir código. .

Preparación inicial:

       Primero, escriba archivos de encabezado y macros para proteger la inseguridad de la función scanf.

(La razón por la que no se utiliza la función scanf_s es porque la función scanf_s es VS y no es compatible con otros compiladores, lo que resulta en la no portabilidad de la función).

       A continuación, cree una función principal, cree una ventana con una altura de 800 píxeles y un ancho de 600 píxeles de acuerdo con la idea de análisis, y luego use la función de línea para dibujar la tabla. El código general es el siguiente:

void printline()   //进行表格的绘画
{
	int x = 0;
	for (x = 0; x <= 800; x += NODE_WIDTH)
	{
		line(x, 0, x, 600);   //line函数是画出直线的函数
	}
	int y = 0;
	for (y = 0; y < 600; y += NODE_WIDTH)
	{
		line(0, y, 800, y);
	}
}
int main()
{
    //创建窗口
	initgraph(800, 600);
	setbkcolor(RGB(164, 225, 202)); //创建一个像素窗口
	cleardevice();
	getchar();
	closegraph();
	return 0;
}

Creación de Serpiente: 

      Luego crea la serpiente y usa la estructura para crear un nodo.

typedef struct {   //贪吃蛇的结点
	int x;
	int y;
}node;

       Defina la posición inicial de la serpiente:

node snack[100] = { {5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7} };

       Debido a que el cuerpo de la serpiente se compone de múltiples rectángulos (cubos), es necesario construirlo usando un bucle . Se sabe que la longitud de la serpiente se construye usando un bucle for.

       Hay tres bucles en lenguaje C, a saber: for, while y do while. Tienen algunas diferencias que los hacen aplicables a diferentes escenarios. Si se conoce el número de bucles, utilice un bucle for, si no conoce el número de bucles, utilice un bucle while y si desea realizar un bucle una vez, utilice un hacer mientras bucle.

void printsnack(node* snack, int n)  //进行蛇主题的绘画
{
	int left, right, bottom, top;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		left = snack[i].x * NODE_WIDTH;
		top = snack[i].y * NODE_WIDTH;
		right = (snack[i].x + 1) * NODE_WIDTH;
		bottom = (snack[i].y + 1) * NODE_WIDTH;
		solidrectangle(left, top, right, bottom); 
	}
}

       Después de construir la serpiente, mueve la serpiente, ¿cómo hacer que la serpiente se mueva? Use coordenadas para hacer que la serpiente se mueva. Por ejemplo, pasar el valor del nodo anterior al valor del siguiente nodo y hacer un bucle hará que la serpiente se mueva un paso hacia la derecha. Usar el nodo principal para mover la serpiente también usa el nodo principal.punto para controlar la dirección, por ejemplo, para moverse hacia arriba, la coordenada vertical del nodo principal es menos uno, el código es el siguiente:

node snackmove(node* snack, int length, int direction) //蛇移动的函数
{
	node newfinsh = snack[length - 1];  //将蛇结点的最后一个结点保存下来
	for (int i = length - 1; i > 0; i--)
	{
		snack[i] = snack[i - 1];   //将前一个蛇结点移动到后一个蛇结点,进行蛇的移动
	}
	node head;  //定义一个头结点并利用头结点进行方向的移动
	head = snack[0];
	if (direction == eUp)
	{
		head.y--;
	}
	else if (direction == eDown)
	{
		head.y++;
	}
	else if (direction == eLeft)
	{
		head.x--;
	}
	else if (direction == eRight)
	{
		head.x++;
	}
	snack[0] = head;
	return newfinsh;
}

       Aquí se explica cómo interactuar con el teclado , es decir, escribir 'w' en el teclado hará que la serpiente se mueva hacia arriba. Primero, use la función _kbhit para verificar si hay datos en el área del búfer de entrada y use la función getch () para obtener los datos de entrada del área del búfer y generar los datos correspondientes. Cabe señalar aquí que la serpiente no puede moverse en la dirección opuesta a la dirección de movimiento, por lo que es necesario agregar condiciones.

void changedirection(enum direction* pD)   //中间有键盘交互的代码
{ 
	if (_kbhit() != 0)//检查输入缓存区中是否有数据
	{
		char c = _getch();//从缓存区中获取输入数据并做相应的数据
		switch (c)
		{
		case 'w':
			if(*pD != eDown) //要注意蛇不能向正在移动的反方向进行移动
			*pD = eUp;
			break;
		case 's':
			if(*pD != eUp)
			*pD = eDown;
			break;
		case 'a':
			if(*pD != eRight)
			*pD = eLeft;
			break;
		case 'd':
			if(*pD != eLeft)
			*pD = eRight;
			break;
		}
	}
}

Creación de alimentos:

       La creación de alimentos debe distribuirse aleatoriamente , por lo que se utilizan números aleatorios para aleatorizar la ubicación de los alimentos. El valor aleatorio debe estar dentro de la ventana creada y no puede exceder la ventana. No se puede crear comida en el cuerpo de la serpiente, el código es el siguiente:

node creatfood(node* snack, int length)  //创建食物
{
	node food;
	while (1)
	{
		food.x = rand() % (800 / NODE_WIDTH); //利用随机数进行食物位置的随机
		food.y = rand() % (600 / NODE_WIDTH);
		int i = 0;
		for (i = 0; i < length; i++) //利用for循环一一遍历,防止食物生成在蛇身上
		{
			if (food.x == snack[i].x && food.y == snack[i].y)
			{
				break;
			}
		}
		if (i < length) //如果i小于蛇的长度,则需要继续遍历,知道i大于蛇的长度
		{
			continue;
		}
		else
			break;
	}
	return food;
}

       Es relativamente fácil imprimir comida en el formulario, que también se dibuja usando la función solidrectangle, sin embargo, para distinguir el color de la comida y la serpiente, podemos usar la función setfillcolor para llenarlo con diferentes colores.

Condiciones de finalización del juego:

       La condición es que la serpiente no pueda tocar la pared y la serpiente no pueda tocar el cuerpo de la serpiente, lo que se puede hacer usando el juicio. Tenga en cuenta que el tipo de retorno de esta función es de tipo bool.

bool isgameover(node* snack, int length)//游戏结束的条件
{
	if (snack[0].x < 0 || snack[0].x>800 / NODE_WIDTH)//当蛇碰到墙壁,游戏结束
		return true;
	if (snack[0].y < 0 || snack[0].y>600 / NODE_WIDTH)
		return true;
	for (int i = 1; i < length; i++)   //当蛇碰到蛇身游戏结束
	{
		if (snack[0].x == snack[i].x && snack[0].y == snack[i].y)
			return true;
	}
	return false;
}

Inicialización del juego:

        Es el estado de dejar que el juego progrese y reiniciarlo.

Dentro de la función principal:

        Utilice la función Dormir para ajustar la velocidad del movimiento de la serpiente. Si la serpiente come comida, crecerá más.

while (1)
	{
		cleardevice();
		printline();
		printsnack(snack, length);
		printfood(food);
		Sleep(500);
		changedirection(&d);
		node newlist = snackmove(snack, length, d);
		if (snack[0].x == food.x && snack[0].y == food.y)
		{
			if(length < 100)
			{
				snack[length] = newlist;
				length++;
			}
			food = creatfood(snack, length);
		}
		if (isgameover(snack, length) == true)
		{
			reset(snack, &length, &d);
			food = creatfood(snack, length);
		}
	}

          Gracias a todos por mirar, si hay algún error, espero que puedan criticarlo y corregirlo. Este es un recién llegado que acaba de embarcarse en un viaje de programación.

Supongo que te gusta

Origin blog.csdn.net/2301_77868664/article/details/131151819
Recomendado
Clasificación