cocos2d-js判断点是否在矩形内

本文介绍了一个 Vector2 类的实现细节,包括基本属性设置、常用向量操作方法如长度计算、标准化、加减乘除等,并展示了如何利用该类进行点与矩形碰撞检测的应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// Vector2.js
"use strict"

var Vector2 = function(x, y) {
	this.x = x;
	this.y = y;
};
Vector2.prototype.constructor = Vector2;

Vector2.prototype = {
	copy : function() {
		return new Vector2(this.x, this.y);
	},
	length : function() {
		return Math.sqrt(this.x * this.x + this.y * this.y);
	},
	sqrLength : function() {
		return this.x * this.x + this.y * this.y;
	},
	normalize : function() {
		var inv = 1 / this.length();
		return new Vector2(this.x * inv, this.y * inv);
	},
	negate : function() {
		return new Vector2(-this.x, -this.y);
	},
	add : function(v) {
		return new Vector2(this.x + v.x, this.y + v.y);
	},
	subtract : function(v) {
		return new Vector2(this.x - v.x, this.y - v.y);
	},
	multiply : function(f) {
		return new Vector2(this.x * f, this.y * f);
	},
	divide : function(f) {
		var invf = 1 / f;
		return new Vector2(this.x * invf, this.y * invf);
	},
	dot : function(v) {
		return this.x * v.x + this.y * v.y;
	},
	cross : function(v) {
		return this.x * v.y - this.y * v.x;
	}
};



dotInBox : function(sprite, tx, ty) {

		// 判断待检测的点是否在矩形范围内
		// 三个点p1, p2, p3
		// 向量v1 = (p2.x-p1.x, p2,y-p1.y) v2 = (p3.x - p1.x, p3.y - p1.y)
		// 
		// 运用向量的差乘的知识
		// s = v1 × v2 = v1.x * v2.y - v1.y * v2.x = |v1|*|v2|*sinθ
		// θ的角度是从v1旋转到v2的角度,根据这个角度的正负即可判断v2向量在v1的哪个方向,即可判断点p3是在线段p2p1的左边还是右边
		// 所以,
		// s > 0, 则p3在p2p1的左边
		// s < 0, 则p3在p2p1的右边
		// s == 0,则p3在p2p1上
		var pointList = this.getRect(sprite);
		var v3 = new Vector2(tx, ty);
		for(var i = 0, j = 3; i < 4; j = i++) {
			var p_x_1 = pointList[2 * i];
			var p_y_1 = pointList[2 * i + 1];
			var p_x_2 = pointList[2 * j];
			var p_y_2 = pointList[2 * j + 1];
			var v1 = new Vector2(p_x_1, p_y_1);
			var v2 = new Vector2(p_x_2, p_y_2);
			var s = v2.subtract(v1).cross(v3.subtract(v1));
			if(s > 0) {
				return false;
			}
		}
		return true;
	},

	getRect : function(sprite) {
		var box_width 	= sprite.getContentSize().width;
		var box_height 	= sprite.getContentSize().height;
		var x 			= sprite.getPositionX();
		var y 			= sprite.getPositionY();
		var degree 		= sprite.getRotation(); // 旋转的角度,cocos的0度角方向和笛卡尔坐标系y轴方向平行,而不是x轴方向 _|_,向右旋转为正,向左为负
		var angle 		= degree * 0.017453292519943295;	// 角度转弧度 0.017453292519943295 = (Math.PI / 180)
		box_width 		= box_width / 2;
		box_height 		= box_height / 2;

		var sint 	= Math.sin(angle);
		var cost 	= Math.cos(angle);
		var hot_x1 	= -box_width;
		var hot_y1 	= -box_height;
		var hot_x2 	= box_width;
		var hot_y2 	= box_height;

		// -->注意,cocos旋转角度的起始位置<--
		// 假设(x, y)和原点连线的角度为α,(x, y)和原点的距离r为1,这个点旋转β后的点为(x`, y`)
		// x = r * sinα = sinα
		// y = r * cosα = cosα
		// x` = r * sin(α + β) = sin(α + β) = sinαcosβ + cosαsinβ = xcosβ + ysinβ =  xcosβ + ysinβ
		// y` = r * cos(α + β) = cos(α + β) = cosαcosβ - sinαsinβ = ycosβ - xsinβ = -xsinβ + ycosβ
		// 转换成矩形形式
		// 		||
		// 		\/
		// | cost  sint |   | x |   | x` |
		// |		    | * |   | = |    |
		// |-sint  cost |   | y |   | y` |
		// 

		// 计算图片四个点旋转后的坐标
		var x1 = hot_x1 * cost + hot_y1 * sint + x;
		var y1 = -hot_x1 * sint + hot_y1 * cost + y;

		var x2 = hot_x2 * cost + hot_y1 * sint + x;
		var y2 = -hot_x2 * sint + hot_y1 * cost + y;

		var x3 = hot_x2 * cost + hot_y2 * sint + x;
		var y3 = -hot_x2 * sint + hot_y2 * cost + y;

		var x4 = hot_x1 * cost + hot_y2 * sint + x;
		var y4 = -hot_x1 * sint + hot_y2 * cost + y;

		return [x1, y1, x2, y2, x3, y3, x4, y4];
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

shangdibaozi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值