2016-03-28 63 views
0

我试图从屏幕的顶部做一个方形的下降。但是当它下降一半时,它会一直在屏幕上反弹。我没有在屏幕中间创建一个对象。我不明白为什么它在屏幕中间弹跳。SKSpriteNode弹跳的东西,我没有在Swift中创建

这里的运行代码的链接,我的视频:http://sendvid.com/enm9l1np

下面的代码:

import SpriteKit 

class GameScene: SKScene, SKPhysicsContactDelegate { 

    var animator : UIDynamicAnimator? 
    let BlueSquare = SKSpriteNode() 
    let RedSquare = SKSpriteNode() 
    var scorenumber = 0 
    var Ground = SKSpriteNode() 

    override func didMoveToView(view: SKView) { 
     /* Setup your scene here */ 
     physicsWorld.gravity = CGVector(dx: 1.0, dy: -9.0) 

     let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 
     // 2. Set the friction of that physicsBody to 0 
     borderBody.friction = 0 
     // 3. Set physicsBody of scene to borderBody 
     self.physicsBody = borderBody 





     let width = UInt32(self.frame.size.width) 

     let X = arc4random() % width 


     Ground = SKSpriteNode(imageNamed: "Ground") 
     Ground.setScale(1.0) 
     Ground.position = CGPoint(x: self.frame.width/2, y: 5) 
     Ground.physicsBody = SKPhysicsBody(rectangleOfSize: Ground.size) 
     Ground.physicsBody!.affectedByGravity = false 
     Ground.physicsBody!.dynamic = false 

     Ground.zPosition = 3 

     self.addChild(Ground) 


     //INizialize 
     animator = UIDynamicAnimator(referenceView: self.view!) 

     //Add Gravity 

     //animator?.addBehavior(gravity, sprite) 




     BlueSquare.size = CGSize(width: 100, height: 100) 
     BlueSquare.position = CGPoint(x: CGFloat(X), y: 1000) 
     BlueSquare.physicsBody?.affectedByGravity = true 
     BlueSquare.physicsBody?.dynamic = false 
     BlueSquare.name = "bluecube" 
     BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20) 
     BlueSquare.color = SKColor.blueColor() 
     // BlueSquare.physicsBody?.velocity = CGVectorMake(0, 0) 

     //BlueSquare.physicsBody?.applyImpulse(CGVectorMake(0, -90)) 
     self.addChild(BlueSquare) 

     let X2 = arc4random() % width 
     RedSquare.size = CGSize(width: 100, height: 100) 
     RedSquare.position = CGPoint(x: CGFloat(X2), y: 1000) 
     RedSquare.physicsBody?.affectedByGravity = true 
     RedSquare.physicsBody?.dynamic = true 
     RedSquare.name = "redcube" 
     RedSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20) 
     RedSquare.hidden = false 

     RedSquare.color = SKColor.redColor() 

     self.addChild(RedSquare) 




     var gameTimer = NSTimer!() 
     gameTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "spawning1", userInfo: nil, repeats: true) 

    } 



    func spawning1() { 


    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     /* Called when a touch begins */ 

     for touch in touches { 
      // let location = touch.locationInNode(self) 
      let currentPoint = touch.locationInNode(self) 
      let currentNode = nodeAtPoint(currentPoint) 
      let nodeName: String? = currentNode.name 


      if nodeName == "bluecube" { 
       BlueSquare.hidden = true 

       score() 
      } 

      if nodeName == "redcube" { 
       RedSquare.hidden = true 

       score() 
      } 

     } 
    } 

    func score() { 
     scorenumber++ 
     print(scorenumber) 
    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
     if CGRectIntersectsRect(RedSquare.frame, Ground.frame) { 
     RedSquare.position = CGPoint(x: RedSquare.position.x, y: RedSquare.position.y + 10) 
     } 
    } 
} 
+0

请不要用大写字母开头变量名。变量名称(和方法名称)是'camelCase',类名称是'CamelCase'。您可以看到格式化程序将您的变量名写入蓝色,因为它认为它们是类名。 – Hamish

回答

2

你的代码是有点乱,所以让我们通过它去

1)首先在您的GameViewController.swift中,您应该在调用第一个场景之前设置此属性

skView.showsPhysics = true 

在测试时帮助您直观地看到您的物理机构。 2)不要将NSTimers用于SpriteKit游戏,而应使用SKActions.waitForDuration。

let timerAction1 = SKAction.waitForDuration(0.5) 
let timerAction2 = SKAction.runBlock(spawning1) 
let timerSequence = SKAction.sequence([timerAction1, timerAction2]) 
runAction(SKAction.repeatActionForever(timerSequence)) 

如果你需要在游戏中无效在某一时刻计时器不是简单地给runAction关键

runAction(SKAction.repeatActionForever(timerSequence), withKey: "SpawnTimer") 

,比删除它,像这样

removeActionForKey("SpawnTimer") 

乍一看,这似乎更多的代码,但相信我,它是一个更好的方式spriteKit游戏。 NSTimers在您暂停场景时不会暂停,或者它们可能会导致场景转换出现问题。尽可能多地使用spriteKit API。

3)在某些精灵你是力展开物理机构

....physicsBody!.affectedByGravity.... 

使用?代替。

....physicsBody?.affectedByGravity.... 

一般在斯威夫特,当你正在处理自选,如physicsBody在这种情况下,始终使用?只要编译器也允许你。

4)在一些你的身体,你要设置的物理属性前,你实际上是给该对象的物理身体

BlueSquare.physicsBody?.affectedByGravity = true 
    BlueSquare.physicsBody?.dynamic = false 
    BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20) // WRONG SPOT 

它应该是这样的

BlueSquare.physicsBody = SKPhysicsBody(circleOfRadius: 20) 
    BlueSquare.physicsBody?.affectedByGravity = true 
    BlueSquare.physicsBody?.dynamic = false 

我们实际的问题我相信你的问题与你的场景大小有关。如果你没有缩放你的场景来适应设备而不是物理边界,那么你给场景的尺寸不会和你期望的大小一样。默认场景大小(GameScene.sks)为1024x768(iPad肖像分辨率)。您的游戏处于横向模式和iPhone上,因此您的场景将被裁剪/缠绕。 要了解更多有关场景缩放模式检查这些物品

http://blog.infinitecortex.com/2014/01/spritekit-understanding-skscene-scalemode/

https://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1

我的问候场景大小最近回答过类似的问题,它也可以帮助你

How to change SKscene size

如果你正在快速学习,作为另一个小技巧,最好遵循文档,例如你的像BlueSquare这样的属性不应该以大写字母开头。只有类,结构和协议应该以大写字母开头。

希望这会有帮助