如何将敌人移向移动的玩家? [英] How to move enemy towards a moving player?

查看:42
本文介绍了如何将敌人移向移动的玩家?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个简单的精灵套件游戏,它将玩家定位在屏幕左侧,而敌人从右侧接近.由于玩家可以上下移动,我希望敌人聪明地"调整他们朝向玩家的路径.

我尝试在玩家移动时删除和重新添加 SKAction 序列,但是下面的代码导致敌人根本不显示,可能是因为它只是在每次更新帧时添加和删除每个动作,所以他们从来没有移动的机会.

希望得到一些关于创建随时向玩家位置移动的智能"敌人的最佳实践的反馈.

这是我的代码:

 func moveEnemy(enemy: Enemy) {让 moveEnemyAction = SKAction.moveTo(CGPoint(x:self.player.position.x, y:self.player.position.y), 持续时间:1.0)moveEnemyAction.speed = 0.2让 removeEnemyAction = SKAction.removeFromParent()敌人.runAction(SKAction.sequence([moveEnemyAction,removeEnemyAction]), withKey: "moveEnemyAction")}func updateEnemyPath() {对于 self.enemies 中的敌人 {如果让行动 = 敌人.actionForKey("moveEnemyAction") {敌人.removeAllActions()self.moveEnemy(敌人)}}}覆盖 func 更新(当前时间:NSTimeInterval){自己.更新敌人路径()}

解决方案

你必须在每次更新时更新敌人的 positionzRotation 属性:方法调用.

搜索者和目标

好的,让我们向场景添加一些节点.我们需要一个寻求者和一个目标.导引头是导弹,目标是接触位置.我说过你应该在 update: 方法中执行此操作,但我将使用 touchesMoved 方法来制作一个更好的示例.以下是您应该如何设置场景:

import SpriteKit类 GameScene:SKScene,SKPhysicsContactDelegate {让导弹 = SKSpriteNode(imageNamed: "seeking_missile")让导弹速度:CGFloat = 3.0覆盖 func didMoveToView(view: SKView) {导弹.位置 = CGPoint(x: frame.midX, y: frame.midY)addChild(导弹)}}

瞄准

要实现瞄准,您必须根据精灵的目标计算必须旋转多少精灵.在本例中,我将使用导弹并使其指向触摸位置.为此,您应该使用 atan2 函数,如下所示(在 touchesMoved: 方法中):

if let touch = touches.first {让位置 = touch.locationInNode(self)//目的让 dx = 位置.x - 导弹.位置.x让 dy = location.y - 导弹.位置.y让角度 = atan2(dy, dx)导弹.zRotation = 角度}

请注意,

请注意,在 Sprite-Kit 中,0 弧度的角度指定了正 x 轴.而正角是逆时针方向:

在 而不是向上 .您也可以使用向上的图像,但您必须执行以下操作:

missile.zRotation = 角度 - CGFloat(M_PI_2)

I am creating a simple sprite kit game that will position a player on the left side of the screen, while enemies approach from the right. Since the player can be moved up and down, I want the enemies to "smartly" adjust their path towards the player.

I tried removing and re-adding the SKAction sequence whenever the player moves, but the below code causes the enemies to not show at all, probably because its just adding and removing each action on every frame update, so they never have a chance to move.

Hoping to get a little feedback about the best practice of creating "smart" enemies that will move towards a player's position at any time.

Here is my code:

    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()
}

解决方案

You have to update enemy position and zRotation property in each update: method call.

Seeker and a Target

Okay, so lets add some nodes to the scene. We need a seeker and a target. Seeker would be a missile, and target would be a touch location. I said you should do this inside of a update: method, but I will use touchesMoved method to make a better example. Here is how you should setup the scene:

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)
    }
}

Aiming

To implement the aiming you have to calculate the how much you have to rotate a sprite based on its target. In this example I will use a missile and make it point towards the touch location. To accomplish this, you should use atan2 function, like this ( inside touchesMoved: method):

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

}

Note that atan2 accepts parameters in y,x order, rather than x,y.

So right now, we have an angle in which missile should go. Now lets update its position based on that angle (add this inside touchesMoved: method right below the aiming part):

//Seek
 let vx = cos(angle) * missileSpeed
 let vy = sin(angle) * missileSpeed

 missile.position.x += vx
 missile.position.y += vy

And that would be it. Here is the result:

Note that in Sprite-Kit the angle of 0 radians specifies the positive x axis. And the positive angle is in the counterclockwise direction:

Read more here.

This means that you should orient your missile to the right rather than upwards . You can use the upwards oriented image as well, but you will have to do something like this:

missile.zRotation = angle - CGFloat(M_PI_2)

这篇关于如何将敌人移向移动的玩家?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆