C++实现贪吃蛇

头文件function.h

#pragma once
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#define BLOCK_SIZE 20
#define HEIGHT 30
#define WIDTH 40
int blocks[HEIGHT][WIDTH] = { 0 };
int score = 0;//吃的食物数量,来控制速度
char moveDirection = 'd';//控制舍身运动方向;
int food_i, food_j;//食物的坐标
bool isfailure = false;//是否失败的标识符

void startup() {//初始化函数
	int i;
	blocks[HEIGHT / 2][WIDTH / 2] = 1;  //1代表蛇头,给地图最中心生成蛇头
	for (i = 1; i < 3; i++) {
		blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;
	}//在蛇头后面初始化一个长度为5的蛇身;


	srand(time(0));//给srand()时间种子,防止随机有规律有寻;
	food_i = rand() % (HEIGHT - 5) + 2;//初始化食物坐标
	food_j = rand() % (WIDTH - 5) + 2;
	initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE);//初始化窗体

	setlinecolor(RGB(50, 50, 50));//设置地图中每个方块的边界颜色
	BeginBatchDraw();//开始批量绘制,防止闪屏,与FlushBatchDraw()一起使用;
}
void show() {//绘制函数
	cleardevice();//清屏与绘画搭配使用,做到动画的效果;
	int i, j;
	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH; j++) {//整个地图遍历
			if (blocks[i][j] > 0) {
				setfillcolor(RGB(300, 50, 100));//蛇身的绘制,并用到HSVTORBG(),使蛇身颜色不一样;
			}
			else {
				setfillcolor(RGB(0, 0, 0));//绘制非蛇身的场景;
			}
			fillrectangle(j * BLOCK_SIZE, i * BLOCK_SIZE, (j + 1) * BLOCK_SIZE, (i + 1) * BLOCK_SIZE);//真正的绘制函数;

		}
	}
	setfillcolor(RGB(0, 255, 0));//设置食物颜色
	fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE, (food_j + 1) * BLOCK_SIZE, (food_i + 1) * BLOCK_SIZE);//在食物地址绘制食物;
	if (isfailure) {//如果游戏失败,绘制游戏失败标题;
		setbkmode(TRANSPARENT);
		settextcolor(RGB(255, 0, 0));
		settextstyle(80, 0, _T("宋体"));
		outtextxy(240, 220, _T("游戏失败"));
	}

	setbkmode(TRANSPARENT);
	settextcolor(RGB(255, 0, 0));
	settextstyle(20, 0, _T("宋体"));
	TCHAR s[20];
	swprintf_s(s, _T("Now Your Socre is:%d"), score);
	outtextxy(0, 0, s);

	FlushBatchDraw();//按从BeginBatchDraw()开始的绘制要求绘制
}
void moveSnake() {//控制蛇身动作反应的内在函数
	int i, j;
	for (i = 0; i < HEIGHT; i++) {//给所有的蛇身的数组加一
		for (j = 0; j < WIDTH; j++) {
			if (blocks[i][j] > 0) {
				blocks[i][j]++;
			}
		}
	}
	int oldtial_i, oldtial_j, oldHead_i, oldHead_j;
	int max = 0;
	for (i = 0; i < HEIGHT; i++) {
		for (j = 0; j < WIDTH; j++) {
			if (max < blocks[i][j]) {//数组中最大的一定是蛇尾,把旧蛇尾的坐标存起来;
				max = blocks[i][j];
				oldtial_i = i;
				oldtial_j = j;
			}
			if (blocks[i][j] == 2) {//因为蛇头1加了1,所以为2,借此得到蛇头的位置
				oldHead_i = i;
				oldHead_j = j;
			}
		}
	}

	int newHead_i = oldHead_i; //  设定变量存储新蛇头的位置
	int newHead_j = oldHead_j;
	if (moveDirection == 'w') {
		newHead_i = oldHead_i - 1;//向上新蛇头的位置应该是逻辑上老蛇头的Y坐标减1;
	}
	else if (moveDirection == 's') {
		newHead_i = oldHead_i + 1;//向下新蛇头的位置应该是逻辑上老蛇头的Y坐标加1;
	}
	else if (moveDirection == 'a') {
		newHead_j = oldHead_j - 1;//向左新蛇头的位置应该是逻辑上老蛇头的X坐标减1;
	}
	else if (moveDirection == 'd') {
		newHead_j = oldHead_j + 1;//向右新蛇头的位置应该是逻辑上老蛇头的X坐标加1;
	}


	if (newHead_i >= HEIGHT || newHead_i <= 0 || newHead_j >= WIDTH || newHead_j <= 0 || blocks[newHead_i][newHead_j] > 0) {//蛇头蛇尾出界,以及检查到新蛇头在蛇身上,也就是蛇咬到自己为游戏失败;
		isfailure = true;
		return;
	}
	blocks[newHead_i][newHead_j] = 1;//给新蛇头的位置赋值1;
	if (newHead_i == food_i && newHead_j == food_j) {//如果新蛇头位置在食物的地方,也就是蛇吃到了食物,并给食物重新给一个位置;
		food_i = rand() % (HEIGHT - 5) + 2;
		food_j = rand() % (WIDTH - 5) + 2;
		score++;//吃的次数加一;
	}
	else
		blocks[oldtial_i][oldtial_j] = 0;//如果没迟到食物,则尾部为0,就是逻辑上减一

}
void updateWithoutInput() {
	if (isfailure) {//游戏未失败继续
		return;
	}
	static int waitIndex = 1;
	waitIndex++;

	if (waitIndex == 10) {
		moveSnake();
		waitIndex = 1;//循环重新开始
	}
}
void updateWithInput() {
	if (_kbhit() && isfailure == 0) {//如果有输入,且未失败
		char input = _getch();
		if (input == 'a' || input == 's' || input == 'w' || input == 'd') {
			moveDirection = input;
			moveSnake();
		}
	}
}

cpp文件

#include "function.h"
int main()
{
	startup();//初始化;
	while (1) {//不断调用;
		show();
		updateWithoutInput();//更新与输入无关的参数;
		updateWithInput();//更新与输入有关的参数;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Grey.yschakk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值