SpriteKit:精灵在高速下看起来很模糊(有重影)但在低速下很精细

时间:2017-11-16 01:59:12

标签: ios iphone sprite-kit skspritenode skscene

在SpriteKit中使用高速(线性或角度)时,精灵看起来很模糊,好像有一个“幽灵”跟踪精灵。精灵在低速时看起来很好。

下面是截图和GIF,说明高线速度的模糊/重影问题,但 angularVelocity 属性也会出现问题。

球码(使用下面的SKScene重现模糊):

    let radius = CGFloat(8)

    let body = SKPhysicsBody(circleOfRadius: radius)
    body.isDynamic = true
    body.affectedByGravity = false
    body.allowsRotation = true
    body.friction = 0
    body.restitution = 0.0
    body.linearDamping = 0.0
    body.angularDamping = 0
    body.categoryBitMask = categoryBitMask

    let ball = SKShapeNode(circleOfRadius: radius)
    ball.physicsBody = body
    ball.physicsBody?.velocity.dx = 0
    ball.physicsBody?.velocity.dy = -1200

看起来很好:

ball.physicsBody?.velocity.dy = -200

看起来模糊:

ball.physicsBody?.velocity.dy = -1200

截图:

enter image description here

GIF:

enter image description here

SKScene(放入项目和现场看模糊):

import Foundation
import SpriteKit


class TestScene : SKScene, SKPhysicsContactDelegate {
    let BallBitMask                   : UInt32 = 0x1 << 1
    let BottomWallBitMask             : UInt32 = 0x1 << 3
    let TopWallBitMask                : UInt32 = 0x1 << 4
    let RightWallBitMask              : UInt32 = 0x1 << 5
    let LeftWallBitMask               : UInt32 = 0x1 << 6

    let SceneBackgroundColor = UIColor(red: 58/255.0, green: 50/255.0, blue: 96/255.0, alpha: 1.0)

    let HorizontalWallHeight = CGFloat(10)
    let VerticallWallWidth = CGFloat(5)

    override init() {
        super.init()
    }


    override init(size: CGSize) {
        super.init(size: size)
        doInit()
    }


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


    fileprivate func doInit() {
        // Set background
        backgroundColor = SceneBackgroundColor

        // Set scale mode
        scaleMode = .resizeFill

        // Set anchor point to screen center
        anchorPoint = CGPoint(x: 0.5, y: 0.5)

        // Add walls
        layoutWalls()

        // Create ball
        let radius = CGFloat(8)
        let body = SKPhysicsBody(circleOfRadius: radius)
        body.isDynamic = true
        body.affectedByGravity = false
        body.allowsRotation = true
        body.friction = 0
        body.restitution = 0.0
        body.linearDamping = 0.0
        body.angularDamping = 0
        body.categoryBitMask = BallBitMask
        body.collisionBitMask =  TopWallBitMask | RightWallBitMask | BottomWallBitMask | LeftWallBitMask

        let ball = SKShapeNode(circleOfRadius: radius)
        ball.fillColor = UIColor.orange
        ball.physicsBody = body
        ball.physicsBody?.velocity.dx = 0
        ball.physicsBody?.velocity.dy = -1200

        // Add ball to scene
        addChild(ball)
    }


    fileprivate func layoutWalls() {
        // Set wall offset
        let wallOffset = CGFloat(3)

        // Layout bottom wall
        let bottomWallSize = CGSize(width: UIScreen.main.bounds.width, height: HorizontalWallHeight)
        let bottomWall = SKSpriteNode(color: UIColor.red, size: bottomWallSize)
        bottomWall.position.y = -UIScreen.main.bounds.height/2 - bottomWallSize.height/2 - wallOffset
        bottomWall.physicsBody = createWallPhysics(categoryBitMask: BottomWallBitMask, wallSize: bottomWallSize)
        addChild(bottomWall)

        // Layout top wall
        let topWallSize = CGSize(width: UIScreen.main.bounds.width, height: HorizontalWallHeight)
        let topWall = SKSpriteNode(color: UIColor.red, size: topWallSize)
        topWall.position.y = UIScreen.main.bounds.height/2 + topWallSize.height/2 + wallOffset
        topWall.physicsBody = createWallPhysics(categoryBitMask: TopWallBitMask, wallSize: topWallSize)
        addChild(topWall)

        // Layout right wall
        let rightWallSize = CGSize(width: VerticallWallWidth, height: UIScreen.main.bounds.height)
        let rightWall = SKSpriteNode(color: UIColor.blue, size: rightWallSize)
        rightWall.position.x = UIScreen.main.bounds.width/2 + rightWallSize.width/2 + wallOffset
        rightWall.physicsBody = createWallPhysics(categoryBitMask: RightWallBitMask, wallSize: rightWallSize)
        addChild(rightWall)

        // Layout left wall
        let leftWallSize = CGSize(width: VerticallWallWidth, height: UIScreen.main.bounds.height)
        let leftWall = SKSpriteNode(color: UIColor.blue, size: leftWallSize)
        leftWall.position.x = -UIScreen.main.bounds.width/2 - leftWallSize.width/2 - wallOffset
        leftWall.physicsBody = createWallPhysics(categoryBitMask: LeftWallBitMask, wallSize: leftWallSize)
        addChild(leftWall)
    }


    fileprivate func createWallPhysics(categoryBitMask: UInt32, wallSize: CGSize) -> SKPhysicsBody {
        // Create new physics body for wall
        let physicsBody = SKPhysicsBody(edgeLoopFrom: CGRect(x: -wallSize.width/2, y: -wallSize.height/2, width: wallSize.width, height: wallSize.height))
        physicsBody.isDynamic = true
        physicsBody.friction = 0
        physicsBody.restitution = 1.0
        physicsBody.linearDamping = 0
        physicsBody.angularDamping = 0.0
        physicsBody.categoryBitMask = categoryBitMask

        // Return body
        return physicsBody
    }
}

1 个答案:

答案 0 :(得分:2)

其中哪一个看起来更加神奇?

&#34;技巧&#34;是由眼睛执行。我们没有能力以低速60fps处理快速移动物体的屏幕。我们通过虚假的视觉持久性在屏幕上保持一个图像,因此我们的大脑和意识可以计算出事物的移动速度和移动速度。在屏幕上。

在现实生活中,我们得到了近乎无数的&#34;帧&#34;处理运动,深度和各种其他线索,所以我们很少在任何地方做到这一点。

我们仍然这样做,但它不太明显,因为我们已经接近无限数量的帧。

以下三张图片以不同的方式表达不同的东西。

第一个是线速度,立即加速到其旋转速度并立即停止。

第二个具有斜坡上升并下降到其转速,该转速具有更高的峰值旋转速度。这对大脑产生了一种有趣的影响,使其能够为即将实现的速度做好准备。

决赛有很多假运动模糊(对于真实世界的动态图形使用来说太多),它显示了模糊效果在解决这个问题的效果方面的效果,以及慢速快门对电影制作如此重要的原因。 / p>

线性旋转速度: enter image description here

加速和减速:

enter image description here

严重模糊:

enter image description here