簡體   English   中英

我沒有在Swift中創建的東西的SKSpriteNode彈跳

[英]SKSpriteNode bouncing of something I didn't create in 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)
        }
    }
}

您的代碼有點混亂,所以讓我們來看一下

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....

通常,在Swift中,當您處理可選內容時(例如本例中的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

我最近在場景大小方面回答了類似的問題,它可能也對您有所幫助

如何更改SKscene大小

作為進一步的提示,如果您快速學習,則遵循文檔是個好習慣,因此,例如,BlueSquare之類的屬性不應以大寫字母開頭。 僅類,結構和協議應以大寫字母開頭。

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM