C语言项目 [一] | ——— | 贪吃蛇源码+讲解

贪吃蛇

PS:此贪吃蛇是利用结构体数组的方式实现的!

贪吃蛇项目开发平台:

VS2017 + 图形库

一、在VS2017中添加图形库,具体方法见如下文章

如何在VS2017中添加 ”graphics.h” 头文件? So easy

二、贪吃蛇的框架

  • 1.蛇的属性

          蛇的属性包括蛇的长度+蛇的坐标+蛇的方向

  • 2.食物的属性

          食物的坐标

  • 3.蛇的初始化

          初始化开始时蛇的方向和长度

  • 4.在窗口绘制蛇和食物

          利用图形库自带的函数绘制蛇和食物

  • 5.蛇的移动和食物的随机出现

          利用四个方向上蛇坐标的变化来实现蛇的运动,利用随机数来实现食物的随机出现

  • 6.蛇的方向

          利用_getch()输入来判断和改变蛇的方向

  • 7.蛇的死亡条件

          利用条件语句来判断蛇是否撞墙和咬尾

  • 8.暂停、继续和退出

          利用_getch()输入来暂停、继续或者退出游戏!

  • 9.还有很多的功能可以DIY!

贴代码时刻:

在贴代码之前有一段说明:

#include
#pragma comment(lib,"winmm.lib")

//初始化音乐
//PlaySound();//WAV
mciSendString("open 遥不可及的你.mp3 alias BGM", 0, 0, 0);//向底层声卡驱动发送字符串消息
mciSendString("play BGM", 0, 0, 0);

这些代码是用来播放音乐的API接口

遥不可及的你.mp3 这个文件就是播放音乐的文件,大家可以下载我的演示视频观看就知道怎么回事了.

视频链接   :  https://pan.baidu.com/s/1BEge-PZxsMvZ17blgvg8qw 
提  取  码   :  yie0

snack.h文件

#include 
#include 
#include 
#include 
#include 
#pragma comment(lib,"winmm.lib")

//蛇的最大长度
#define SNACK_LENTH 500

//方向
enum Ch {
	up = 72,
	down = 80,
	left = 75,
	right = 77,
	backspase = 32,
	esc = 27
};
//坐标
struct Coor {
	int x;
	int y;
};
struct Snack
{
	//一条蛇的属性
	int n;
	Coor szb[SNACK_LENTH];
	Ch ch;
}snack; 

struct Food {
	Coor fzb;
	int flag;
}food;


void InitSnack();
void DrawSnack();
void MoveSnack();
void ChangeSnackCh();
void CoorFood();
void DrawFood();
void EatFood();
void ExitSystem();

snack.cpp文件

#include "snack.h"              // 引用图形库头文件
int move;
int main()
{
	InitSnack();//1.初始化蛇
	/*
		按键之前.程序在做什么?
			移动+绘图(循环)
			//按键
		改变蛇的方向.按键之后
			移动+绘图(循环)
	*/
	while (1) {
		while (!_kbhit()) 
		{
			if (food.flag==0) {
				CoorFood();
			}
			cleardevice();
			MoveSnack();
			DrawFood();	
			DrawSnack();
			EatFood();
			ExitSystem();
			Sleep(100);
		}
		ChangeSnackCh();
	}
	system("pause");
	return 0;
}

void InitSnack() {
	//初始化窗口
	initgraph(640,480);
	srand((unsigned int)time(NULL));

	//初始化音乐
	//PlaySound();//WAV
	mciSendString("open 遥不可及的你.mp3 alias BGM", 0, 0, 0);//向底层声卡驱动发送字符串消息
	mciSendString("play BGM", 0, 0, 0);
	//初始化蛇
	snack.n = 3;
	snack.ch = right;
	snack.szb[0].x = 100;
	snack.szb[0].y = 100;
	snack.szb[1].x = 90;
	snack.szb[1].y = 100;
	snack.szb[2].x = 80;
	snack.szb[2].y = 100;
	/*
	snack.szb[0].x = 20;
	snack.szb[0].y = 0;
	snack.szb[1].x = 10;
	snack.szb[1].y = 0;
	snack.szb[2].x = 0;
	snack.szb[2].y = 0;
	*/
}

void DrawSnack() {
	setlinecolor(GREEN);//线条的颜色
	setfillcolor(BLUE);//填充的颜色

	//遍历数组的方式,去访问数组中每一个元素的值,绘制出每一个元素所对应的矩形
	for (int i = 0;i < snack.n;i++) {
		fillrectangle(snack.szb[i].x, snack.szb[i].y,
			snack.szb[i].x + 10, snack.szb[i].y + 10);
	}

}

void MoveSnack() {
	for (int i = snack.n - 1;i > 0;i--) {
		snack.szb[i].x = snack.szb[i - 1].x;
		snack.szb[i].y = snack.szb[i - 1].y;
	}

	switch (snack.ch) {
	case up:
		snack.szb[0].y -= 10;
		break;
	case down:
		snack.szb[0].y += 10;
		break;
	case left:
		snack.szb[0].x -= 10;
		break;
	case right:
		snack.szb[0].x += 10;
		break;
	}
}

void ChangeSnackCh() {
	move = _getch();
	switch (move) 
	{
	case up:
		if (snack.ch != down)
			snack.ch = up;
		break;
	case down:
		if (snack.ch != up)
			snack.ch = down;
		break;
	case left:
		if (snack.ch != right)
			snack.ch = left;
		break;
	case right:
		if (snack.ch != left)
			snack.ch = right;
		break;
	}
}

void CoorFood() {
	food.fzb.x = rand() % 64 * 10;
	food.fzb.y = rand() % 48 * 10;

	food.flag = 1;
}

void DrawFood() {
	fillroundrect(food.fzb.x, food.fzb.y, food.fzb.x + 10, food.fzb.y + 10,10,10);
}

void EatFood() {
	if (snack.szb[0].x == food.fzb.x&&snack.szb[0].y == food.fzb.y) {
		snack.n++;
		food.flag = 0;
	}
	else if (snack.szb[0].x == 0 || snack.szb[0].x + 10 == 640 || snack.szb[0].y == 0 || snack.szb[0].y + 10 == 480) {
		outtextxy(150, 240, "Against the wall,Game Over!");
		system("pause");
		exit(0);
	}
	for (int i = 3;i < snack.n;i++) {
		if ((snack.szb[0].y == snack.szb[i].y + 10 && snack.szb[0].x == snack.szb[i].x&&snack.ch == down) || (snack.szb[0].y == snack.szb[i].y + 10 && snack.szb[0].x == snack.szb[i].x&& snack.ch == up) || (snack.szb[0].x == snack.szb[i].x + 10 && snack.szb[0].y == snack.szb[i].y&& snack.ch == right) || (snack.szb[0].x == snack.szb[i].x + 10 && snack.szb[0].y == snack.szb[i].y&& snack.ch == left)) {
			outtextxy(150, 240, "Bite into your own body,Game Over!");
			system("pause");
			exit(0);
		}
	}
	 
}

void ExitSystem() {
	switch (move) {
	case backspase:
		//按空格键暂停,按非空格键继续!
		outtextxy(150, 240, "Pause, press any key to continue!");
		_getch();
		break;
	case esc:
		outtextxy(150, 240, "Exit System,thanks you play!");
		system("pause");
		exit(0);
	}
}

PS:这是贪吃蛇的基础版本,可变的是实现的效果,不变的是实现的思维

        理解代码最好的方法就是多敲几遍,并且理解敲的代码有何作用

另外,今天了解到正点原子要出Linux系列的开发板了,很期待!!!!

你可能感兴趣的:(C/C++,开发手记,C语言练习题)