前のページ

前のページの雪を降らせるコードを参考に、流れ星の表現をつくってみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
func design( screen:PGScreen ) {
    screen.clearColor = LLColor( 0.0, 0.05, 0.2, 1.0 )
    
    for _ in 0 ..< 10 {
        let size = (40.0 ... 80.0).randomize
        let speed = size / 80.0
        let c = LLColor( 1.0, 0.8, 0.25, Float( speed ) )
        
        PGAddMask( "mask-star" )
        .color( c )
        .position( 
            cx:(screen.minX-200...screen.maxX+200).randomize,
            cy:(screen.minY...screen.maxY).randomize
        )
        .deltaPosition( 
            dx:(10.0 ... 12.0).randomize * speed,
            dy:(-1.5 ... 3.5).randomize * speed
        )
        .scale( square:size )
        .angle( .random )
        .deltaAngle( degrees:-4.0 * speed )
        .iterate {
            $0.deltaPosition.y -= 0.05
                        
            if Float( screen.maxX + 200.0 ) <= $0.position.x {
                $0
                .position( 
                    cx:screen.minX-200,
                    cy:(screen.minY...screen.maxY).randomize
                )
                .deltaPosition( 
                    dx:(10.0 ... 12.0).randomize * speed,
                    dy:(-1.5 ... 3.5).randomize * speed
                )
            }
        }    
        .interval( sec:0.05 ) {
            PGAddCircle()
            .color( c )
            .position( $0.position )
            .scale( square:0 )
            .deltaScale( dw:0.5 * speed, dh:0.5 * speed )
            .alpha( 0 )
            .deltaLife( -0.02 )
            .iterate {
                $0.alpha( sin( $0.life * Float.pi ) * 0.5 )
            }
        }
    }
}

  1. screen.clearColor = LLColor( 0.0, 0.05, 0.2, 1.0 ) で背景を群青色にします。

  1. forで、10回繰り返します。

  1. forの中に、初期設定に必要な変数をつくります。
    • let size = (40.0 ... 80.0).randomize
      • 大きさ用の変数。40.0~80.0のランダム値をつくり、代入します。
    • let speed = size / 80.0
      • 速度用の変数。sizeに合わせて0.5~1.0の値をつくり、代入します。
    • let c = LLColor( 1.0, 0.8, 0.25, Float( speed ) )
      • 色用の変数。少し赤めの黄色を作成し代入します。またアルファにspeedの値を設定します。

  1. forの中で、加算合成マスク画像 PGAddMask( "mask-star" ) をつくります。星の画像を指定します。

  1. 初期設定のコードを書きます。
    • .color( c )
      • 色。変数cを指定します。
    • .position( cx:(screen.minX-200...screen.maxX+200).randomize, cy:(screen.minY...screen.maxY).randomize )
      • 位置。x方向は左端-200~右端+200のランダム、 y方向は上端~下端ポイントのランダム座標に設定します。(画面全体から横にはみ出した範囲にランダムに配置されます。前回は縦でした。今回は横です)
    • .deltaPosition( dx:(10.0 ... 12.0).randomize * speed, dy:(-1.5 ... 3.5).randomize * speed )
      • 毎フレームの移動量。x方向は10.0~12.0ポイントのランダム、 y方向は-1.5~3.5のランダムに、変数speedを掛け算した値を設定します。(星が右方向へ移動します)
    • .scale( square:size )
      • 大きさ。変数sizeを設定します。
    • .angle( .random )
      • 角度。ランダムを設定します。
    • .deltaAngle( degrees:-4.0 * speed )
      • 毎フレームの回転量。-4.0に変数speedを掛け算した値を設定します。(星が時計回りに回転します)

  1. .iterate{ } を用意します。y方向の移動量を調整します。また図形の再利用のタイミングをうかがいます。

    • $0.deltaPosition.y -= 0.05
      • 毎フレーム、y方向の移動量を0.05減らします。(下方向へ速くなります)
    • if Float( screen.maxX + 200.0 ) <= $0.position.x
      • 図形が画面の右端から200ポイントはみ出したとき、{ }の中の処理を行います。
    • .position( cx:screen.minX-200, cy:(screen.minY...screen.maxY).randomize )
      • x方向は左端-200ポイント、y方向は下端~上端のランダムの位置に再配置します。
    • .deltaPosition( dx:(10.0 ... 12.0).randomize * speed, dy:(-1.5 ... 3.5).randomize * speed )
      • 毎フレームの移動量を初期化します。

  1. .interval( sec:0.05 ) { } を用意します。0.05秒ごとに定期的に実行されます。内部で加算合成の円(PGAddCircle())を作ります。その円に以下の設定を行います。

    • .color( c )
      • 色。変数cを設定します。
    • .position( $0.position )
      • 位置。星の現在位置 $0.position を設定します。
    • .scale( square:0 )
      • 大きさ。0を設定します。
    • deltaScale( dw:0.5 * speed, dh:0.5 * speed )
      • 毎フレーム、0.5にspeedを掛け算したポイントを大きさに足します。
    • .alpha( 0 )
      • アルファ。透明を設定します。
    • .deltaLife( -0.02 )
      • 毎フレーム、lifeを0.02減少します。

  1. 7で作成した加算合成の円に.iterate{ } を追加します。
    • .alpha( sin( $0.life * Float.pi ) * 0.5 )
      • アルファにlifeに合わせたサイン値に、0.5を掛け算した値を設定します。

  1. 「コードを実行」を押します。

目標

  • 星が飛ぶエフェクトが表示されたら成功です。

次のページ


  • Note: このサンプルは、.interval(sec:) { } を用いています。 secで指定した秒数ごと定期的に{ }の中身を実行します。