【cocos creater】7.仿《弓箭传说》- 控制主角朝向敌人
查看项目所有章节接着上一章,我们添加一个敌人精灵,起名enemy并在enemy属性中,添加图集,设置图片得到效果:新建一个enemy的TypeScript脚本,并将脚本添加到entity精灵上编辑ga
on
2025/10/15查看项目所有章节
接着上一章,我们添加一个敌人精灵,起名enemy

并在enemy属性中,添加图集,设置图片

得到效果:

新建一个enemy的TypeScript脚本,并将脚本添加到entity精灵上
编辑game_manager脚本,在顶部添加entity的导入
import Enemy from '../script/enemy'
并添加entity属性节点
@property(Enemy)
enemy: Enemy = null
修改update(dt)方法中的代码
update(dt) {
//计算出朝向
var dx = this.role.node.x - this.enemy.node.x
var dy = this.role.node.y - this.enemy.node.y
var dir = cc.v2(dx, dy)
var angle = dir.signAngle(cc.v2(1, 0))
//var degree = (angle / Math.PI) * 180 + 90
var degree = Math.floor(cc.misc.radiansToDegrees(angle)) + 90
//移动
if (this.joystick.state === 1) {
var s = this.role.move_speed * 0.016
this.role.move(s, this.joystick.radius)
} else {
}
//设置敌人朝向
this.enemy.node.angle = -degree
}
保存后,打开GameManager节点,编辑属性,将enemy精灵拖到enemy属性中

点击运行查看效果:

到这里,敌人始终朝向主角的代码已经写完了,我们来解释一下这段代码的含义
首先,查看几何数学中的夹角公式之余弦公式:

在查看了cocos2d-js的源码:


不难得出以下代码:
clampf(value: number, min_inclusive: number, max_inclusive: number) {
//如果最小值大于最大值,则变量值相互交换
if (min_inclusive > max_inclusive) {
var temp = min_inclusive
min_inclusive = max_inclusive
max_inclusive = temp
}
//若value比最小值小,则返回最小值,如果比最大值大,则返回最大值
return value < min_inclusive ? min_inclusive : value < max_inclusive ? value : max_inclusive
}
update(dt) {
//【计算出朝向】
var dx = this.role.node.x - this.enemy.node.x
var dy = this.role.node.y - this.enemy.node.y
//直线a (主角和敌人直接的向量)
var a = cc.v2(dx, dy)
//直线b (X轴正方向)
var b = cc.v2(1, 0)
//1.使用系统API
//var angle = a.signAngle(b)
//2.手动实现
//实现angle
var m1 = a.x * a.x + a.y * a.y
var m2 = b.x * b.x + b.y * b.y
var dot = a.x * b.x + a.y * b.y
var theta = dot / Math.sqrt(m1 * m2)
//clampf函数:如果比-1小,则返回-1,如果比1大,则返回1
theta = this.clampf(theta, -1, 1)
var angle = Math.acos(theta)
//实现signAngle
//this.cross(vector) < 0 ? -angle : angle
angle = a.x * b.y - a.y * b.x < 0 ? -angle : angle
//1.使用系统API将弧度转化
//var degree = Math.floor(cc.misc.radiansToDegrees(angle)) + 90
//2.手动实现
var degree = (angle / Math.PI) * 180 + 90
//移动
if (this.joystick.state === 1) {
var s = this.role.move_speed * 0.016
this.role.move(s, this.joystick.radius)
} else {
}
//设置敌人朝向
this.enemy.node.angle = -degree
}
OK,之前的敌人跟随主角朝向的代码我们都通过手写的方式实现了,但系统提供了强大的API,就可以直接使用系统封装的,可以减少我们很多写代码的时间,但原理我们一定要清楚
接下来我们实现一下,当主角停止移动时,主角朝向敌人的代码
首先添加一个标志位,因为update方法会不断被调用,但我们只需要在主角停止移动时,只设置一次方向
//是否移动了主角
move: boolean = false
修改update方法
//移动
if (this.joystick.state === 1) {
var s = this.role.move_speed * 0.016
this.role.move(s, this.joystick.radius)
this.move = true
} else {
//若停止移动,设置主角朝向
if (this.move) {
this.move = false
console.log('停止移动 :' + degree)
this.role.node.angle = -degree + 180
}
}
查看效果:

本章源码:
