在 CocosCreator 开发中,我们经常有限制位置的需求。对于长方形区域我们可以简单的判断 x y 方向的坐标,但是遇到六边形区域该怎么办呢?
我们先用 cc.graphics 组件绘制下限制区域。
(2.1.2 版本的绘图组件有个 Bug 只能以左下角为 0 0 ,现在 2.1.3 修复了。对本文章无影响。)
// 已声明 this.area = [] 绘图组件 this.g
onLoad () {
// 装入六边形点
this.area.push(cc.v2(200, 500));
this.area.push(cc.v2(400, 500));
this.area.push(cc.v2(500, 300));
this.area.push(cc.v2(400, 100));
this.area.push(cc.v2(200, 100));
this.area.push(cc.v2(100, 300));
// 绘制
this.drawArea();
}
// 根据点绘制六边形
drawArea () {
let g = this.g;
g.moveTo(this.area[0].x, this.area[0].y);
for (let i = 1; i < this.area.length; i++) {
g.lineTo(this.area[i].x, this.area[i].y);
}
g.lineTo(this.area[0].x, this.area[0].y);
g.stroke();
}
在 CocosCreator 中有这么一个 API 能够测试点是否在多边形内。
层级中添加单色的 player 节点。
// 已声明 this.player 为一个单色节点。
start () {
this.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMove, this);
}
// 触摸移动
_touchMove (event) {
let pos = event.getLocation();
if (cc.Intersection.pointInPolygon(pos, this.area)) {
this.player.position = pos;
}
}
如图,我们能够清晰的看见几个区域。
在上下区域我们应该对齐 x ,在左右区域我们应该对齐 y。
至于四个角落,可写成定点,也可不处理。
我们先看下直线的表示公式。
y1 - y2 = k * (x1 - x2)
所以先用公式求 k 值,再用公式求 x 或 y。
封装一个方法。根据点的下标和给定的 y 值,计算 x 值并返回。
pointInLine (index1, index2, value) {
let point1 = this.area[index1];
let point2 = this.area[index2];
let k = (point2.y - point1.y) / (point2.x - point1.x);
let x = ((value - point1.y) / k) + point1.x;
return x;
}
_touchMove (event) {
let pos = event.getLocation();
if (cc.Intersection.pointInPolygon(pos, this.area)) {
this.player.position = pos;
} else {
const CENTER = 300;
const X_MIN = 200;
const X_MAX = 400;
const Y_MIN = 100;
const Y_MAX = 500;
// 区域判断
if (pos.y > Y_MIN && pos.y < Y_MAX) {
// 左区右区各两条直线
if (pos.x < CENTER) {
// 上直线
if (pos.y > CENTER) {
pos.x = this.pointInLine(0, 5, pos.y);
this.player.position = pos;
} else {
pos.x = this.pointInLine(5, 4, pos.y);
this.player.position = pos;
}
} else {
// 上直线
if (pos.y > CENTER) {
pos.x = this.pointInLine(1, 2, pos.y);
this.player.position = pos;
} else {
pos.x = this.pointInLine(2, 3, pos.y);
this.player.position = pos;
}
}
} else if (pos.x > X_MIN && pos.x < X_MAX) {
// 上下区比较简单
if (pos.y > CENTER) pos.y = Y_MAX;
else pos.y = Y_MIN;
this.player.position = pos;
} else {
// 四角区不处理
}
}
}
游戏中很多问题都是需要数学知识解决的,要打好基础哦!
O(∩_∩)O~~
工程源码在我的微信公众号回复关键词【限位】即可获得
O(∩_∩)O~~
游戏中很多问题都是需要数学知识解决的,要打好基础哦!
O(∩_∩)O~~
工程源码在我的微信公众号回复关键词【限位】即可获得
O(∩_∩)O~~
[外链图片转存中…(img-Hm9c0XEn-1569767321591)]