重新创建完全相同的球,HTML5 到 SpriteKit

问题描述 投票:0回答:1

我有以下 SCSS 代码来定义游戏中的球:

$color-green-dark: #226f54;

$color-cream: #f4f0bb;
$color-coffee: #7b4b39;
$color-brown: #43291f;

.ballType1 {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;

  &::after {
    content: '';
    width: 60%;
    height: 60%;
    border-radius: 50%;

    box-shadow: 2px 2px 5px #00000030;

    background-image: radial-gradient(
      circle at 40% 40%,
      mix($color-cream, $color-coffee, 90%) 5%,
      mix($color-cream, $color-coffee, 40%) 50%,
      mix($color-cream, $color-brown, 10%) 80%
    );
  }
}

它呈现出我想要的效果:

我尝试用 SpriteKit 重新创建同一个球,但这不是我想要的:

我最终得到的代码是(GameScene):

    override func didMove(to view: SKView) {
        super.didMove(to: view)
        
        // Setup your scene initial state here
        self.backgroundColor = SKColor.greenDark
        
        addBall()
    }
    
    func addBall() {
        let ballRadius = 100.0
        let ball = SKShapeNode(circleOfRadius: ballRadius)
        ball.position = CGPoint(x: 40, y: 70)
        
        let shader = SKShader(source: """
            void main() {
                float dist = distance(v_tex_coord, vec2(0.4, 0.4));
                vec3 color = mix(vec3(0.957, 0.941, 0.733), vec3(0.482, 0.294, 0.224), smoothstep(0.05, 0.5, dist));
                color = mix(color, vec3(0.259, 0.161, 0.122), smoothstep(0.5, 0.8, dist));
                gl_FragColor = vec4(color, 1.0);
            }
        """)
        
        ball.fillShader = shader
        ball.strokeColor = SKColor.clear
        
        let shadowNode = SKShapeNode(circleOfRadius: ballRadius)
        shadowNode.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.19)
        shadowNode.strokeColor = SKColor.clear
        shadowNode.position = CGPoint(x: 2, y: -2)
        shadowNode.zPosition = -1
        
        let shadowBlurNode = SKEffectNode()
        shadowBlurNode.shouldRasterize = true
        shadowBlurNode.filter = CIFilter(name: "CIGaussianBlur", parameters: ["inputRadius": 5])
        shadowBlurNode.addChild(shadowNode)
        
        ball.addChild(shadowBlurNode)
        
        addChild(ball)
    }

当您将半径更改为 20 时,事情会变得非常混乱。看起来不太好。

我正在寻找更好地渲染它的方法,我有什么选择?我倾向于创建 SVG,并以某种方式导入它。我不太擅长着色器,尝试了多个参数但运气不佳。

也许我遗漏了一些明显的东西?如何从 HTML/CSS 重新创建同一个球?

我尝试使用着色器手动重新创建事物。编辑着色器,但只会变得更加混乱。

swift sprite-kit
1个回答
0
投票

事实证明我的颜色转换不正确。我最后得到了这个:

虽然不完美,但仍然有所作为。这是更新后的代码:

    func addBall() {
        let ballRadius = 100.0
        let ball = SKShapeNode(circleOfRadius: ballRadius)
        ball.position = CGPoint(x: frame.midX, y: frame.midY)  // Centering the ball at the middle of the screen

        let shader = SKShader(source: """
            void main() {
                float dist = distance(v_tex_coord, vec2(0.4, 0.4)); // Adjust center to 40%, 40%
                vec3 colorCream = vec3(0.957, 0.941, 0.733);
                vec3 colorCoffee = vec3(0.482, 0.294, 0.224);
                vec3 colorBrown = vec3(0.263, 0.161, 0.122);
                vec3 mixedColor1 = mix(colorCream, colorCoffee, 0.1);  // 90% cream, 10% coffee
                vec3 mixedColor2 = mix(colorCream, colorCoffee, 0.6);  // 40% cream, 60% coffee
                vec3 mixedColor3 = mix(colorCream, colorBrown, 0.9);  // 10% cream, 90% brown
                vec3 color = mix(mixedColor1, mixedColor2, smoothstep(0.05, 0.5, dist));
                color = mix(color, mixedColor3, smoothstep(0.5, 0.8, dist));
                gl_FragColor = vec4(color, 1.0);
            }
        """)

        ball.fillShader = shader
        ball.strokeColor = SKColor.clear

        let shadowNode = SKShapeNode(circleOfRadius: ballRadius)
        shadowNode.fillColor = UIColor.black.withAlphaComponent(0.19)
        shadowNode.strokeColor = SKColor.clear
        shadowNode.position = CGPoint(x: 2, y: -2)
        shadowNode.zPosition = -1

        let shadowBlurNode = SKEffectNode()
        shadowBlurNode.shouldRasterize = true
        shadowBlurNode.filter = CIFilter(name: "CIGaussianBlur", parameters: ["inputRadius": 5])
        shadowBlurNode.addChild(shadowNode)

        ball.addChild(shadowBlurNode)

        addChild(ball)
    }

我还有一些想要修复的问题。由于 HTML 中的球看起来更好一点,所以你想亲吻它:

我不知道为什么。仍在寻找如何 100% 重现它的答案。

© www.soinside.com 2019 - 2024. All rights reserved.