下面我有我正在制作的简单游戏的部分代码。 在游戏中,你的手指在屏幕上,一个球在你的手指下面。然后每 10 秒添加一个球,跟随你的球。我有一个SKAaction,它每10秒调用一次我的添加敌人函数,从而生成敌人。问题是我无法让添加敌人功能每帧更新一次,因为如果 SKAction 每帧更新一次,它就不会让我调用它,所以我不确定该怎么做才能让球每 10 秒添加一次并让该球跟踪您的位置。因为目前它只跟踪球被添加时的初始位置。任何帮助不胜感激,谢谢。
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: 2))
enemy.run(SKAction.moveTo(y: me.position.y, duration: 2))
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) {
}
}
- 通过字典中的 .name 属性在字典中保留所有当前活着的敌人的列表。此字典中的值是一个元组。此元组跟踪敌人的实例及其目标的实例。
我通过makeEnemyName
和addEnemyToDict
在您的createEnemy
中执行此操作
- 在
update
给每个敌人一个新的行动来跟踪它的目标。这是通过遍历字典,然后使用每个键的值来moveFollowerToTarget
来完成的。此信息存储在我们创建的元组类型中。
import SpriteKit
class GameScene22: SKScene {
// MARK: - My code:
// Tuple to keep track of enemy objects:
typealias FollowerAndTarget = (follower: SKSpriteNode, target: SKSpriteNode)
// [followerName: (followerSprite, targetSprite):
var spriteDictionary: [String: FollowerAndTarget] = [:]
// Give each enemy a unique name for the dictionary:
var enemyCounter = 0
// Assign to each enemy a unique name for the dictionary:
private func makeEnemyName() -> String {
enemyCounter += 1
return "enemy(enemyCounter)"
}
private func addEnemyToDict(enemy: SKSpriteNode, target: SKSpriteNode) {
if let name = enemy.name { spriteDictionary[name] = (enemy, target) }
else { print("enemy not found") } // error!
}
private func removeEnemyFromDict(enemy: SKSpriteNode) {
if let name = enemy.name { spriteDictionary[name] = nil }
else { print("enemy not removed from dictionary!") } // error!
}
// Note, you did not set the enemy to have a constant speed, so the enemy will move at random speeds
// based on how far they are away from the target.
private func moveFollowerToTarget(_ sprites: FollowerAndTarget) {
let action = SKAction.move(to: sprites.target.position, duration: 2)
sprites.follower.run(action)
}
private func allEnemiesMoveToTarget() {
for sprites in spriteDictionary.values {
moveFollowerToTarget(sprites)
}
}
// Use this carefully if you are using phsyics later on:
func killEnemy(_ enemy: SKSpriteNode) {
// Remove this enemy from the update loop:
removeEnemyFromDict(enemy: enemy)
enemy.removeAllActions()
enemy.removeFromParent()
enemy.physicsBody = nil
}
// MARK: - Your code (mostly):
var me = SKSpriteNode()
override func didMove(to view: SKView) {
me = SKSpriteNode(color: .blue, size: CGSize(width: 50, height: 50))
me.name = "me"
addChild(me)
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
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(color: .purple, size: CGSize(width: 30, height: 30))
enemy.name = makeEnemyName()
addEnemyToDict(enemy: enemy, target: me)
moveFollowerToTarget((follower: enemy, target: me))
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))
allEnemiesMoveToTarget()
}
}
override func update(_ currentTime: TimeInterval) {
// Will iterate through dictonary and then call moveFollowerToTarget()
// thus giving each enemy a new movement action to follow.
allEnemiesMoveToTarget()
}
}