如何将敌人移向移动的玩家?
How to move enemy towards a moving player?
我正在创建一个简单的 sprite 套件游戏,它将玩家定位在屏幕的左侧,而敌人则从右侧接近。由于玩家可以上下移动,我希望敌人 "smartly" 调整他们朝向玩家的路径。
我尝试在玩家移动时删除并重新添加 SKAction 序列,但下面的代码导致敌人根本不显示,可能是因为它只是在每个帧更新时添加和删除每个动作,所以他们永远不会有机会搬家。
希望就创建 "smart" 随时会向玩家位置移动的敌人的最佳实践获得一些反馈。
这是我的代码:
func moveEnemy(enemy: Enemy) {
let moveEnemyAction = SKAction.moveTo(CGPoint(x:self.player.position.x, y:self.player.position.y), duration: 1.0)
moveEnemyAction.speed = 0.2
let removeEnemyAction = SKAction.removeFromParent()
enemy.runAction(SKAction.sequence([moveEnemyAction,removeEnemyAction]), withKey: "moveEnemyAction")
}
func updateEnemyPath() {
for enemy in self.enemies {
if let action = enemy.actionForKey("moveEnemyAction") {
enemy.removeAllActions()
self.moveEnemy(enemy)
}
}
}
override func update(currentTime: NSTimeInterval) {
self. updateEnemyPath()
}
您必须在每次更新中更新敌人 position
和 zRotation
属性:方法调用。
搜索者和目标
好的,让我们在场景中添加一些节点。我们需要一个探索者和一个目标。导引头是导弹,目标是触摸位置。我说过你应该在 update: 方法中执行此操作,但我将使用 touchesMoved 方法来制作一个更好的示例。以下是您应该如何设置场景:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let missile = SKSpriteNode(imageNamed: "seeking_missile")
let missileSpeed:CGFloat = 3.0
override func didMoveToView(view: SKView) {
missile.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(missile)
}
}
瞄准
要实现瞄准,您必须计算根据目标旋转 sprite 的程度。在本例中,我将使用导弹并使其指向触摸位置。为此,您应该使用 atan2 函数,如下所示(在 touchesMoved:
方法内):
if let touch = touches.first {
let location = touch.locationInNode(self)
//Aim
let dx = location.x - missile.position.x
let dy = location.y - missile.position.y
let angle = atan2(dy, dx)
missile.zRotation = angle
}
请注意 atan2 接受 y,x 顺序的参数,而不是 x,y。
所以现在,我们有一个导弹应该发射的角度。现在让我们根据那个角度更新它的位置(在瞄准部分正下方的 touchesMoved:
方法中添加这个):
//Seek
let vx = cos(angle) * missileSpeed
let vy = sin(angle) * missileSpeed
missile.position.x += vx
missile.position.y += vy
就是这样。这是结果:
请注意,在 Sprite-Kit 中,0 弧度的角度指定正 x 轴。而正角是逆时针方向:
阅读更多here。
这意味着您应该将导弹朝向右侧 rather than upwards 。你也可以使用向上的图像,但你必须这样做:
missile.zRotation = angle - CGFloat(M_PI_2)
我正在创建一个简单的 sprite 套件游戏,它将玩家定位在屏幕的左侧,而敌人则从右侧接近。由于玩家可以上下移动,我希望敌人 "smartly" 调整他们朝向玩家的路径。
我尝试在玩家移动时删除并重新添加 SKAction 序列,但下面的代码导致敌人根本不显示,可能是因为它只是在每个帧更新时添加和删除每个动作,所以他们永远不会有机会搬家。
希望就创建 "smart" 随时会向玩家位置移动的敌人的最佳实践获得一些反馈。
这是我的代码:
func moveEnemy(enemy: Enemy) {
let moveEnemyAction = SKAction.moveTo(CGPoint(x:self.player.position.x, y:self.player.position.y), duration: 1.0)
moveEnemyAction.speed = 0.2
let removeEnemyAction = SKAction.removeFromParent()
enemy.runAction(SKAction.sequence([moveEnemyAction,removeEnemyAction]), withKey: "moveEnemyAction")
}
func updateEnemyPath() {
for enemy in self.enemies {
if let action = enemy.actionForKey("moveEnemyAction") {
enemy.removeAllActions()
self.moveEnemy(enemy)
}
}
}
override func update(currentTime: NSTimeInterval) {
self. updateEnemyPath()
}
您必须在每次更新中更新敌人 position
和 zRotation
属性:方法调用。
搜索者和目标
好的,让我们在场景中添加一些节点。我们需要一个探索者和一个目标。导引头是导弹,目标是触摸位置。我说过你应该在 update: 方法中执行此操作,但我将使用 touchesMoved 方法来制作一个更好的示例。以下是您应该如何设置场景:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let missile = SKSpriteNode(imageNamed: "seeking_missile")
let missileSpeed:CGFloat = 3.0
override func didMoveToView(view: SKView) {
missile.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(missile)
}
}
瞄准
要实现瞄准,您必须计算根据目标旋转 sprite 的程度。在本例中,我将使用导弹并使其指向触摸位置。为此,您应该使用 atan2 函数,如下所示(在 touchesMoved:
方法内):
if let touch = touches.first {
let location = touch.locationInNode(self)
//Aim
let dx = location.x - missile.position.x
let dy = location.y - missile.position.y
let angle = atan2(dy, dx)
missile.zRotation = angle
}
请注意 atan2 接受 y,x 顺序的参数,而不是 x,y。
所以现在,我们有一个导弹应该发射的角度。现在让我们根据那个角度更新它的位置(在瞄准部分正下方的 touchesMoved:
方法中添加这个):
//Seek
let vx = cos(angle) * missileSpeed
let vy = sin(angle) * missileSpeed
missile.position.x += vx
missile.position.y += vy
就是这样。这是结果:
请注意,在 Sprite-Kit 中,0 弧度的角度指定正 x 轴。而正角是逆时针方向:
阅读更多here。
这意味着您应该将导弹朝向右侧
missile.zRotation = angle - CGFloat(M_PI_2)