HTML5游戏_基于DOM平台跳跃小游戏开发_11.玩家精灵碰撞

HTML5游戏_基于DOM平台跳跃小游戏开发

玩家精灵碰撞

  • 效果图
    在这里插入图片描述
  • 本章新内容
  • filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
var 年龄数组 = [32, 33, 12, 40];
var 大于三十的年龄数组 = 年龄数组.filter
(
	function(年龄)
	{
		return 年龄 > 30;
	}
);
//大于三十的年龄数组 [32,33,40]
  • **some()**方法用于检测数组中的元素是否满足指定条件,some()方法会依次执行数组的每个元素,并返回布尔值
var 年龄数组 = [32, 33, 12, 40];
var 是否有等于四十岁的年龄 = 年龄数组.some
(
	funtion(年龄)
	{
		return 年龄 === 40;
	}
);
//是否有等于四十岁的年龄 true


  • 我们先来修改 生成地图数据.js 在生成地图数据函数里添加玩家和状态属性,然后再添加 玩家精灵碰撞 方法和 判断精灵碰撞 方法

生成地图数据.js

/**
 *@描述:	生成地图数据 函数
 *@传参:	地图 (地图数组的一项,如 地图数组[0] )
 *@参数:	宽,高,元素数组,精灵数组,玩家,状态
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/02/24
 *@修改人和其它信息:
**/
function 生成地图数据(地图)
{
	//定义属性 宽 为地图[]数组的长度
	this.= 地图[0].length;
	//定义属性 高 为地图数组的长度
	this.= 地图.length;
	//定义属性 元素数组 用来存放游戏里每个元素对应地图数据中的元素类型
	this.元素数组 = [];
	//定义 精灵数组 用来存放游戏里对应地图数据中的精灵
	this.精灵数组 = [];
	//遍历地图数组,识别地图元素
	for (var y = 0; y < this.; y++) 
	{
		//定义变量 行 来存放地图里一行的数据
		const= 地图[y];
		//定义数组 元素行 来存放解析地图一行数据后的元素类型
		let 元素行 = [];
		//遍历一行地图数据
		for (var x = 0; x < this.; x++) 
		{
			//定义变量 元素 来存 行[] 里的数据
			const 元素 =[x];
			//定义变量 元素类型 来存解析后的元素类型
			let 元素类型 = null;
			//定义变量 精灵内容 来保存在精灵集合对象中找出元素对应的属性
			const 精灵内容 = 精灵集合[元素];
			//判断元素
			if (精灵内容)
			{
				//如果是精灵集合中元素,添加到精灵数组
				this.精灵数组.push(new 精灵内容(new 矢量(x, y), 元素));
			}
			else if (元素 === "x")
			{
				元素类型 = "墙体";
			}
			else if (元素 === "@")
			{
				元素类型 = "玩家";
			}
			else if (元素 === "!")
			{
				元素类型 = "熔岩";
			}
			//将元素类型添加到元素行
			元素行.push(元素类型)
		}
		//将一行数据添加到元素数组
		this.元素数组.push(元素行);
	}
	//filter() 方法会创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
	this.玩家 = this.精灵数组.filter
	(
		function(精灵) 
		{
			return 精灵.类型 === "玩家"
		}
	)[0];
	//游戏状态,null表示没有结束,成功表示游戏胜利,失败表示游戏失败
	this.状态 = null;
}
/**
 *@描述:	生成地图数据 添加 动画 方法
 *@传参:	每帧执行时间(每帧执行时间)
 *@参数:
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/02/24
 *@修改人和其它信息:
**/
生成地图数据.prototype.动画 = function(每帧执行时间, 按键内容) 
{
	//定义变量 最大每帧执行时间=0.05
	const 最大每帧执行时间 = 0.05;
	//循环查看是否需要补帧动画
	while (每帧执行时间 > 0) 
	{
		//定义变量 当前帧执行时间 如果每帧执行时间大于最大每帧执行时间则取最大每帧执行时间0.05,即秒20帧
		const 当前帧执行时间 = Math.min(每帧执行时间, 最大每帧执行时间);
		//循环遍历 精灵数组
		this.精灵数组.forEach(function(精灵) 
		{
			//依次执行精灵.行为方法
			精灵.行为(当前帧执行时间, this, 按键内容);
		}, this);
		//结合循环条件查看是否需要补帧动画
		每帧执行时间 -= 当前帧执行时间;
	}
};
/**
 *@描述:	生成地图数据 添加 判断障碍物 方法
 *@传参:	坐标 大小
 *@参数:
 *@返回值:	元素类型
 *@创建人:	王天宇
 *@创建时间:2021/03/01
 *@修改人和其它信息:
**/
生成地图数据.prototype.判断障碍物 = function(坐标, 大小) 
{
	//定义区域大小
	//x起始位置
	const x起始位置 = Math.floor(坐标.x);
	//x结束位置 坐标x+大小矢量的x
	const x结束位置 = Math.ceil(坐标.x + 大小.x);
	//y起始位置
	const y起始位置 = Math.floor(坐标.y);
	//y结束位置 坐标y+大小矢量的y
	const y结束位置 = Math.ceil(坐标.y + 大小.y);
	//判断区域是否在地图的左右上边界
	if (x起始位置 < 0 || x结束位置 > this.|| y起始位置 < 0)
	{
		return "墙体";
	}
	//判断区域是否在下边界
	if (y结束位置 > this.)
	{
		return "熔岩";
	}
	//判断区域内是否有障碍物
	for (let y = y起始位置; y < y结束位置; y++) 
	{
		for (let x = x起始位置; x < x结束位置; x++) 
		{
			const 元素类型 = this.元素数组[y][x];
			//判断元素类型 是否有值
			if (元素类型) 
			{
				return 元素类型;
			}	
		}
	}
};
/**
 *@描述:	生成地图数据 添加 玩家精灵碰撞 方法
 *@传参:	碰撞精灵类型, 碰撞精灵
 *@参数:	
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/05
 *@修改人和其它信息:
**/
生成地图数据.prototype.玩家精灵碰撞 = function(碰撞精灵类型, 碰撞精灵) 
{
	//判断碰撞精灵类型如果是熔岩同时状态为null
	if (碰撞精灵类型 == "熔岩" && this.状态 == null) 
	{
		//定义状态为失败
		this.状态 = "失败";
	} 
	//判断碰撞精灵类型是金币
	else if (碰撞精灵类型 == "金币") 
	{
		//将碰撞的金币精灵从精灵数组中删除
		this.精灵数组 = this.精灵数组.filter(function(其他精灵) 
		{
			return 其他精灵 != 碰撞精灵;
		});
		//判断精灵数组中是否还有金币精灵
		if (!this.精灵数组.some(
			function(碰撞精灵) 
			{
				return 碰撞精灵.类型 == "金币";
			})) 
		{
			//没有金币精灵 设定状态为成功
			this.状态 = "成功";
		}
	}
};
/**
 *@描述:	生成地图数据 添加 判断精灵碰撞 方法
 *@传参:	精灵
 *@参数:	
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/05
 *@修改人和其它信息:
**/
生成地图数据.prototype.判断精灵碰撞 = function(精灵) 
{
	//依次判断精灵与其他精灵是否发生碰撞
	for (var i = 0; i < this.精灵数组.length; i++) 
	{
		const 其他精灵 = this.精灵数组[i];
		//判断精灵坐标与大小是否与精灵有碰撞
		if (其他精灵 != 精灵 &&
			精灵.坐标.x + 精灵.大小.x > 其他精灵.坐标.x &&
			精灵.坐标.x < 其他精灵.坐标.x + 其他精灵.大小.x &&
			精灵.坐标.y + 精灵.大小.y > 其他精灵.坐标.y &&
			精灵.坐标.y < 其他精灵.坐标.y + 其他精灵.大小.y)
		{
			return 其他精灵;
		}	
	}
};
  • 修改 精灵.js 补充 玩家精灵的 行为 方法,玩家精灵的 x/y方向移动 方法中关于精灵碰撞的部分
//定义全局对象 精灵集合
var 精灵集合 = 
{
	"@": 玩家精灵,
	"o": 金币精灵,
	"=": 熔岩精灵,
	"v": 熔岩精灵,
	"|": 熔岩精灵
};
//定义全局变量 玩家移动速度
var 玩家移动速度 = 10;
//定义全局变量 玩家跳跃速度
var 玩家跳跃速度 = 14;
//定义全局变量 重力
var 重力 = 30;

/**
 *@描述:	玩家精灵 函数
 *@传参:	坐标 (矢量)
 *@参数:	坐标,大小,速度矢量,类型
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/04
 *@修改人和其它信息:
**/
function 玩家精灵(坐标) 
{
	this.类型 = "玩家";
	this.坐标 = 坐标;
	this.大小 = new 矢量(0.5, 1);
	this.速度矢量 = new 矢量(0, 0);
}
/**
 *@描述:	玩家精灵 添加 行为 方法
 *@传参:	每帧执行时间, 生成地图数据, 按键内容
 *@参数:	
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/04
 *@修改人和其它信息:
**/
玩家精灵.prototype.行为 = function(每帧执行时间, 生成地图数据, 按键内容)
{
	this.x方向移动(每帧执行时间, 生成地图数据, 按键内容);
	this.y方向移动(每帧执行时间, 生成地图数据, 按键内容);
	const 碰撞精灵 = 生成地图数据.判断精灵碰撞(this);
	if (碰撞精灵)
	{
		document.getElementById("碰撞").innerHTML = "碰撞精灵:" + 碰撞精灵.类型;
		生成地图数据.玩家精灵碰撞(碰撞精灵.类型, 碰撞精灵);
	}
	else
	{
		document.getElementById("碰撞").innerHTML = "碰撞精灵:";
	}
};
/**
 *@描述:	玩家精灵 添加 x方向移动 方法
 *@传参:	每帧执行时间, 生成地图数据, 按键内容
 *@参数:	新坐标,障碍物
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/04
 *@修改人和其它信息:
**/
玩家精灵.prototype.x方向移动 = function(每帧执行时间, 生成地图数据, 按键内容)
{
	//给 速度矢量.x 赋值0
	this.速度矢量.x = 0;
	//判断按键内容
	if (按键内容.) 
	{
		this.速度矢量.x -= 玩家移动速度;
	}
	if (按键内容.)
	{
		this.速度矢量.x += 玩家移动速度;
	}
	//定义定量 新坐标
	const 新坐标 = this.坐标.偏移(new 矢量(this.速度矢量.x * 每帧执行时间, 0));
	//定义定量 障碍物
	const 障碍物 = 生成地图数据.判断障碍物(新坐标, this.大小);
	//判断有没有障碍物
	if(障碍物)
	{
		//有障碍物
		生成地图数据.玩家精灵碰撞(障碍物);
	}
	else
	{
		this.坐标 = 新坐标;
	}	
};
/**
 *@描述:	玩家精灵 添加 y方向移动 方法
 *@传参:	每帧执行时间, 生成地图数据, 按键内容
 *@参数:	新坐标,障碍物
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/04
 *@修改人和其它信息:
**/
玩家精灵.prototype.y方向移动 = function(每帧执行时间, 生成地图数据, 按键内容) 
{
	//给 速度矢量.y 每帧执行时间 * 重力
	this.速度矢量.y += 每帧执行时间 * 重力;
	//定义定量 新坐标
	const 新坐标 = this.坐标.偏移(new 矢量(0, this.速度矢量.y * 每帧执行时间));
	//定义定量 障碍物
	const 障碍物 = 生成地图数据.判断障碍物(新坐标, this.大小);
	//判断有没有障碍物
	if(障碍物)
	{
		生成地图数据.玩家精灵碰撞(障碍物);
		//下方有障碍物
		if (按键内容.&& this.速度矢量.y > 0)
		{
			//如果按上键,给玩家速度矢量.y一个向上的速度
			this.速度矢量.y = -玩家跳跃速度;	
		}
		else
		{
			//定义速度矢量.y=0
			this.速度矢量.y = 0;	
		}
	}
	else
	{
		//无障碍物
		if (按键内容.&& this.速度矢量.y > 0)
		{
			//如果按下键,给玩家速度矢量.y一个向下的速度
			this.速度矢量.y += 每帧执行时间 * 重力 * 2;
		}
		this.坐标 = 新坐标;
	}
};

/**
 *@描述:	熔岩精灵 函数
 *@传参:	坐标 (矢量)
 *@参数:	初始坐标,坐标,大小,速度矢量,类型
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/01
 *@修改人和其它信息:
**/
function 熔岩精灵(坐标, 元素) 
{
	//定义属性 类型
	this.类型 = "熔岩";
	//定义属性 初始坐标
	this.坐标 = 坐标;
	//定义大小
	this.大小 = new 矢量(1, 1);
	//根据元素来定义速度矢量属性 在x,y上的移动速度
	if(元素 === "=")
	{
		//= 是横向移动熔岩,所以x有速度y没有
		this.速度矢量 = new 矢量(2, 0);
	}
	else if(元素 === "|")
	{
		//| 是横向移动熔岩,所以y有速度x没有
		this.速度矢量 = new 矢量(0, 2);
	}
	else if(元素 === "v")
	{
		//v 是掉落熔岩,所以y有速度x没有
		this.速度矢量 = new 矢量(0, 3);
		this.初始坐标 = 坐标;
	}
}
/**
 *@描述:	熔岩精灵 添加 行为 方法
 *@传参:	每帧执行时间, 生成地图数据
 *@参数:	
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/03/01
 *@修改人和其它信息:
**/
熔岩精灵.prototype.行为 = function(每帧执行时间, 生成地图数据)
{
	//熔岩精灵偏移后的新坐标
	const 新坐标 = this.坐标.偏移(this.速度矢量.矢积(每帧执行时间));
	//判断熔岩精灵偏移后的新坐标是否有障碍物
	if (!生成地图数据.判断障碍物(新坐标, this.大小))
	{
		//新坐标区域内没有障碍元素,熔岩可以移动
		//将新坐 付给 坐标
		this.坐标 = 新坐标;
	}
	//有障碍物 回到初始坐标
	else if (this.初始坐标)
	{
		this.坐标 = this.初始坐标;
	}
	//有障碍物 反向运动
	else
	{
		this.速度矢量 = this.速度矢量.矢积(-1);
	}
};
/**
 *@描述:	金币精灵 函数
 *@传参:	坐标 (矢量)
 *@参数:	初始坐标,大小,晃动值,类型
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/02/24
 *@修改人和其它信息:
**/
function 金币精灵(坐标) 
{
	//定义属性 类型
	this.类型 = "金币";
	//定义属性 初始坐标
	this.初始坐标 = this.坐标 = 坐标;
	//定义大小 因为游戏场景中每格大小为15*15
	this.大小 = new 矢量(0.7, 0.7);
	//定义属性 晃动值 初始的晃动系数
	/*
		PI是180°,PI*2=360° 随机数(0~1)*PI*2 就是在0°~360°中随机取一个角度
		范围即0*3.1415*2 ~ 0.9999*3.1415*2
	*/
	this.晃动值 = Math.random() * Math.PI * 2;
}
/**
 *@描述:	金币精灵 添加 行为 方法
 *@传参:	每帧执行时间 (每帧执行时间)
 *@参数:	晃动速度,晃动区域,晃动坐标y
 *@返回值:	无
 *@创建人:	王天宇
 *@创建时间:2021/02/24
 *@修改人和其它信息:
**/
金币精灵.prototype.行为 = function(每帧执行时间) 
{
	//定义定量 晃动速度
	const 晃动速度 = 8;
	//定义定量 晃动区域
	const 晃动区域 = 0.07;
	//晃动值自加 每帧执行时间*晃动速度=每帧移动距离
	this.晃动值 += 每帧执行时间 * 晃动速度;
	//定义定量 晃动坐标y
	const 晃动坐标y = Math.sin(this.晃动值) * 晃动区域;
	//设置坐标偏移后的值
	this.坐标 = this.初始坐标.偏移(new 矢量(0, 晃动坐标y));
};
  • 最后再html页面里面加一个h3标签来显示碰撞信息

html页面

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>html跳跃小游戏</title>
		<!--CSS样式-->
		<link rel="stylesheet" type="text/css" href="./css/css样式.css">
	</head>
	<body>
		<h5 id="fps" style="color: #ffffff;">FPS=0</h5>
		<h5 id="碰撞" style="color: #ffffff;">碰撞精灵:</h5>
		<!--pre标签可定义预格式化的文本-->
		<pre id="按键监听测试" style="color: #ffffff;"></pre>
		<!--JS脚本-->
		<script type="text/javascript" src="./js/精灵.js"></script>
		<script type="text/javascript" src="./js/地图数组.js"></script>
		<script type="text/javascript" src="./js/工具函数.js"></script>
		<script type="text/javascript" src="./js/按键监听.js"></script>
		<script type="text/javascript" src="./js/生成地图数据.js"></script>
		<script type="text/javascript" src="./js/生成关卡.js"></script>
		<script type="text/javascript" src="./js/运行帧动画.js"></script>
		<script>
		//初始化程序
		function 初始化()
		{
			//开始第一个关卡
			开始关卡(0);
		}
		function 开始关卡(n) 
		{
			//生成地图数据
			var 新地图数据 = new 生成地图数据(地图数组[n]);
			//生成关卡
			var 新关卡 = new 生成关卡(document.body, 新地图数据);
			//运行帧动画
			运行帧动画(function(每帧执行时间) 
			{
				/*这个方法是游戏里每帧运行的所有内容,包括动画/判断碰撞/按键监听等*/
				//播放关卡地图里精灵一帧动画动作
				新地图数据.动画(每帧执行时间, 按键内容);
				//重新绘制一帧关卡
				新关卡.画精灵层();
				//计算每秒帧数
				document.getElementById("fps").innerHTML = "FPS=" + (1 / 每帧执行时间).toFixed(2);
				//每帧显示按键信息,&#9代表tab制表符
				document.getElementById("按键监听测试").innerHTML = 
					"按键左=" + (按键内容.=== true) + 
					"&#9按键右=" + (按键内容.=== true) + 
					"&#9按键上=" + (按键内容.=== true) +
					"&#9按键下=" + (按键内容.=== true);
				//执行每帧动作方法 返回false时结束运行帧动画, 返回其他则继续执行动画
				return true;
			});
		}
		初始化();
		</script>
	</body>
</html>
  • 效果图
    在这里插入图片描述
阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱玎科技首席执行官

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

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

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

打赏作者

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

抵扣说明:

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

余额充值