前のページ

前のページの仕組みを応用して、図形に触れた時反応するエフェクトをつくってみましょう。


 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
func design( screen:PGScreen ) {
    screen.clearColor = .black
    
    for _ in 0 ..< 30 {
        let speed = (2.5...4.0).randomize
        let radians = (0.0...2.0).randomize * Double.pi
        let dx = speed * cos( radians )
        let dy = speed * sin( radians )
        
        PGAddCircle()
        .color( .random )
        .position( 
            cx: (screen.minX + 25 ... screen.maxX - 25).randomize,
            cy: (screen.minY + 25 ... screen.maxY - 25).randomize
        )
        .deltaPosition( 
            dx:dx,
            dy:dy
        )
        .scale( square:50 )
        .iterate {
            if $0.position.x - 25 <= Float( screen.minX ) {
                $0.deltaPosition.x *= -1
            }
            
            if Float( screen.maxX ) <= $0.position.x + 25 {
                $0.deltaPosition.x *= -1
            }
            
            if $0.position.y - 25 <= Float( screen.minY ) {
                $0.deltaPosition.y *= -1
            }
            
            if Float( screen.maxY ) <= $0.position.y + 25 {
                $0.deltaPosition.y *= -1
            }
            
            if 0 < screen.touches.count {
                let touch = screen.touches[0]
                
                // タッチ位置と図形の距離
                let dx = touch.x - $0.position.x
                let dy = touch.y - $0.position.y
                // 図形の円内部をタッチしていたら、弾けさせる
                if sqrt( dx * dx + dy * dy ) < 25 {
                    // 本体のライフを0にして無くす
                    $0.life( 0.0 )
                
                    // 本体を中心に60個新しい図形を作る
                    for _ in 0 ..< 60 {
                        let speed = (4.0...6.0).randomize
                        let radians = (0.0...2.0).randomize * Double.pi
                        let vx = speed * cos( radians )
                        let vy = speed * sin( radians )
                        
                        PGAddCircle()
                        .color( $0.color )
                        .position( $0.position )
                        .deltaPosition( 
                            dx:vx,
                            dy:vy
                        )
                        .scale( square:10 )
                        .deltaLife( -0.01 )
                        .iterate {
                            $0.deltaPosition.x *= 0.95
                            $0.deltaPosition.y *= 0.95
                            $0.alpha( $0.life )
                        }
                    }
                }
            }
        }    
    }
}

func update( screen:PGScreen ) {

}

  1. design関数に screen.clearColor = .black を書きます。背景は黒にします。

  1. update関数を用意します。今回update関数は空です。

  1. design関数の背景色の後にfor _ in 0 ..< 30のループを書き、加算合成の円PGAddCircle()を作ります。

  1. 図形の初期化に用いる値を計算し、変数に代入します。
    • let speed = (2.5...4.0).randomize

      • スピードを計算します。2.5~4.0のランダム値を代入します。
    • let radians = (0.0...2.0).randomize * Double.pi

      • 進む方向の角度を計算します。0~360度のランダム値です。
    • let dx = speed * cos( radians )

      • x方向の移動量を計算します。
    • let dy = speed * sin( radians )

      • y方向の移動量を計算します。

  1. 図形の初期設定のコードを書きます。
    • .color( .random )

      • 色。ランダムを設定します。
    • .position( cx: (screen.minX + 25 ... screen.maxX - 25).randomize, cy: (screen.minY + 25 ... screen.maxY - 25).randomize )

      • 位置。画面全体にランダムに配置します。
    • .deltaPosition( dx:dx, dy:dy )

      • 位置の変化量。計算したdx,dyを設定します。
    • .scale( square:50 )

      • 大きさ。固定値50を設定します。

  1. .iterate{ } を用意して、毎フレームの計算を行います。
    • if $0.position.x - 25 <= Float( screen.minX ) { ... }

      • 画面左端に図形がある時、処理を行います。
      • $0.deltaPosition.x *= -1
        • x方向の移動量を反転します。
    • if Float( screen.maxX ) <= $0.position.x + 25 { ... }

      • 画面右端に図形がある時、処理を行います。
      • $0.deltaPosition.x *= -1
        • x方向の移動量を反転します。
    • if $0.position.y - 25 <= Float( screen.minY ) { ... }

      • 画面上橋に図形がある時、処理を行います。
      • $0.deltaPosition.y *= -1
        • y方向の移動量を反転します。
    • if Float( screen.maxY ) <= $0.position.y + 25 { ... }

      • 画面下端に図形がある時、処理を行います。
      • $0.deltaPosition.y *= -1
        • y方向の移動量を反転します。

  1. iterate{ }の中でif screen.touches.count > 0の判定を行い、タッチしたときをとらえます。
    • let touch = screen.touches[0]

      • タッチ位置を取得します。
    • let dx = touch.x - $0.position.x

      • タッチ位置と図形のx方向の距離を計算します。
    • let dy = touch.y - $0.position.y

      • タッチ位置と図形のy方向の距離を計算します。
    • if sqrt( dx * dx + dy * dy ) < 25 { ... }

      • dxとdyからタッチ位置と図形の中心の距離を計算します。これが25未満の時、図形に触れていることになります。
    • $0.life( 0.0 )

      • 図形のライフを0にして図形を消去します。
    • for _ in 0 ..< 60 { ... }を書き、元の図形の位置を中心に、60個新しい図形を作る処理を追加します。

      • ループの中で図形の作成に必要な変数を作ります。

      • let speed = (4.0...6.0).randomize

        • 新しいスピード。4.0~6.0のランダム値を代入します。
      • let radians = (0.0...2.0).randomize * Double.pi

        • 新しい角度。0~360度方向のランダム値を代入します。
      • let vx = speed * cos( radians )

        • x方向の移動量を計算します。
      • let vy = speed * sin( radians )

        • y方向の移動量を計算します。
      • PGAddCircle()

        • 作る図形は加算合成の円とします。
      • .color( $0.color )

        • 色。色は元の図形と同じ色にします。
      • .position( $0.position )

        • 位置。元の図形と同じ位置を初期位置に設定します。
      • .deltaPosition( dx:vx, dy:vy )

        • 位置の変化量。vxとvyを設定します。
      • .scale( square:10 )

        • 大きさ。固定値の10とします。小さな円です。
      • .deltaLife( -0.01 )

        • ライフの変化量。100フレームで図形が消えるようにします。
      • 新しい図形用のiterate{ }を作り、以下の計算を行います。

        • $0.deltaPosition.x *= 0.95
          • x方向の変化量を0.95倍し徐々に遅くするようにします。
        • $0.deltaPosition.y *= 0.95
          • y方向の変化量を0.95倍し徐々に遅くするようにします。
        • $0.alpha( $0.life )
          • アルファ値はライフ値を代入します。時間が経つにつれ薄くなっていきます。

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

目標

  • 実行後、動き回る図形に触れた時、弾けるエフェクトが表現できたら成功です。

次のページ