游戏引擎学习实践之数学知识 ---向量 (一)

利用cocos creator认识向量在游戏中的作用

题目

1.利用cocos creator的graphics组件画一个圆(不使用circle方法)。
2.以此圆的圆心为原点制作一个60°的扇形。
3.假设圆心的原点为敌人,步骤二所制作的扇形为敌人的技能攻击范围。以鼠标在游戏内的坐标点为玩家所在位置,求任意时刻鼠标是否处在敌人攻击范围内(通过扇形颜色区分)

思考

1.首先我们以(0,0)点为原点,以r为半径,每隔1°画一个点,之后将这些点连接,便组成一个圆。
2.以(0,0)点为原点,以r为半径±30°画两个点,之后连接两个点便组成一个扇形。
3.首先获取鼠标当前坐标点并转换为游戏节点内坐标,其次根据向量的叉积以及当前点与原点距离判断点是否在扇形内。

实践

1.首先我们以(0,0)点为原点,以r为半径,每隔1°画一个点,之后将这些点连接,便组成一个圆。

	drawCircle () {
		let line = this.circle;
		//设置线条宽度
		line.lineWidth = 1;
		//设置线条颜色
		line.strokeColor = cc.Color.GREEN;
		let lastPos;
		for (let i = 0; i <= 360; i += 1) {
			let pos = this.createPoint(i);
			if (i === 0) {
			   //创建线条起始点
			   line.moveTo(pos.x, pos.y);
			}
			else {
			   //与前一段线条相连
			   line.lineTo(lastPos.x, lastPos.y);
			}
			lastPos = pos
	   }
	   line.stroke();
	},

	createPoint (angle) {
		//将x转换为弧度
		// let result = this.amplitude * Math.sin(this.cycle * x * Math.PI / 180 + this.offsetX) + this.offsetY;
		let x = this.pointO.x + this.redium * Math.cos(angle * Math.PI / 180);
		let y = this.pointO.y + this.redium * Math.sin(angle * Math.PI / 180);
		let pos = cc.v2(x, y);
		return pos;
	},

效果:
在这里插入图片描述
2.以(0,0)点为原点,以r为半径±30°画两个点,之后连接两个点便组成一个扇形。

 	//根据angle的范围从圆心画两条直线
    drawLine () {
        let line = this.tip;
        line.lineWidth = 1;
        line.strokeColor = cc.Color.RED;
        this.pos1 = this.createPoint(this.angle);
        this.pos2 = this.createPoint(-this.angle);

        line.moveTo(0, 0);
        line.lineTo(this.pos1.x, this.pos1.y);
        line.stroke();

        line.moveTo(0, 0);
        line.lineTo(this.pos2.x, this.pos2.y);
        line.stroke();
    },

效果
在这里插入图片描述
3.首先获取鼠标当前坐标点并转换为游戏节点内坐标,其次根据向量的叉积以及当前点与原点距离判断点是否在扇形内。

	onLoad () {
		this.node.on('touchstart', function (event) {
			//转换为本地坐标
			this.target.position = this.node.convertToNodeSpaceAR(event.getLocation());
			//判断鼠标是否在扇形范围内
			this.judgeTargetIsFront();
		}, this);
	},

    judgeTargetIsFront () {
        if (!this.target) {
            return;
        }
        this.tip.clear();
        //判断当前目标与扇形圆心的方向向量
        //在-angle点处的顺时针方向 在angle点处的逆时针方向
        if ((this.pos1.sub(this.pointO).cross(this.target.position.sub(this.pointO)) * this.pos2.sub(this.pointO).cross(this.target.position.sub(this.pointO))) <= 0 && this.checkPointInCircle()) {
            let line = this.tip;
            //设置线条宽度
            line.lineWidth = 1;
            //设置线条颜色
            line.strokeColor = cc.Color.YELLOW;
            for (let i = -this.angle; i <= this.angle; i += 1) {
                let pos = this.createPoint(i);
                //创建线条起始点
                line.moveTo(this.pointO.x, this.pointO.y);
                //与前一段线条相连
                line.lineTo(pos.x, pos.y);
            }
            line.stroke();
        }
        else {
            let line = this.lineNode.getComponent(cc.Graphics);
            //设置线条宽度
            line.lineWidth = 1;
            //设置线条颜色
            line.strokeColor = cc.Color.GRAY;
            for (let i = -this.angle; i <= this.angle; i += 1) {
                let pos = this.createPoint(i);
                //创建线条起始点
                line.moveTo(this.pointO.x, this.pointO.y);
                //与前一段线条相连
                line.lineTo(pos.x, pos.y);
            }
            line.stroke();
        }
    },

    checkPointInCircle () {
        if (this.pointO.sub(this.target.position).mag() <= this.redium) {
            return true;
        }
        return false;
    },

效果:
在这里插入图片描述
在这里插入图片描述
完整代码:

cc.Class({
    extends: cc.Component,

    properties: {
        lineNode: cc.Node,
        redium: 0,
        angle: 0,
        pointO: cc.Vec2,
        target: cc.Node,

        tip: cc.Graphics,
        line: cc.Graphics,
        circle: cc.Graphics,
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.drawCircle();
                //通过画线分解成扇形 (攻击范围)
                this.drawLine();
                this.node.on('touchstart', function (event) {
                    this.target.position = this.node.convertToNodeSpaceAR(event.getLocation());
                    this.judgeTargetIsFront();
                }, this);
    },

    judgeTargetIsFront () {
        if (!this.target) {
            return;
        }
        this.tip.clear();
        //判断当前目标与扇形圆心的方向向量
        //在-angle点处的顺时针方向 在angle点处的逆时针方向
        if ((this.pos1.sub(this.pointO).cross(this.target.position.sub(this.pointO)) * this.pos2.sub(this.pointO).cross(this.target.position.sub(this.pointO))) <= 0 && this.checkPointInCircle()) {
            let line = this.tip;
            //设置线条宽度
            line.lineWidth = 1;
            //设置线条颜色
            line.strokeColor = cc.Color.YELLOW;
            for (let i = -this.angle; i <= this.angle; i += 1) {
                let pos = this.createPoint(i);
                //创建线条起始点
                line.moveTo(this.pointO.x, this.pointO.y);
                //与前一段线条相连
                line.lineTo(pos.x, pos.y);
            }
            line.stroke();
        }
        else {
            let line = this.lineNode.getComponent(cc.Graphics);
            //设置线条宽度
            line.lineWidth = 1;
            //设置线条颜色
            line.strokeColor = cc.Color.GRAY;
            for (let i = -this.angle; i <= this.angle; i += 1) {
                let pos = this.createPoint(i);
                //创建线条起始点
                line.moveTo(this.pointO.x, this.pointO.y);
                //与前一段线条相连
                line.lineTo(pos.x, pos.y);
            }
            line.stroke();
        }
    },

    //根据angle的范围从圆心画两条直线
    drawLine () {
        let line = this.tip;
        line.lineWidth = 1;
        line.strokeColor = cc.Color.RED;
        this.pos1 = this.createPoint(this.angle);
        this.pos2 = this.createPoint(-this.angle);

        line.moveTo(0, 0);
        line.lineTo(this.pos1.x, this.pos1.y);
        line.stroke();

        line.moveTo(0, 0);
        line.lineTo(this.pos2.x, this.pos2.y);
        line.stroke();
    },

    drawCircle () {
        let line = this.circle;
        //设置线条宽度
        line.lineWidth = 1;
        //设置线条颜色
        line.strokeColor = cc.Color.GREEN;
        let lastPos;
        for (let i = 0; i <= 360; i += 1) {
            let pos = this.createPoint(i);
            if (i === 0) {
                //创建线条起始点
                line.moveTo(pos.x, pos.y);
            }
            else {
                //与前一段线条相连
                line.lineTo(lastPos.x, lastPos.y);
            }
            lastPos = pos
        }
        line.stroke();
    },

    createPoint (angle) {
        //将x转换为弧度
        // let result = this.amplitude * Math.sin(this.cycle * x * Math.PI / 180 + this.offsetX) + this.offsetY;
        let x = this.pointO.x + this.redium * Math.cos(angle * Math.PI / 180);
        let y = this.pointO.y + this.redium * Math.sin(angle * Math.PI / 180);
        let pos = cc.v2(x, y);
        return pos;
    },

    checkPointInCircle () {
        if (this.pointO.sub(this.target.position).mag() <= this.redium) {
            return true;
        }
        return false;
    },

    start () {

    },

    update (dt) {

    },
});

节点摆放
在这里插入图片描述
其中circle tip line上均挂一个graphics组件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值