问题描述
我正在 Xcode 中为 iOS 制作一个砖块破坏风格的游戏。没有桨,球都是从同一位置发射的(由第一个球从最后一层落下的位置决定)。根据玩家创造的球数量,每次发射不同数量的球。每场比赛都从一个球开始,但用户在玩游戏时会收集更多。当对球精灵施加脉冲时,我只能同时移动一个精灵或所有球精灵。如何在每次精灵启动之间延迟移动球精灵?
下面我将回顾我已经尝试过的内容。在此先感谢您的帮助!
到目前为止,我已经尝试了几件事。首先,我试图在允许用户启动并将所有球精灵放在同一位置之前创建所有球精灵。然后我列举了它们并试图在那里延迟启动它们。然而,这只是在延迟后同时发射所有球,而不是单独发射。
gameWorldNode.enumerateChildNodes(withName: BallCategoryName) {
node,stop in
let ball = node as! SKSpriteNode
ball.move(toParent: gameWorldNode)
//Calculate Vector
var dx = CGFloat(touchLocation.x - ball.position.x)
var dy = CGFloat(touchLocation.y - ball.position.y)
//Calculate Magnitude
let magnitude = sqrt(dx * dx + dy * dy)
dx /= magnitude
dy /= magnitude
//Create Vector
let vector = CGVector(dx: 30.0 * dx,dy: 30.0 * dy)
let secondsToDelay = 0.25
dispatchQueue.main.asyncAfter(deadline: .Now() + secondsToDelay){
//Apply impulse
ball.physicsBody!.applyImpulse(vector)
}
}
其次,我突然想到,如果我在施加脉冲之前、前一个球发射之后才创建球精灵,可能会更好地提高游戏性能。所以我尝试了以下代码。然而,虽然我认为我现在可能走在正确的道路上,但新创建的球精灵没有启动。他们被创造出来,但出于某种原因,他们没有应用冲动。
let ball = gameWorldNode.childNode(withName: BallCategoryName) as! SKSpriteNode
ball.move(toParent: gameWorldNode)
//Calculate Vector
var dx = CGFloat(touchLocation.x - ball.position.x)
var dy = CGFloat(touchLocation.y - ball.position.y)
//Calculate Magnitude
let magnitude = sqrt(dx * dx + dy * dy)
dx /= magnitude
dy /= magnitude
//Create Vector
let vector = CGVector(dx: 30.0 * dx,dy: 30.0 * dy)
ball.physicsBody!.applyImpulse(vector)
var i = 1
while (i != ballsAvailabe) {
//Create new ball sprite
let nextBall: SKSpriteNode = Ball()
nextBall.position = CGPoint(x: locationX,y: locationY)
gameWorldNode.addChild(nextBall)
let secondsToDelay = 0.1
dispatchQueue.main.asyncAfter(deadline: .Now() + secondsToDelay) {
//Apply impulse to ball
nextBall.physicsBody!.applyImpulse(vector)
}
//Update i
i += 1
}
我还尝试将精灵添加到数组中并遍历该数组。然而,这只是一次发射每个球。
for _ in 0..<ballsAvailabe {
//Create new ball sprite
let ball: SKSpriteNode = Ball()
ball.position = CGPoint(x: locationX,y: locationY)
ball.physicsBody!.categoryBitMask = nextBallCategory
ball.color = nextBallInPlay
ball.colorBlendFactor = 1
ball.physicsBody!.contactTestBitMask = BottomCategory | AddABallCategory | RedBlockCategory | BlueBlockCategory | OrangeBlockCategory | PurpleBlockCategory | GreenBlockCategory | CyanBlockCategory
ballSprites.append(ball)
gameWorldNode.addChild(ball)
}
for sprite in ballSprites {
let secondsToDelay = 0.3
dispatchQueue.main.asyncAfter(deadline: .Now() + secondsToDelay) {
sprite.physicsBody!.applyImpulse(vector)
}
}
编辑: 遵循下面的约翰评论,我在第二次尝试中添加了代码,以确保正确创建物理体。抱歉,代码中的所有变量都是我创建的全局变量,并保存在自己的文件中,以确保我在整个代码中保持值一致。这效果更好。当用户只有一个球时,它可以完美地工作。但是,当用户收集更多要发射的球时,它有时会延迟到预期位置而完美发射。其他时候它只会发射第一个球。其他时候它会发射到一个意想不到的位置。
这是更新的代码:
//Grab existing ball object
let ball = gameWorldNode.childNode(withName: BallCategoryName) as! SKSpriteNode
//Assign to game world node
ball.move(toParent: gameWorldNode)
//Apply ball properties
ball.color = nextBallInPlay
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 2)
ball.physicsBody!.categoryBitMask = RedBallCategory
ball.name = BallCategoryName
ball.colorBlendFactor = 1
ball.physicsBody?.pinned = false
ball.physicsBody?.mass = ballMass
ball.physicsBody?.affectedByGravity = ballGravity
ball.physicsBody?.allowsRotation = ballRotation
ball.physicsBody?.isDynamic = ballDynamic
ball.zPosition = ballZPos
ball.physicsBody?.friction = ballFriction
ball.physicsBody?.restitution = ballRestitution
ball.physicsBody?.lineardamping = ballLineardaming
ball.physicsBody?.angulardamping = ballAngulardamping
//Stop more launches and accidently using power ups
isFingerOnScreen = true
canBallBeLaunched = false
canUsePowerUps = false
//Ensure physics world speed is accurate
physicsWorld.speed = 1
//Launching location
var dx = CGFloat(touchLocation.x - locationX)
var dy = CGFloat(touchLocation.y - locationY)
//Calculate Magnitude
let magnitude = sqrt(dx * dx + dy * dy)
dx /= magnitude
dy /= magnitude
//Create Vector
let vector = CGVector(dx: 30.0 * dx,dy: 30.0 * dy)
//Apply impule to first ball
ball.physicsBody!.applyImpulse(vector)
//loop to create x number of balls based on what the user has collected
var i = 1
while (i != ballsAvailabe) {
//Create new ball sprite
let nextBall: SKSpriteNode = Ball()
nextBall.position = CGPoint(x: locationX,y: locationY)
gameWorldNode.addChild(nextBall)
//Ball properties
nextBall.color = nextBallInPlay
nextBall.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 2)
nextBall.physicsBody!.categoryBitMask = RedBallCategory
nextBall.name = BallCategoryName
nextBall.colorBlendFactor = 1
nextBall.physicsBody?.pinned = false
nextBall.physicsBody?.mass = ballMass
nextBall.physicsBody?.affectedByGravity = ballGravity
nextBall.physicsBody?.allowsRotation = ballRotation
nextBall.physicsBody?.isDynamic = ballDynamic
nextBall.zPosition = ballZPos
nextBall.physicsBody?.friction = ballFriction
nextBall.physicsBody?.restitution = ballRestitution
nextBall.physicsBody?.lineardamping = ballLineardaming
nextBall.physicsBody?.angulardamping = ballAngulardamping
//Delay between each ball
let secondsToDelay = 0.1
dispatchQueue.main.asyncAfter(deadline: .Now() + secondsToDelay) {
//Apply impulse to ball
nextBall.physicsBody!.applyImpulse(vector)
}
//Update i
i += 1
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)