【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(二)

终于忙完这段时间的项目、考证了,接下来将继续填之前的坑了。

书接上回【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(一)

本次将使得角色和AI动起来,实现键盘控制,同时使得AI可以动起来以及一些细节补充

一.角色控制

        控制角色可以使用GetAsyncKeyState([in] int vKey)函数实时检测哪个按键被按下,具体的虚拟键码(部分)如下:

        本次讲使用ASDW键来控制角色移动,具体代码如下:

int playerSpeedCol = 0; 
int playerSpeedRow = 0;
int player_speed = 5; //角色移动速度

if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x41))
	{
		playerSpeedCol = -player_speed;
		playerSpeedRow = -player_speed;
	}
	//上右
	else if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x44))
	{
		playerSpeedCol = -player_speed;
		playerSpeedRow = player_speed;
	}
	//下右
	else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x44))
	{
		playerSpeedCol = player_speed;
		playerSpeedRow = player_speed;
	}
	//下左
	else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x41))
	{
		playerSpeedCol = player_speed;
		playerSpeedRow = -player_speed;
	}
	//左
	else if (GetAsyncKeyState(0x41))
	{
		playerSpeedRow = -player_speed;
		playerSpeedCol = 0;
	}
	//下
	else if (GetAsyncKeyState(83))
	{
		playerSpeedCol = player_speed;
		playerSpeedRow = 0;
	}
	//右
	else if (GetAsyncKeyState(0x44))
	{
		playerSpeedRow = player_speed;
		playerSpeedCol = 0;
	}
	//上
	else if (GetAsyncKeyState(0x57))
	{
		playerSpeedCol = -player_speed;
		playerSpeedRow = 0;
	}
	else
	{
		if (playerSpeedRow > 0)
			playerSpeedRow = player_speed;
		if (playerSpeedCol > 0)
			playerSpeedCol = player_speed;
		if (playerSpeedRow < 0)
			playerSpeedRow = -player_speed;
		if (playerSpeedCol < 0)
			playerSpeedCol = -player_speed;
	}

        根据按下的实际按键确定角色的移动方向,将值更新到角色的实例结构体中:

	//赋值处理
	int playerbody_x = player.x;
	int playerbody_y = player.y;
	player.x += playerSpeedRow;
	player.y += playerSpeedCol;

        最后就是尾部的处理,确保角色的头部在进行移动的时候,它的尾部也可以随时跟在身后:

	//尾部处理
	int x = player_body[0].x; //该变量在上一篇文章有定义,定义的是尾部的长度
	int y = player_body[0].y; //该变量在上一篇文章有定义,定义的是尾部的长度
	player_body[0].x = playerbody_x;
	player_body[0].y = playerbody_y;
	for (int i = 1; i < body_num; i++)
	{
		int a = 0, b = 0;
		if (i % 2 == 1)
		{
			a = player_body[i].x;
			b = player_body[i].y;
			player_body[i].x = x;
			player_body[i].y = y;
		}
		else
		{
			x = player_body[i].x;
			y = player_body[i].y;
			player_body[i].x = a;
			player_body[i].y = b;
		}
	}

二.AI自主移动

        AI移动的原理其实和角色的移动原理差不多,区别就在于需要使用一个随机函数来让AI自行随机移动,等到检测到角色靠近之后会自己主动逃避。首先是AI的随机移动:

int AiSpeedCol[Ai_num] = { 0 };
int AiSpeedRow[Ai_num] = { 0 };

srand((unsigned)time(NULL));
int count[Ai_num] = { 0 };

for (int i = 0; i < Ai_num; i++)
{
		count[i] = rand() % 8;
		
		if (count[i] == 0)
		{
			AiSpeedCol[i] = -player_speed;
			AiSpeedRow[i] = -player_speed;
		}
		
		else if (count[i] == 1)
		{
			AiSpeedCol[i] = -player_speed;
			AiSpeedRow[i] = player_speed;
		}
		
		else if (count[i] == 2)
		{
			AiSpeedCol[i] = player_speed;
			AiSpeedRow[i] = player_speed;
		}
		
		else if (count[i] == 3)
		{
			AiSpeedCol[i] = player_speed;
			AiSpeedRow[i] = -player_speed;
		}
		
		else if (count[i] == 4)
		{
			AiSpeedRow[i] = -player_speed;
			AiSpeedCol[i] = 0;
		}
		
		else if (count[i] == 5)
		{
			AiSpeedCol[i] = player_speed;
			AiSpeedRow[i] = 0;
		}
		
		else if (count[i] == 6)
		{
			AiSpeedRow[i] = player_speed;
			AiSpeedCol[i] = 0;
		}
		
		else if (count[i] == 7)
		{
			AiSpeedCol[i] = -player_speed;
			AiSpeedRow[i] = 0;
		}
		
		if (Ai[i].x >= map_wide - player_speed)
		{
			AiSpeedRow[i] = -player_speed;
		}
		else if (Ai[i].y >= map_hight - player_speed)
		{
			AiSpeedCol[i] = -player_speed;
		}
		else if (Ai[i].y <= player_speed)
		{
			AiSpeedCol[i] = player_speed;
		}
		else if (Ai[i].x <= player_speed)
		{
			AiSpeedRow[i] = player_speed;
		}
		
		for (int j = 0; j < body_num; j++)
		{
			if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20)
			{
				
				if (Ai[i].x < player_body[j].x)
				{
					AiSpeedRow[i] = -player_speed;
				}
				
				if (Ai[i].y < player_body[j].y)
				{
					AiSpeedCol[i] = -player_speed;
				}
				
				if (Ai[i].x > player_body[j].x)
				{
					AiSpeedCol[i] = player_speed;
				}
				
				if (Ai[i].y > player_body[j].y)
				{
					AiSpeedRow[i] = player_speed;
				}
			}
		}
		
		int m = Ai[i].x;
		int n = Ai[i].y;
		Ai[i].x += AiSpeedRow[i];
		Ai[i].y += AiSpeedCol[i];
		int x = Ai_body[i][0].x;
		int y = Ai_body[i][0].y;
		Ai_body[i][0].x = m;
		Ai_body[i][0].y = n;
		for (int j = 1; j < Ai_body_num[i]; j++)
		{
			int a = 0, b = 0;
			if (j % 2 == 1)
			{
				a = Ai_body[i][j].x;
				b = Ai_body[i][j].y;
				Ai_body[i][j].x = x;
				Ai_body[i][j].y = y;
			}
			else
			{
				x = Ai_body[i][j].x;
				y = Ai_body[i][j].y;
				Ai_body[i][j].x = a;
				Ai_body[i][j].y = b;
			}
		}
	}

        这里需要注意的是AI会实时检测与角色的距离,角色靠的过近之后会自动原理:

int Distance(int x, int y, int x1, int y1)
{
	return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}

for (int j = 0; j < body_num; j++)
{
	if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20)
	{
				
				if (Ai[i].x < player_body[j].x)
				{
					AiSpeedRow[i] = -player_speed;
				}
				
				if (Ai[i].y < player_body[j].y)
				{
					AiSpeedCol[i] = -player_speed;
				}
				
				if (Ai[i].x > player_body[j].x)
				{
					AiSpeedCol[i] = player_speed;
				}
				
				if (Ai[i].y > player_body[j].y)
				{
					AiSpeedRow[i] = player_speed;
				}
	}
}

        以下是运行图:

        在下一篇最后的文章中,将完成AI吃食物、角色吃AI等操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919737.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【UE5】使用基元数据对材质传参,从而避免新建材质实例

在项目中&#xff0c;经常会遇到这样的需求&#xff1a;多个模型&#xff08;例如 100 个&#xff09;使用相同的材质&#xff0c;但每个模型需要不同的参数设置&#xff0c;比如不同的颜色或随机种子等。 在这种情况下&#xff0c;创建 100 个实例材质不是最佳选择。正确的做…

Python-简单病毒程序合集(一)

前言&#xff1a;简单又有趣的Python恶搞代码&#xff0c;往往能给我们枯燥无味的生活带来一点乐趣&#xff0c;激发我们对编程的最原始的热爱。那么话不多说&#xff0c;我们直接开始今天的编程之路。 编程思路&#xff1a;本次我们将会用到os,paltform,threading,ctypes,sys,…

初级数据结构——串

目录 前言一、串的定义二、串的存储结构三、串的基本操作四、串的模式匹配五、串的应用六、c代码模版七、经典例题1.汉字统计代码题解 2.查找最大元素代码题解 3.首字母变大写代码题解 八、总结结语 前言 这期我们一起深入学习初级数据结构——串&#xff0c;数据结构中的串&a…

【K8S系列】Kubernetes Pod节点ImagePullBackOff 状态及解决方案详解【已解决】

在 Kubernetes 中&#xff0c;当某个 Pod 的容器无法从指定的镜像仓库拉取镜像时&#xff0c;Pod 的状态会变为 ImagePullBackOff。这通常是因为指定的镜像不存在、镜像标签错误、认证失败或网络问题等原因。 以下是关于 ImagePullBackOff 的详细分析及解决方案。 1. ImagePull…

CSS3新特性——字体图标、2D、3D变换、过渡、动画、多列布局

目录 一、Web字体 二、字体图标 三、2D变换 1.位移 &#xff08;1&#xff09;浮动 &#xff08;2&#xff09;相对定位 &#xff08;3)绝对定位和固定定位 &#xff08;4&#xff09;位移 用位移实现盒子的水平垂直居中 2.缩放 利用缩放调整字体到12px以下&#xff…

前端项目规范~

前言 项目一般都是几个开发一起迭代升级&#xff0c;那肯定存在各种代码风格、格式化以及命名等等&#xff0c;懂得都懂&#x1f4a9;&#xff0c;所以项目规范就凸显出来了呀&#xff0c;以下主要是介绍工具自动化使用~ husky 安装husky pnpm add --save-dev husky .husk…

【编译器】Dev C++建立C语言工程

【编译器】Dev C建立C语言工程 文章目录 [TOC](文章目录) 前言一、创建工程二、添加.c.h三、主函数处理四、在桌面中打开exe文件五、参考资料总结 前言 在使用了很多编译器之后&#xff0c; 要么是太大了&#xff0c; 要么是太新了&#xff0c; 要么是在线编译器&#xff0c;用…

CHIMA网络安全攻防大赛经验分享

比赛模式 第一轮&#xff1a;20分钟基础知识赛&#xff08;50道题&#xff09; 安全运维&#xff0c;法律法规&#xff0c;linux操作系统等 第二轮&#xff1a;50分钟CTF夺旗&#xff08;5道题&#xff09; 题目涵盖 密码学 运用多种工具&#xff0c;如ASCII对照&#xff0c…

基于yolov8、yolov5的植物类别识别系统(含UI界面、训练好的模型、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8、yolov8 SE注意力机制 或 yolov5、yolov5 SE注意力机制 &#xff0c; 直接提供最少两个训练好的模型。模型十分重要&#xff0c;因为有些同学的电脑没有 GPU&#xff0…

JavaWeb开发10

多表设计 一对多 关系实现&#xff1a;在数据库表中多的一方添加字段来关联一的一方的主键 外键约束 一对一 关系&#xff1a;一对一关系&#xff0c;多用于单表拆分&#xff0c;将一张表的基础字段放在一张表中&#xff0c;其他字段放在另一张表中&#xff0c;以提高操作…

leetcode-12-整数转罗马数字

题解&#xff1a; 1、初始化字典&#xff1a; 2、 代码&#xff1a;

Seatunnel解决Excel中无法将数字类型转换成字符串类型以及源码打包

需求 需要实现将Excel中的数字类型的单元格像数据库中字符串类型的字段中推送 问题原因 Seatunnel在读取字段类型的时候都是使用强转的形式去获取数据的 假如说数据类型不一样的话直接强转就会报错 修改位置 org/apache/seatunnel/api/table/type/SeaTunnelRow.java org…

Keil基于ARM Compiler 5的工程迁移为ARM Compiler 6的工程

环境&#xff1a; keil版本为5.38&#xff0c;版本务必高于5.30 STM32F4的pack包版本要高于2.9 软件包下载地址&#xff1a;https://zhuanlan.zhihu.com/p/262507061 一、更改Keil中编译器 更改后编译&#xff0c;会报很多错&#xff0c;先不管。 二、更改头文件依赖 观察…

JeecgBoot 与分布式事务 Seata v1.7.0 集成实战

准备环境 一、创建四个数据库&#xff0c;如下 jeecg_order&#xff08;订单数据库&#xff09; jeecg_account&#xff08;账户数据库&#xff09; jeecg_product&#xff08;商品数据库&#xff09; seata&#xff08;seata数据库&#xff09;以上数据库脚本已存放至 jeecg…

鸿蒙动画开发07——粒子动画

1、概 述 粒子动画是在一定范围内随机生成的大量粒子产生运动而组成的动画。 动画元素是一个个粒子&#xff0c;这些粒子可以是圆点、图片。我们可以通过对粒子在颜色、透明度、大小、速度、加速度、自旋角度等维度变化做动画&#xff0c;来营造一种氛围感&#xff0c;比如下…

MAC创建一个自动操作,启动系统【睡眠】功能,并将绑定快捷键

目的 通过 Automator 创建一个服务来启动系统【睡眠】这个功能&#xff0c;并绑定快捷键。 步骤一&#xff1a;创建 Automator 服务 打开 Automator&#xff1a; ○ 在 Spotlight 中搜索 Automator&#xff0c;然后打开。选择服务类型&#xff1a; ○ 在 Automator 的启动界…

基于AIRTEST和Jmeter、Postman的自动化测试框架

基于目前项目和团队技术升级&#xff0c;采用了UI自动化和接口自动化联动数据&#xff0c;进行相关测试活动&#xff0c;获得更好的测试质量和测试结果。

HarmonyOS4+NEXT星河版入门与项目实战------Button组件

文章目录 1、控件图解2、案例实现1、代码实现2、代码解释3、运行效果4、总结1、控件图解 这里我们用一张完整的图来汇整 Button 的用法格式、属性和事件,如下所示: 按钮默认类型就是胶囊类型。 2、案例实现 这里我们实现一个根据放大和缩小按钮来改变图片大小的功能。 功…

5、深入剖析PyTorch DataLoader源码

文章目录 1. 重要类2. DataSet3. DataLoader4. Python实例 参考大神B站&#xff0c;记录学习笔记 5、深入剖析PyTorch DataLoader源码 其他大神笔记&#xff1a; pytorch数据操作—dataset&#xff0c;dataloader&#xff0c;transform 1. 重要类 Data LoaderDatasetSampleRa…

D74【 python 接口自动化学习】- python 基础之HTTP

day74 http基础定义 学习日期&#xff1a;20241120 学习目标&#xff1a;http定义及实战 -- http基础介绍 学习笔记&#xff1a; HTTP定义 HTTP 是一个协议&#xff08;服务器传输超文本到浏览器的传送协议&#xff09;&#xff0c;是基于 TCP/IP 通信协议来传递数据&…