更改场景时出错。(精灵套件)

时间:2016-05-02 19:11:23

标签: ios swift sprite-kit

我正在制作一款游戏,一旦你输了就会把你带到最终场景。结束场景有一个重启按钮,可以将您发送回gamescene。 (这是重启功能。)

 func Restart(){

        self.view?.presentScene(GameScene())
        RestartButton.removeFromSuperview()

    }

由于某种原因,当我运行它时构建失败并且我收到错误消息"无法调用类型' GameScene'的初始化程序。没有参数"。在我添加此代码之前,构建已运行:

 let gamearea: CGRect

    override init(size: CGSize) {


        let maxAspectRatio: CGFloat = 16.0/9.0
        let playableWidth = size.height / maxAspectRatio
        let margin = (size.width - playableWidth) / 2
        gamearea = CGRect(x: margin, y: 0, width: playableWidth, height: size.height)


        super.init(size: size)


    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

此代码需要在此处使其他内容有效。 在我为场景设置大小之前。 请告诉我如何解决这个问题以及为了做到这一点我需要做些什么。 我的完整游戏场景代码如下。

import SpriteKit



struct physicsCatagory {
    static let person : UInt32 = 0x1 << 1
    static let Ice : UInt32 = 0x1 << 2
    static let IceTwo : UInt32 = 0x1 << 3
    static let IceThree : UInt32 = 0x1 << 4
    static let Score : UInt32 = 0x1 << 5
}


class GameScene: SKScene, SKPhysicsContactDelegate {


    func random() -> CGFloat{

        return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
    }
    func random(min min: CGFloat, max: CGFloat) -> CGFloat{
        return random() * (max - min) + min
    }


    let gamearea: CGRect

    override init(size: CGSize) {


        let maxAspectRatio: CGFloat = 16.0/9.0
        let playableWidth = size.height / maxAspectRatio
        let margin = (size.width - playableWidth) / 2
        gamearea = CGRect(x: margin, y: 0, width: playableWidth, height: size.height)


        super.init(size: size)


    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    var timeOfLastSpawn: CFTimeInterval = 0.0
    var timePerSpawn: CFTimeInterval = 1.2
    var scorenumber = Int()
    var lifenumber = Int()
    var SpeedNumber : Double = 0.5
    var person = SKSpriteNode(imageNamed: "Person1")
    let Score = SKSpriteNode()
    var ScoreLable = SKLabelNode()
    let BackGround = SKSpriteNode (imageNamed: "BackGround")


    override func didMoveToView(view: SKView) {





        physicsWorld.contactDelegate = self

        //self.scene?.size = CGSize(width: 640, height: 1136)

        lifenumber = 0
        SpeedNumber = 1

        BackGround.size = CGSize(width: self.frame.width, height: self.frame.height)
        BackGround.position = CGPointMake(self.size.width / 2, self.size.height / 2)
        BackGround.zPosition = -5
        self.addChild(BackGround)


         Score.size = CGSize(width: 1563, height: 1)
        Score.position = CGPoint(x: 320, y: -90)
        Score.physicsBody = SKPhysicsBody(rectangleOfSize: Score.size)
        Score.physicsBody?.affectedByGravity = false
        Score.physicsBody?.dynamic = false
        Score.physicsBody?.categoryBitMask = physicsCatagory.Score
        Score.physicsBody?.collisionBitMask = 0
        Score.physicsBody?.contactTestBitMask = physicsCatagory.IceThree
        Score.color = SKColor.blueColor()
        self.addChild(Score)


        person.zPosition = 1
        person.position = CGPointMake(self.size.width/2, self.size.height/10)
        person.setScale(0.6)
        person.physicsBody = SKPhysicsBody (rectangleOfSize: CGSize(width: 40, height: 50))
        person.physicsBody?.affectedByGravity = false
        person.physicsBody?.categoryBitMask = physicsCatagory.person
        person.physicsBody?.contactTestBitMask = physicsCatagory.Ice
        person.physicsBody?.collisionBitMask = physicsCatagory.Ice
        person.physicsBody?.dynamic = false




        ScoreLable = SKLabelNode(fontNamed: "Zapfino")
        ScoreLable.position = CGPoint(x: self.frame.width / 2, y: 1700)
        ScoreLable.text = "\(scorenumber)"
        ScoreLable.fontColor = UIColor.yellowColor()
        ScoreLable.fontSize = 150
        ScoreLable.fontName = "Zapfino "
        self.addChild(ScoreLable)





        self.addChild(person)





    }




     func didBeginContact(contact: SKPhysicsContact) {
            let firstBody = contact.bodyA
            let secondBody = contact.bodyB


        if firstBody.categoryBitMask == physicsCatagory.person && secondBody.categoryBitMask == physicsCatagory.IceThree || firstBody.categoryBitMask == physicsCatagory.IceThree && secondBody.categoryBitMask == physicsCatagory.person{

           scorenumber++

            if scorenumber == 20 {

              timePerSpawn = 1.0

            }

            if scorenumber == 40{
                timePerSpawn = 0.89

            }
            if scorenumber == 60{

                timePerSpawn = 0.6
            }
            if scorenumber == 80{

                timePerSpawn = 0.5
            }

            if scorenumber == 100{

                timePerSpawn = 0.4
            }

            if scorenumber == 120{

                timePerSpawn = 0.3
            }



            ScoreLable.text = "\(scorenumber)"
            CollisionWithPerson(firstBody.node as! SKSpriteNode, Person: secondBody.node as! SKSpriteNode)


        }

        if firstBody.categoryBitMask == physicsCatagory.Score && secondBody.categoryBitMask == physicsCatagory.IceThree ||
            firstBody.categoryBitMask == physicsCatagory.IceThree && secondBody.categoryBitMask == physicsCatagory.Score{
                lifenumber++

                if lifenumber == 1{
                    //person.texture
                    person.texture = SKTexture (imageNamed: "Flower#2")
                }

                if lifenumber == 2{
            person.texture = SKTexture (imageNamed: "Flower #3")

        }
                if lifenumber == 3{
                    self.view?.presentScene(EndScene())

                }


        }
    }



    func CollisionWithPerson (Ice: SKSpriteNode, Person: SKSpriteNode){

      Person.removeFromParent()

    }



    func spawnThirdIce(){

        var Ice = SKSpriteNode(imageNamed: "Ice")
        Ice.zPosition = 2
        Ice.setScale(1.5)
        Ice.physicsBody = SKPhysicsBody(rectangleOfSize: Ice.size)
        Ice.physicsBody?.categoryBitMask = physicsCatagory.IceThree
        Ice.physicsBody?.contactTestBitMask = physicsCatagory.person | physicsCatagory.Score
        Ice.physicsBody?.affectedByGravity = false
        Ice.physicsBody?.dynamic = true

        let randomXStart = random(min:CGRectGetMinX(gamearea), max: CGRectGetMaxX(gamearea))
        let randomXend = random(min:CGRectGetMinX(gamearea),max: CGRectGetMaxX(gamearea))

        let startPoint = CGPoint(x: randomXStart, y: self.size.height * 1.2)
        let endpoint = CGPoint(x: randomXend, y: -self.size.height * 0.2)
        Ice.position = startPoint
        let moveEnemy = SKAction.moveTo(endpoint, duration: 2.0)
        let deleteEnemy = SKAction.removeFromParent()
        let enemySequence = SKAction.sequence([moveEnemy , deleteEnemy])
        Ice.runAction(enemySequence)
       // let MinValue = self.size.width / 8
        //let MaxValue = self.size.width - 20
       // let SpawnPoint =  UInt32(MaxValue - MinValue)
       // Ice.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
        self.addChild(Ice)

        //let action = SKAction.moveToY(-85, duration: 2.0)
        //let actionDone = SKAction.removeFromParent()
        //Ice.runAction(SKAction.sequence([action,actionDone]))


    }



    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

            }
    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)
            let previousTouch = touch.previousLocationInNode(self)
            let ammountDragged = location.x - previousTouch.x


            person.position.x += ammountDragged


            if person.position.x > CGRectGetMaxX(gamearea) - person.size.width/2{
                person.position.x = CGRectGetMaxX(gamearea) - person.size.width/2
            }

                if person.position.x <  CGRectGetMinX(gamearea) + person.size.width/2{
                    person.position.x = CGRectGetMinX(gamearea) + person.size.width/2

                }








        }
    }




    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
        if (currentTime - timeOfLastSpawn > timePerSpawn) {
            spawnThirdIce()
            self.timeOfLastSpawn = currentTime
        }
    }




}

1 个答案:

答案 0 :(得分:1)

问题在于你的游戏场景类传递了一个init方法(大小)。

class GameScene: SKScene, SKPhysicsContactDelegate {
  ...
  override init(size: CGSize) {...

但是,在重启func中,你没有调用这个init。

更改此行

self.view?.presentScene(GameScene())

到这一行

self.view?.presentScene(GameScene(size: self.size)) // same size as current scene

我还建议您在gameScene类中使用didMoveToView而不是init方法。

此外,我建议您使用SKNodes / SKSpriteNodes作为按钮而不是UIButtons。 UIButtons被添加到视图中,而不是在SpriteKit游戏中不是你想要的SKScene。 一个简单的版本可能看起来像这样

https://nathandemick.com/programming/tutorial/2014/09/23/buttons-sprite-kit-using-swift.html

对于更高级的版本,您可以查看Apples示例游戏&#34; DemoBots&#34;

另外作为一般提示,您应遵循快速指南。 只有类,枚举协议和结构应以大写字母开头,而您的属性/方法应以小写字母开头。它使您的代码更难以自己和Stackoverflow读取,因为属性标记为蓝色但不应该。

希望这有帮助