SpriteKit:SKSpriteNodes 之间的差距

Posted

技术标签:

【中文标题】SpriteKit:SKSpriteNodes 之间的差距【英文标题】:SpriteKit: A gap between SKSpriteNodes 【发布时间】:2017-06-23 19:50:45 【问题描述】:

当蓝色方块落在红色方块上时,会留下一个间隙。但是当我让蓝色方块从较低的位置落下时,没有间隙。同样,当我给蓝色方块一个更高的质量时,红色方块下方的间隙(在地面上)消失了,当质量太高时,红色方块消失了。 我还使正方形更小,因为像素的数量不等于 png 文件的像素,这导致了更大的间隙。而且,当我将“showsPhysics”设置为 true 时,还有一个可以看到的差距,当正方形没有按比例缩小时甚至更大。

Gap between SKSpriteNodes (picture)

//: Playground - noun: a place where people can play

import UIKit
import SpriteKit
import PlaygroundSupport


class Scene: SKScene 

var square = SKSpriteNode(texture: SKTexture(imageNamed: "red"), size: SKTexture(imageNamed: "red").size())
var square2 = SKSpriteNode(texture: SKTexture(imageNamed: "blue"), size: SKTexture(imageNamed: "blue").size())
var label = SKLabelNode(fontNamed: "Chalkduster")

override func didMove(to view: SKView) 
    self.addChild(square)
    self.addChild(square2)
    self.addChild(label)


override func didChangeSize(_ oldSize: CGSize) 


    // Add Scene Physics
    self.physicsBody?.usesPreciseCollisionDetection = true
    self.physicsBody = SKPhysicsBody(edgeLoopFrom: CGRect(x: -1, y: -1, width: self.size.width + 2, height: self.size.height + 2))
    self.backgroundColor = UIColor.white
    self.physicsBody?.usesPreciseCollisionDetection = true


    //Add square
    square.texture?.usesMipmaps = true
    square.zPosition = 11
    square.physicsBody = SKPhysicsBody(rectangleOf: square.size)
    square.physicsBody?.usesPreciseCollisionDetection = true
    square.physicsBody?.mass = 0.1
    square.physicsBody?.allowsRotation = false
    square.physicsBody?.usesPreciseCollisionDetection = true
    square.setScale(0.25)
    square.position = CGPoint(x: self.frame.width / 2, y: self.square.size.height)
    square.name = "square"


    //Add square2
    square2.texture?.usesMipmaps = true
    square2.zPosition = 11
    square2.physicsBody = SKPhysicsBody(rectangleOf: square2.size)
    square2.physicsBody?.usesPreciseCollisionDetection = true
    square2.physicsBody?.mass = 0.1
    square2.physicsBody?.allowsRotation = false
    square2.physicsBody?.usesPreciseCollisionDetection = true
    square2.setScale(0.25)
    square2.position = CGPoint(x: self.frame.width / 2, y: self.square.size.height * 6)
    square2.name = "square2"

    //Add label
    label.fontSize = 30
    label.text = "w: \(self.frame.size.width) h: \(self.frame.size.height)"
    label.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height - 30)
    label.fontColor = UIColor.black
    label.zPosition = 100





class ViewController: UIViewController 

let scene = Scene()
var viewSize = CGSize(width: 0, height: 0)

override func loadView() 
    self.view = SKView()



override func viewDidLoad() 
    super.viewDidLoad()

    if let view = self.view as! SKView? 
        view.frame = CGRect(origin: CGPoint(x: -1, y: -1), size: viewSize)
        view.presentScene(scene)
        view.showsPhysics = false
        view.showsFPS = true
        view.showsNodeCount = true

    



override func viewDidLayoutSubviews() 
    super.viewDidLayoutSubviews()

    scene.size = CGSize(width: self.view.frame.size.width, height: self.view.frame.size.height)


PlaygroundPage.current.liveView = ViewController()

【问题讨论】:

当您开启 showPhysics 时,总会有感知到的差距,但没有实际差距。 我很好奇这些节点的框架。你能告诉我topNode.frame.minY 是什么,bottomNode.frame.maxY 是什么吗?这可能与纹理有关,而不是实际节点的框架属性。 您能否也上传纹理,以便我们下载它们进行测试。谢谢 topNode.frame.minY = 100.822998046875 bottomNode.frame.maxY = 100.657000005245 我只是认为现在物理学不是100%,这可能是答案..如果这是真正的答案我没问题用它。 4 像素 (2x2) 等于代码中的 1 像素。 override func update(_ currentTime: TimeInterval) 当我使用这个函数并更新physicsBody 时,每次节点的位置发生变化时它都会修复所有问题。但这不能作为答案,如果您有很多节点,那么代码太多并且需要更多的 CPU 功率 【参考方案1】:

作为来自print 命令的证明,精灵节点之间没有实际的间隙,并且来自超级放大的屏幕截图的第二个证明:

您提供的游乐场没有复制问题,这让我想知道...您的项目是怎么回事?

第 2 页:

【讨论】:

你的价值观和我一样吗?场景的宽度和高度也相同?您可以看到标签上显示的尺寸。 但是你可以看到你在地面上有一个缺口。试试这个github.com/simon2204/Playgrounds 地面上没有缝隙了,只有立方体之间。 @S.Sch 它发生在你的操场上??我不明白怎么做。代码很好。 当你创建一个带有纹理的physicsBody时,差距真的很大,你甚至无法修复alphaThreshold。【参考方案2】:

场景的宽度和高度必须乘以 2。所以场景必须比 ViewControllers 视图大 4 倍。在苹果为 Spritekit 提供的游戏模板中也是如此。

scene.size = CGSize(width: self.view.frame.size.width * 2, height: self.view.frame.size.height * 2)

https://github.com/simon2204/Playground

【讨论】:

以上是关于SpriteKit:SKSpriteNodes 之间的差距的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit 和 Swift 中 SKSpriteNodes 的 setScale 和 size 有啥区别?

SpriteKit SKSpriteNodes 管理

SpriteKit:SKSpriteNode 包含另一个 SKSpriteNodes 但只有一个 SKPhysicsBody

Sprite Kit:屏幕上的 SKSpriteNodes 计数

Swift SpriteKit SKSpriteNode 的“有时”不显示

如何检测 SKSpriteNode 和 SKView SpriteKit 之间的冲突