基本的 swift/spritekit 游戏 - 麻烦重绘

Posted

技术标签:

【中文标题】基本的 swift/spritekit 游戏 - 麻烦重绘【英文标题】:Basic swift/spritekit game - trouble redrawing 【发布时间】:2016-02-17 11:27:47 【问题描述】:

我一直在玩 swift,并一直在尝试制作一个基于图块的游戏,它具有滚动视图,因此玩家处于中心位置。我有经理让它开始工作,但我似乎正在重新绘制当前存在的所有节点,所以经过几次移动后,我有 1000 多个节点,游戏就停止了。我猜我需要在绘制新节点之前删除所有旧节点?我已经研究过如何做到这一点,比如移除孩子,但在移动后我最终没有绘制任何内容。

我已经包含了与下面的精灵图相关的部分。

func placeTile2D(tile:Tile, direction:Direction, position:CGPoint) 
    let tileSprite = SKSpriteNode(imageNamed: textureImage(tile, direction: direction, action: Action.Idle))
    if (tile == hero.tile) 
        hero.tileSprite2D = tileSprite
        hero.tileSprite2D.zPosition = 1
    
    tileSprite.position = position
    tileSprite.anchorPoint = CGPoint(x:0,y:0)
    view2D.addChild(tileSprite)


func placeAllTiles2D() 
    let playerPosCur = playerPosition
    let playerPCX: Int = (Int(playerPosCur.x))
    let playerPCY: Int = (-Int(playerPosCur.y))
    var w = 1
    var h = 1
    for i in (playerPCY - 4) ..< (playerPCY + 4)
        let row = tiles[i];
        w = 1
        for j in playerPCX - 4 ..< playerPCX + 4 
            let tile = Tile(rawValue: row[j].0)!
            let direction = Direction(rawValue: row[j].1)!

            let point = CGPoint(x: (w*tileSize.width), y: -(h*tileSize.height))

            if w == 5 
                if h == 5 
                    self.placeTile2D(Tile.Player, direction: .n, position: point)
                
            

            w = w + 1

            placeTile2D(tile, direction : direction, position : point)
        
        h = h + 1
    

是我用来在玩家周围绘制瓷砖的,然后在下面是我用来改变玩家位置的东西,然后调用 placeAllTiles2D() 函数根据新位置重绘。

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) 
    if let touch = touches.first 
        let location = touch.locationInNode(view2D)
        let touchPos2D = location
        let moveXR = CGPoint(x:1,y:0)
        let moveXL = CGPoint(x:-1,y:0)
        let moveYU = CGPoint(x:0,y:1)
        let moveYD = CGPoint(x:0,y:-1)
        let beforeMove = playerPosition
        var afterMove = CGPoint(x:0,y:0)

        if touchPos2D.x > self.size.width*3/4 
            //Move player to right
            afterMove = beforeMove + moveXR
        
        if touchPos2D.x < self.size.width*1/4 
            //Move Player to left
            afterMove = beforeMove + moveXL
        
        if touchPos2D.y > -self.size.height/2 
            if touchPos2D.x < self.size.width*3/4 && touchPos2D.x > self.size.width*1/4 
                //Move PLayer Up
                afterMove = beforeMove + moveYU
            
        
        if touchPos2D.y < -self.size.height/2 
            if touchPos2D.x < self.size.width*3/4 && touchPos2D.x > self.size.width*1/4 
                //Move Player Down
                afterMove = beforeMove + moveYD
            
        


        playerPosition = afterMove
        placeAllTiles2D()

    

任何帮助将不胜感激。 请温柔一点,这是我第一次快速做任何事情!

【问题讨论】:

如果你一直只创建新的精灵,那么是的,最终你会达到性能上限。要么删除不需要的精灵并创建新精灵,要么只是移动/调整它们而不是创建新精灵。 @AntonBronnikov 感谢您的回复,似乎很公平,我需要删除旧的精灵,我只是想知道如何做到这一点,如果我做类似 self.removeAllChildren() 的事情 在放置新精灵之前,然后在移动之后,当我运行应用程序时,什么都不会绘制 我认为您需要先阅读一些内容。这个tutorial 是初学者。阅读 Apple 的 SpriteKit Programming Guide 也不会受到伤害。要回答您的问题,有不同的技术可以删除精灵。您可以为它们分配名称并删除具有特定名称的精灵,您可以对它们触发删除操作,您可以将它们分组到某个特殊节点下并在其上使用 removeAllChildren。 好的,非常感谢您的帮助!我想我今晚要读书了! 【参考方案1】:

您需要使用SKCameraNode 并将其视为移动视口而不是生成图块并在每一帧重新绘制它们。 Here's a good example

基本上是这样工作的:

var sceneCam: SKCameraNode! //declare your camera variable in your scene class

然后,在您的 didMoveToView 函数中:

sceneCam = SKCameraNode() //initialize your camera
//scaleAsPoint lets you zoom the camera in and out
sceneCam.scaleAsPoint = CGPoint(x: 0.25, y: 0.25) 

camera = sceneCam  //set the scene's camera
addChild(sceneCam) //add camera to scene

//position the camera on the gamescene.
sceneCam.position = CGPoint(x: frame.center.x, y: frame.center.y)

现在,当您四处移动播放器时,只需将相机设置到与播放器相同的位置,您就会拥有滚动场景。我同意cmets。如果你回顾一下 sprite kit 的一些基础知识,你会在这方面有一个更好的时间——了解它附带的所有东西,你可以避免忽视像 SKCameraNode 这样的东西。 SpriteKit 为您做了很多事情,比如这个相机概念,可以帮助您快速轻松地制作游戏。

【讨论】:

以上是关于基本的 swift/spritekit 游戏 - 麻烦重绘的主要内容,如果未能解决你的问题,请参考以下文章

Swift,SpriteKit:释放游戏场景并重新分配新场景

swift spritekit 随着游戏时间的推移增加重力?

为啥我的声音让我的游戏在 Swift Spritekit 中滞后?

在我的 swift SpriteKit 游戏中,物理体的轮廓通过所有其他节点显示

如何在swift(SpriteKit)中绘制一个作为单个节点的圆点[关闭]

Swift,SpriteKit:如何保存场景的整个进度