SKAction.repeatActionForever 只在第一次调用时计算随机数
SKAction.repeatActionForever only calculates random number on first call
我想做到这一点,以便我的专栏在超时时生成一个新的 y 值,它被传送,以便它始终在不同的高度移动。出于某种原因,随机数调用仅在第一次调用,从那时起,操作使用相同的数字而不是调用新的数字。这是我的代码:
let slideAction2A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let newLocation = SKAction.moveToY(getFloat(), duration: 0)
let teleportActionGroup2A = SKAction.group([teleportAction2A,newLocation])
let col2ASequence = SKAction.sequence([slideAction2A,teleportActionGroup2A])
let runCol2A = SKAction.repeatActionForever(col2ASequence)
let col2ADelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2A = SKAction.sequence([col2ADelaySlide,runCol2A])
column2A.runAction(delayAndRun2A)
func getFloat() -> CGFloat {
var x: CGFloat
x = CGFloat(arc4random_uniform(200))
x += CGFloat(newScreenHeight)
print(x)
return x
}
完整代码在这里:
```
//
// GameScene.swift
//
//
import SpriteKit
import CoreMotion
class GameScene: SKScene {
let world = SKNode()
let house = Player()
let ground = Ground()
var screenCenterY = CGFloat()
let initialPlayerPosition = CGPoint(x: 150, y: 250)
var playerProgress = CGFloat()
let motionManager = CMMotionManager()
var destX:CGFloat = 0.0
var destY:CGFloat = 0.0
var test = SKNode()
let newScreenHeight: Int = 0
let screenSize: CGRect = UIScreen.mainScreen().bounds
var screenHeight : CGFloat = 0
let colWidInt:Int = 0
let colWidCG:CGFloat = 0
let houseWid = 0
//let newScreenHeight:Int = 0
let colInitialPosInt:Int = 0
let colInitialPosCGFloat:CGFloat = 0
let colTravel:CGFloat = 0
var column2A = SKSpriteNode()
override func didMoveToView(view: SKView) {
print("yao 1")
// Set a sky-blue background color:
self.backgroundColor = UIColor(red: 0.4, green: 0.6, blue: 0.95, alpha: 1.0)
// Add the world node as a child of the scene:
self.addChild(world)
// Store the vertical center of the screen:
screenCenterY = self.size.height / 2
house.spawn(world, position: CGPoint(x: 100, y: 100))
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
screenHeight = screenSize.height
//screenWidthInt = Int(screenWidth)
let colWidInt = 50
let colWidCG:CGFloat = CGFloat(colWidInt)
let houseWid = 50
let newScreenHeight:Int = Int(screenHeight)
let colInitialPosInt:Int = Int(screenWidth)+colWidInt/2
let colInitialPosCGFloat:CGFloat = CGFloat(colInitialPosInt)
let colTravel:CGFloat = CGFloat(colInitialPosInt+colWidInt/2)
// A bronze coin:
let column1A = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column1A.position = CGPoint(x: colInitialPosInt, y: newScreenHeight+35)
self.addChild(column1A)
let column1B = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column1B.position = CGPoint(x: colInitialPosInt, y: -35)
self.addChild(column1B)
column2A = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: colWidCG, height: screenHeight))
column2A.position = CGPoint(x: colInitialPosInt, y: newScreenHeight+35)
self.addChild(column2A)
let column2B = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column2B.position = CGPoint(x: colInitialPosInt, y: -35)
self.addChild(column2B)
let slideAction1A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction1A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col1ASequence = SKAction.sequence([slideAction1A,teleportAction1A])
let runCol1A = SKAction.repeatActionForever(col1ASequence)
column1A.runAction(runCol1A)
let slideAction1B = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction1B = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col1BSequence = SKAction.sequence([slideAction1B,teleportAction1B])
let runCol1B = SKAction.repeatActionForever(col1BSequence)
column1B.runAction(runCol1B)
let slideAction2A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let newLocation = SKAction.moveToY(getFloat(), duration: 0)
let teleportActionGroup2A = SKAction.group([teleportAction2A,newLocation])
let col2ASequence = SKAction.sequence([slideAction2A,teleportActionGroup2A])
let runCol2A = SKAction.repeatActionForever(col2ASequence)
let col2ADelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2A = SKAction.sequence([col2ADelaySlide,runCol2A])
column2A.runAction(delayAndRun2A)
let slideAction2B = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2B = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col2BSequence = SKAction.sequence([slideAction2B,teleportAction2B])
let runCol2B = SKAction.repeatActionForever(col2BSequence)
let col2BDelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2B = SKAction.sequence([col2BDelaySlide,runCol2B])
column2B.runAction(delayAndRun2B)
print("yao 4")
self.motionManager.startAccelerometerUpdates()
if motionManager.accelerometerAvailable == true {
// 2
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler:{
data, error in
let currentX = self.house.position.x
let currentY = self.house.position.y
// 3
if data!.acceleration.x < 0 {
self.destX = currentX + 2*CGFloat(data!.acceleration.x * 200)
}
else if data!.acceleration.x > 0 {
self.destX = currentX + 2*CGFloat(data!.acceleration.x * 200)
}
if data!.acceleration.y < 0 {
self.destY = currentY + CGFloat(data!.acceleration.y * 400)
}
else if data!.acceleration.y > 0 {
self.destY = currentY + CGFloat(data!.acceleration.y * 400)
}
})
}
}
override func didSimulatePhysics() {
}
func getRand() -> CGFloat{
var x: CGFloat
x = CGFloat(arc4random_uniform(200))
//print("x is: ",x)
//x += CGFloat(screenHeight)
//print("ScreenHeight is : ",screenHeight)
//print("new x is: ",x)
return x
}
func getFloat() -> CGFloat {
var x: CGFloat = getRand()
//x = CGFloat(arc4random_uniform(200))
//print("x is: ",x)
x += CGFloat(screenHeight)
//print("ScreenHeight is : ",screenHeight)
//print("new x is: ",x)
return x
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
}
override func update(currentTime: NSTimeInterval) {
let actionX = SKAction.moveToX(destX, duration: 0.3)
let actionY = SKAction.moveToY(destY, duration: 0.3)
let actionGroup = SKAction.group([actionX,actionY])
house.runAction(actionGroup)
}
}
```
所以这是对同一件事的一种方式(并且有很多方式)。
这段代码的作用是:
- 制造障碍
- 将它从左侧移动到屏幕的右侧
- 移除屏幕外的障碍物
- 在每次创建障碍物时随机化障碍物的 y 坐标
只需复制粘贴即可查看效果:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
//MARK: - Sprite kit functionality
override func didMoveToView(view: SKView) {
startSpawning()
}
func startSpawning(){
let wait = SKAction.waitForDuration(1.5)
let block = SKAction.runBlock({[unowned self] in self.spawnObstacle()})
let sequence = SKAction.sequence([wait, block])
runAction(SKAction.repeatActionForever(sequence), withKey: "spawning")
}
func spawnObstacle(){
// 1) create an obstacle
let obstacle = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 50, height: frame.size.height/2.0))
// 2) Place it outside the screen, next to the right edge and randomize the y position each time
let lowerBound:CGFloat = -200 //Calcluate this to match your needs
let upperBound:CGFloat = 200 //Calcluate this to match your needs
let obstacleRandomY = randomBetweenNumbers(lowerBound, secondNum: upperBound)
obstacle.position = CGPoint(x: frame.maxX + obstacle.size.width, y: obstacleRandomY)
// 3) Add it to the scene
addChild(obstacle)
// 4) Move the obstacle from the right side, to the left side of a screen
let move = SKAction.moveToX(-obstacle.calculateAccumulatedFrame().width, duration: 3)
// 5) Remove the obstacle from the scene when off-screen
let moveAndRemove = SKAction.sequence([move, SKAction.removeFromParent()])
obstacle.runAction(moveAndRemove)
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat{
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}
}
你可以添加另一个障碍物(上管)并调整一点 lowerBound 和 upperBound 变量,这样你就会有像 Flappy Birds 中的效果...
我想做到这一点,以便我的专栏在超时时生成一个新的 y 值,它被传送,以便它始终在不同的高度移动。出于某种原因,随机数调用仅在第一次调用,从那时起,操作使用相同的数字而不是调用新的数字。这是我的代码:
let slideAction2A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let newLocation = SKAction.moveToY(getFloat(), duration: 0)
let teleportActionGroup2A = SKAction.group([teleportAction2A,newLocation])
let col2ASequence = SKAction.sequence([slideAction2A,teleportActionGroup2A])
let runCol2A = SKAction.repeatActionForever(col2ASequence)
let col2ADelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2A = SKAction.sequence([col2ADelaySlide,runCol2A])
column2A.runAction(delayAndRun2A)
func getFloat() -> CGFloat {
var x: CGFloat
x = CGFloat(arc4random_uniform(200))
x += CGFloat(newScreenHeight)
print(x)
return x
}
完整代码在这里:
```
//
// GameScene.swift
//
//
import SpriteKit
import CoreMotion
class GameScene: SKScene {
let world = SKNode()
let house = Player()
let ground = Ground()
var screenCenterY = CGFloat()
let initialPlayerPosition = CGPoint(x: 150, y: 250)
var playerProgress = CGFloat()
let motionManager = CMMotionManager()
var destX:CGFloat = 0.0
var destY:CGFloat = 0.0
var test = SKNode()
let newScreenHeight: Int = 0
let screenSize: CGRect = UIScreen.mainScreen().bounds
var screenHeight : CGFloat = 0
let colWidInt:Int = 0
let colWidCG:CGFloat = 0
let houseWid = 0
//let newScreenHeight:Int = 0
let colInitialPosInt:Int = 0
let colInitialPosCGFloat:CGFloat = 0
let colTravel:CGFloat = 0
var column2A = SKSpriteNode()
override func didMoveToView(view: SKView) {
print("yao 1")
// Set a sky-blue background color:
self.backgroundColor = UIColor(red: 0.4, green: 0.6, blue: 0.95, alpha: 1.0)
// Add the world node as a child of the scene:
self.addChild(world)
// Store the vertical center of the screen:
screenCenterY = self.size.height / 2
house.spawn(world, position: CGPoint(x: 100, y: 100))
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
screenHeight = screenSize.height
//screenWidthInt = Int(screenWidth)
let colWidInt = 50
let colWidCG:CGFloat = CGFloat(colWidInt)
let houseWid = 50
let newScreenHeight:Int = Int(screenHeight)
let colInitialPosInt:Int = Int(screenWidth)+colWidInt/2
let colInitialPosCGFloat:CGFloat = CGFloat(colInitialPosInt)
let colTravel:CGFloat = CGFloat(colInitialPosInt+colWidInt/2)
// A bronze coin:
let column1A = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column1A.position = CGPoint(x: colInitialPosInt, y: newScreenHeight+35)
self.addChild(column1A)
let column1B = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column1B.position = CGPoint(x: colInitialPosInt, y: -35)
self.addChild(column1B)
column2A = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: colWidCG, height: screenHeight))
column2A.position = CGPoint(x: colInitialPosInt, y: newScreenHeight+35)
self.addChild(column2A)
let column2B = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: colWidCG, height: screenHeight))
column2B.position = CGPoint(x: colInitialPosInt, y: -35)
self.addChild(column2B)
let slideAction1A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction1A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col1ASequence = SKAction.sequence([slideAction1A,teleportAction1A])
let runCol1A = SKAction.repeatActionForever(col1ASequence)
column1A.runAction(runCol1A)
let slideAction1B = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction1B = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col1BSequence = SKAction.sequence([slideAction1B,teleportAction1B])
let runCol1B = SKAction.repeatActionForever(col1BSequence)
column1B.runAction(runCol1B)
let slideAction2A = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2A = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let newLocation = SKAction.moveToY(getFloat(), duration: 0)
let teleportActionGroup2A = SKAction.group([teleportAction2A,newLocation])
let col2ASequence = SKAction.sequence([slideAction2A,teleportActionGroup2A])
let runCol2A = SKAction.repeatActionForever(col2ASequence)
let col2ADelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2A = SKAction.sequence([col2ADelaySlide,runCol2A])
column2A.runAction(delayAndRun2A)
let slideAction2B = SKAction.moveByX(-colTravel, y: 0, duration: 5)
let teleportAction2B = SKAction.moveToX(colInitialPosCGFloat, duration: 0)
let col2BSequence = SKAction.sequence([slideAction2B,teleportAction2B])
let runCol2B = SKAction.repeatActionForever(col2BSequence)
let col2BDelaySlide = SKAction.moveByX(0, y: 0, duration: 2.5)
let delayAndRun2B = SKAction.sequence([col2BDelaySlide,runCol2B])
column2B.runAction(delayAndRun2B)
print("yao 4")
self.motionManager.startAccelerometerUpdates()
if motionManager.accelerometerAvailable == true {
// 2
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler:{
data, error in
let currentX = self.house.position.x
let currentY = self.house.position.y
// 3
if data!.acceleration.x < 0 {
self.destX = currentX + 2*CGFloat(data!.acceleration.x * 200)
}
else if data!.acceleration.x > 0 {
self.destX = currentX + 2*CGFloat(data!.acceleration.x * 200)
}
if data!.acceleration.y < 0 {
self.destY = currentY + CGFloat(data!.acceleration.y * 400)
}
else if data!.acceleration.y > 0 {
self.destY = currentY + CGFloat(data!.acceleration.y * 400)
}
})
}
}
override func didSimulatePhysics() {
}
func getRand() -> CGFloat{
var x: CGFloat
x = CGFloat(arc4random_uniform(200))
//print("x is: ",x)
//x += CGFloat(screenHeight)
//print("ScreenHeight is : ",screenHeight)
//print("new x is: ",x)
return x
}
func getFloat() -> CGFloat {
var x: CGFloat = getRand()
//x = CGFloat(arc4random_uniform(200))
//print("x is: ",x)
x += CGFloat(screenHeight)
//print("ScreenHeight is : ",screenHeight)
//print("new x is: ",x)
return x
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
}
override func update(currentTime: NSTimeInterval) {
let actionX = SKAction.moveToX(destX, duration: 0.3)
let actionY = SKAction.moveToY(destY, duration: 0.3)
let actionGroup = SKAction.group([actionX,actionY])
house.runAction(actionGroup)
}
}
```
所以这是对同一件事的一种方式(并且有很多方式)。
这段代码的作用是:
- 制造障碍
- 将它从左侧移动到屏幕的右侧
- 移除屏幕外的障碍物
- 在每次创建障碍物时随机化障碍物的 y 坐标
只需复制粘贴即可查看效果:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
//MARK: - Sprite kit functionality
override func didMoveToView(view: SKView) {
startSpawning()
}
func startSpawning(){
let wait = SKAction.waitForDuration(1.5)
let block = SKAction.runBlock({[unowned self] in self.spawnObstacle()})
let sequence = SKAction.sequence([wait, block])
runAction(SKAction.repeatActionForever(sequence), withKey: "spawning")
}
func spawnObstacle(){
// 1) create an obstacle
let obstacle = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 50, height: frame.size.height/2.0))
// 2) Place it outside the screen, next to the right edge and randomize the y position each time
let lowerBound:CGFloat = -200 //Calcluate this to match your needs
let upperBound:CGFloat = 200 //Calcluate this to match your needs
let obstacleRandomY = randomBetweenNumbers(lowerBound, secondNum: upperBound)
obstacle.position = CGPoint(x: frame.maxX + obstacle.size.width, y: obstacleRandomY)
// 3) Add it to the scene
addChild(obstacle)
// 4) Move the obstacle from the right side, to the left side of a screen
let move = SKAction.moveToX(-obstacle.calculateAccumulatedFrame().width, duration: 3)
// 5) Remove the obstacle from the scene when off-screen
let moveAndRemove = SKAction.sequence([move, SKAction.removeFromParent()])
obstacle.runAction(moveAndRemove)
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat{
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}
}
你可以添加另一个障碍物(上管)并调整一点 lowerBound 和 upperBound 变量,这样你就会有像 Flappy Birds 中的效果...