5

スプライト キットを使用した私のセットアップは次のとおりです。まず、次のように、SKScene 内に単純なスプライト ノードを作成します。

let block = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(90, 160))
block.zPosition = 2
block.shadowCastBitMask = 1
addChild(block)

次に、ライト ノードをシーンに追加します。

let light = SKLightNode()
light.categoryBitMask = 1
light.falloff = 1
addChild(light)

案の定、ブロックは素敵な小さな影を落とします:

アルファ = 1.0 の SKSpriteNode が影を落としている

次に、たとえばアクションを実行して、アルファ値を操作してブロックをフェードします。

let fadeOut = SKAction.fadeAlphaTo(0.0, duration: 5.0)
block.runAction(fadeOut)

ここで厄介な状況があります:ブロックがますます半透明になる一方で、影はまったく同じままです。これは、アクションが終了する直前の様子です。

ここに画像の説明を入力

そして、アルファが完全に 0.0 まで下がると、あるフレームから次のフレームへと影が突然消えます。

ただし、シャドウをキャストするオブジェクトがますます透明になるにつれて、シャドウが徐々に弱くなっていく方がはるかに優れてます

質問:

スプライト キットでこのような効果は可能ですか? もしそうなら、あなたはそれについてどうしますか?

4

2 に答える 2

3

SKLightNodeによってキャストされる影はノードのalphaプロパティの影響を受けないため、これは少し注意が必要です。必要なことは、 のshadowColorプロパティのアルファ チャネルをフェード アウトSKLightNodeすると同時に、 をフェード アウトすることですblock

基本的な手順は次のとおりです。

  1. ライトshadowColorとその色のアルファ チャネルを参照用に保存します。
  2. 次のいずれかを作成しますSKAction.customActionWithDuration
    1. 元のアルファ チャネルの値と、アクションでこれまでに経過した時間に基づいて、アルファ チャネルの値を再計算します。
    2. ライトshadowColorを元の色に設定しますが、新しいアルファ チャネルを使用します。
  3. ブロックのフェード アクションと影のフェード アクションを並行して実行します。

例:

let fadeDuration = 5.0 // We're going to use this a lot

// Grab the light's original shadowColor so we can use it later
let shadowColor = light.shadowColor

// Also grab its alpha channel so we don't have to do it each time
let shadowAlpha = CGColorGetAlpha(shadowColor.CGColor)

let fadeShadow = SKAction.customActionWithDuration(fadeDuration) {
    // The first parameter here is the node this is running on.
    // Ideally you'd use that to get the light, but I'm taking
    // a shortcut and accessing it directly.
    (_, time) -> Void in

    // This is the original alpha channel of the shadow, adjusted
    // for how much time has past while running the action so far
    // It will go from shadowAlpha to 0.0 over fadeDuration
    let alpha = shadowAlpha - (shadowAlpha * time / CGFloat(fadeDuration))

    // Set the light's shadowColor to the original color, but replace
    // its alpha channel our newly calculated one
    light.shadowColor = shadowColor.colorWithAlphaComponent(alpha)
}

// Make the action to fade the block too; easy!
let fadeBlock = SKAction.fadeAlphaTo(0.0, duration: fadeDuration)

// Run the fadeBlock action and fadeShadow action in parallel
block.runAction(SKAction.group([fadeBlock, fadeShadow]))
于 2014-09-26T03:18:16.353 に答える
1

以下は、シャドウとブロックのフェードイン/フェードアウトを一緒にする方法の 1 つです。このアプローチを使用するには、ライトとブロックをクラスのプロパティとして宣言する必要があります。

override func didEvaluateActions() {
    light.shadowColor = light.shadowColor.colorWithAlphaComponent(block.alpha/2.0)
}

編集:上記を実装する方法は次のとおりです。

class GameScene: SKScene {

    let light = SKLightNode()
    let block = SKSpriteNode(color: UIColor.redColor(), size: CGSizeMake(90, 160))

    override func didMoveToView(view: SKView) {

        /* Setup your scene here */
        block.zPosition = 2
        block.shadowCastBitMask = 1
        block.position = CGPointMake(100, 100)

        addChild(block)

        light.categoryBitMask = 1
        light.falloff = 1
        addChild(light)

        let fadeOut = SKAction.fadeAlphaTo(0.0, duration: 5.0);
        let fadeIn = SKAction.fadeAlphaTo(1.0, duration: 5.0);

        block.runAction(SKAction.sequence([fadeOut,fadeIn,fadeOut]))
    }

    override func didEvaluateActions() {
        light.shadowColor = light.shadowColor.colorWithAlphaComponent(block.alpha/2.0)
    }
}
于 2014-09-26T07:53:16.670 に答える