如何在每 10 秒内添加一个敌人并让这个敌人跟踪您的位置并跟随它

Posted

技术标签:

【中文标题】如何在每 10 秒内添加一个敌人并让这个敌人跟踪您的位置并跟随它【英文标题】:how to have a enemy be added in every 10 seconds and have this enemy track your location and follow it 【发布时间】:2017-05-18 22:43:46 【问题描述】:

我目前正在开发一个应用程序,在该应用程序中,您的播放器是一个小圆球,可以通过您的手指在屏幕上拖动。然后每 10 秒添加一个敌方球,它会自动跟踪你的球并跟随它,直到它撞上它。这是我到目前为止的代码。你可以在屏幕上拖动你的球,但是即使它的文件在资产中,它也只显示为红色 x 的敌方球每帧都会生成,它们只是移动到你的球在生成时所在的位置.有什么办法可以解决这个问题,不胜感激。我稍后会添加球之间的接触。

import SpriteKit
import GameplayKit

class GameScene: SKScene 


var me = SKSpriteNode()
let enemy = SKSpriteNode (imageNamed: "ellipse 1")

override func didMove(to view: SKView) 
    me = self.childNode(withName: "me") as! SKSpriteNode

    let border = SKPhysicsBody (edgeLoopFrom: self.frame)
    border.friction = 0
    self.physicsBody = border
               



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    for touch in touches
        let location = touch.location(in: self)
        me.run(SKAction.moveTo(x: location.x, duration: 0))
        me.run(SKAction.moveTo(y: location.y, duration: 0))
    




override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
    for touch in touches
        let location = touch.location(in: self)
        me.run(SKAction.moveTo(x: location.x, duration: 0))
        me.run(SKAction.moveTo(y: location.y, duration: 0))
    

override func update(_ currentTime: TimeInterval) 
        let enemy = SKSpriteNode (imageNamed: "ball 2")
    enemy.position = CGPoint(x:667, y: -200)
    enemy.run(SKAction.moveTo(x: me.position.x, duration: 1.5))
    enemy.run(SKAction.moveTo(y: me.position.y, duration: 1.5))
    enemy.zPosition = +1
    addChild(enemy)



【问题讨论】:

【参考方案1】:

所以你遇到的问题是你的敌人的球图像没有加载,而你看到的是一个红色的 X?

如果是这样,您需要将创建精灵的代码分解为多个步骤。首先将图像加载到临时变量中,打印出来,然后使用图像来创建你的精灵:

let enemyImage = imageNamed: "ellipse 1"
print("enemyImage = \(enemyImage)")
let enemy = SKSpriteNode (enemyImage)

如果enemyImage 为零,您需要弄清楚为什么会这样。

【讨论】:

这仍然不起作用,但这不是主要问题,我可以稍后解决,我真正的问题是如何将它们从每帧生成一次更改为每 10 秒生成一次。此外,如果我之后移动我的球,他们只会跟随球坐标到它产生时的位置,敌人不会跟随 检查当前更新时间。如果距离上次生成时间超过 10 秒,则生成一个新敌人并将当前时间保存为上次生成时间。更好的是,只需创建并让 SKAction 每 10 秒运行一次即可生成。 我该怎么做那个skaction方法【参考方案2】:

这是您的代码的修改版本,它将每 10 秒生成一次敌人并让他们跟随您。我使用了苹果的 SpriteKit 模板为敌人提供的 Spaceship 图形。至于您的敌人图形未显示的问题,我会确保该图像在资产文件夹中被命名为“ball 2”。

import SpriteKit
import GameplayKit

class Enemy: SKSpriteNode 
    var enemySpeed: CGFloat = 4


class GameScene: SKScene 

    var me: SKSpriteNode!
    var enemies = [Enemy]()

    override func didMove(to view: SKView) 
        me = self.childNode(withName: "me") as! SKSpriteNode
        let border = SKPhysicsBody (edgeLoopFrom: self.frame)
        border.friction = 0
        self.physicsBody = border
        spawnEnemy() // Spawn an enemy to begin with
        Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(spawnEnemy), userInfo: nil, repeats: true) // Spawns an enemy every 10 seconds
    

    func spawnEnemy() 
        let enemy = Enemy(imageNamed: "Spaceship")
        enemy.xScale = 0.25
        enemy.yScale = 0.25
        enemy.position = CGPoint(x: CGFloat(arc4random() % UInt32(size.width)) - size.width / 2, y: CGFloat(arc4random() % UInt32(size.height)) - size.height / 2)
        enemy.zPosition = 1
        addChild(enemy)
        enemies.append(enemy)
    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        for touch in touches 
            let location = touch.location(in: self)
            me.run(SKAction.move(to: location, duration: 0.05))
        
    

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
        for touch in touches 
            let location = touch.location(in: self)
            me.run(SKAction.move(to: location, duration: 0.05))
        
    

    override func update(_ currentTime: TimeInterval) 
        for enemy in enemies 
            let angle = CGFloat(atan2f(Float(me.position.y - enemy.position.y), Float(me.position.x - enemy.position.x)))
            enemy.zRotation = angle - CGFloat.pi / 2
            enemy.position = CGPoint(x: enemy.position.x + cos(angle) * enemy.enemySpeed, y: enemy.position.y + sin(angle) * enemy.enemySpeed)
        
    

【讨论】:

感谢@mikeytdan,我想出了这个。我的问题是它只跟随我到它产生时的初始位置,然后停在那里。当我把它放在更新函数中让它运行每一帧时我不能调用它 您的代码无法正常工作的原因是因为您每帧都在创建一个新敌人。当他们第一次被创建时,你告诉敌人向你当前的位置移动。您不保留对他们的引用,因此无法告诉他们继续关注您。在我的示例中,我跟踪数组中的所有敌人。每一帧我都会告诉敌人面对并朝着玩家的位置移动。 是的,我想通了,在我过去的评论中,我引用了我刚刚放入答案区域的代码【参考方案3】:
import SpriteKit
import GameplayKit

class GameScene: SKScene 

    var me = SKSpriteNode()

    override func didMove(to view: SKView) 

        me = self.childNode(withName: "me") as! SKSpriteNode

        let border = SKPhysicsBody (edgeLoopFrom: self.frame)
        border.friction = 0
        self.physicsBody = border

        run(SKAction.repeatForever(SKAction.sequence([SKAction.run(createEnemy), SKAction.wait(forDuration: 10.0)])))
    

    func createEnemy () 

        let enemy = SKSpriteNode(imageNamed: "ball 1")
        enemy.name = "enemy"
        enemy.position = CGPoint(x:667, y: -200)

        enemy.run(SKAction.moveTo(x: me.position.x, duration: 1.5))
        enemy.run(SKAction.moveTo(y: me.position.y, duration: 1.5))

        enemy.zPosition = +1
        addChild(enemy)
    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        for touch in touches
            let location = touch.location(in: self)
            me.run(SKAction.moveTo(x: location.x, duration: 0))
            me.run(SKAction.moveTo(y: location.y, duration: 0))
        

    

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
        for touch in touches
            let location = touch.location(in: self)
            me.run(SKAction.moveTo(x: location.x, duration: 0))
            me.run(SKAction.moveTo(y: location.y, duration: 0))
        
    

    override func update(_ currentTime: TimeInterval) 


    

【讨论】:

以上是关于如何在每 10 秒内添加一个敌人并让这个敌人跟踪您的位置并跟随它的主要内容,如果未能解决你的问题,请参考以下文章

如何减少在 Swift spritekit 中创建更多敌人的时间?

如何在java中测试多个交叉点?

我如何在函数中调用某个参数?

如何保持协程直到条件为真 Unity

如何在与玩家碰撞后让敌人停下来一秒钟?团结[重复]

OpenGL - 2D敌人不旋转面对玩家