2-4. 図形を交互に並べる

縦横に並べる を発展させて、複数の図形を描きます。 前ページのプログラムにif文を追加して、条件によって描く形を変えます。ここではxが偶数の時に円、奇数の時に三角を描くようにします。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 func design( screen:PGScreen ) { for y in 0 ..< 7 { for x in 0 ..< 7 { if x % 2 == 0 { PGCircle() .color( .blue ) .scale( width:50, height:50 ) .position( cx:-210 + x * 70, cy:-210 + y * 70 ) } else { PGTriangle() .color( .red ) .scale( width:50, height:50 ) .position( cx:-210 + x * 70, cy:-210 + y * 70 ) } } } } 「コードを実行」を押します。 目標 横方向に丸と三角が交互に表示されたら成功です。 終わったら次のページへ進みます。 ...

2023-12-16 · 2023-12-16

2-4. 燃える軌跡

前のページ このページでは、なぞった位置から炎が立ち上がるエフェクトを作ってみましょう。 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 func design( screen:PGScreen ) { screen.clearColor = .darkGrey } func update( screen:PGScreen ) { for touch in screen.touches { for _ in 0 ..< 2 { PGAddMask( "mask-smoke" ) .color( LLColor( 1.0, 0.4, 0.3, 1.0 ) ) .position( cx: touch.x + (-4.0...4.0).randomize, cy: touch.y + (-4.0...4.0).randomize ) .deltaPosition( dx: (-1.0...1.0).randomize, dy: (2.0...3.0).randomize ) .scale( square:(20.0...90.0).randomize ) .deltaScale( dw:1.0, dh:1.0 ) .angle( .random ) .deltaAngle( degrees:(-2.0...2.0).randomize ) .deltaLife( -0.02 ) .iterate { $0.alpha = $0.life $0.color.R -= 0.02 $0.color.G -= 0.009 $0.color.B -= 0.007 } } } } design関数に screen.clearColor = .darkGrey を書きます。背景は濃い灰色です。 update関数を用意します。 for touch in screen.touchesでタッチのループを作ります。触れている指すべてをとらえます。 3のループ内でfor _ in 0 ..< 2を書き、 加算合成の煙模様PGAddMask( "mask-smoke" )を作ります。 図形の初期設定のコードを書きます。 .color( LLColor( 1.0, 0.4, 0.3, 1.0 ) ) 色。明るい赤色を設定します。少しだけ黄色に近づけます。 .position( cx:touch.x + (-4.0...4.0).randomize, cy:touch.y + (-4.0...4.0).randomize ) 位置。タッチ位置から-4.0~4.0のランダム値を設定します。 .deltaPosition( dx:(-1.0...1.0).randomize, dy:(2.0...3.0).randomize ) 位置の変化量。x方向は-1.01.0のランダム値で横にわずかに移動します。y方向は2.03.0のランダム値で上方向に移動します。 .scale( square:(20.0...90.0).randomize ) 大きさ。20.0~90.0のランダム値で色々な大きさをとります。 .deltaScale( dw:1.0, dh:1.0 ) 大きさの変化量。毎フレーム1.0ずつ大きくしていきます。 .angle( .random ) 初期の角度。ランダムを設定します。 .deltaAngle( degrees:(-2.0...2.0).randomize ) 角度の変化量。毎フレーム-2.0~2.0のランダム値で回転します。 .deltaLife( -0.02 ) ライフの変化量。-0.02を設定し、50フレームで図形が消えるようにします。 ...

2023-12-16 · 2023-12-16

2-5. 加速する

前ページで、四角のアニメーション表現を一通り作成しました。 ここでは、アニメーションを少し工夫してみます。毎フレームの処理を参考に、 .iterate{ } で計算を加えて四角を加速させましょう。 前ページと同じコードを書きます。 .iterate{ } 内の$0 に .deltaPosition(dx:dy:) を追加します。deltaPosition.x と deltaPosition.y を 1.04倍した値 を設定します。1フレームごとに移動量が増えていきます。 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 func design( screen:PGScreen ) { for _ in 0 ..< 20 { PGRectangle() .position( screen.randomPoint ) .deltaPosition( dx:(-1.0...1.0).randomize, dy:(-1.0...1.0).randomize ) .scale( square: 0.0 ) .deltaScale( dw:1.0, dh:1.0 ) .angle( .random ) .deltaAngle( degrees:1.0 ) .color( .random ) .life( .random ) .deltaLife( -0.005 ) .completion { $0 .position( screen.randomPoint ) .deltaPosition( dx:(-1.0...1.0).randomize, dy:(-1.0...1.0).randomize ) .scale( square: 0.0 ) .angle( .random ) .color( .random ) .life( 1.0 ) } .iterate { $0 .alpha( $0.life ) .deltaPosition( dx:$0.deltaPosition.x * 1.04, dy:$0.deltaPosition.y * 1.04 ) } } } 「コードを実行」を押します。 目標 四角がだんだん加速する動きが描けたら成功です。 終わったら次のページへ進みます。 ...

2023-12-16 · 2023-12-16

2-5. 図形のチェッカー

前回のプログラム の条件を工夫すると、チェッカー模様にできます。条件だけ変えてみましょう。 前ページのプログラムのif文の条件を変えます。条件には (x + y) % 2 == 0 を入れます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 func design( screen:PGScreen ) { for y in 0 ..< 7 { for x in 0 ..< 7 { if (x + y) % 2 == 0 { PGCircle() .color( .blue ) .scale( width:50, height:50 ) .position( cx:-210 + x * 70, cy:-210 + y * 70 ) } else { PGTriangle() .color( .red ) .scale( width:50, height:50 ) .position( cx:-210 + x * 70, cy:-210 + y * 70 ) } } } } 「コードを実行」を押します。 目標 色違いのパネルが表示されたら成功です。 終わったら次のページへ進みます。 ...

2023-12-16 · 2023-12-16

2-5. 離した時に光線を描く

前のページ ここでは趣向を変えて、 指を離した時に指の移動した方向に光の線を描きます。 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 func design( screen:PGScreen ) { screen.clearColor = .darkGrey } func update( screen:PGScreen ) { for release in screen.releases { for k in 0 ..< 4 { let dx = release.x - release.startPos.x let dy = release.y - release.startPos.y let angle = Double( atan2( dy, dx ) ) let base_size = Float( 40 + 10 * k ) PGAddBlurryCircle() .color( LLColor( 0.2, 0.4, 0.6, 1.0 ) ) .position( release.startPos ) .angle( radians:angle ) .deltaPosition( dx: dx * 0.08, dy: dy * 0.08 ) .deltaLife( -0.02 ) .scale( square: base_size ) .iterate { $0.deltaPosition.x *= 0.93 $0.deltaPosition.y *= 0.93 let speed = sqrt( $0.deltaPosition.x * $0.deltaPosition.x + $0.deltaPosition.y * $0.deltaPosition.y ) $0 .width( base_size * ( 1.0 + speed / 10.0 ) ) .alpha( $0.life ) } } } } design関数に screen.clearColor = .darkGrey を書きます。背景は濃い灰色です。 update関数を用意します。 for release in screen.releasesでリリースのループを作ります。離れた指をとらえます。 3のループ内でfor k in 0 ..< 4を書き、 加算合成のブラー円PGAddBlurryCircle()を作ります。ブラー円を4つ重ねます。 図形の初期化に用いる値を計算し、変数に代入します。 let dx = release.x - release.startPos.x タッチを始めた位置(release.startPos)、指を離した位置(release)のx方向の距離をdxに代入します。 let dy = release.y - release.startPos.y タッチを始めた位置(release.startPos)、指を離した位置(release)のy方向の距離をdyに代入します。 let angle = Double( atan2( dy, dx ) ) dx, dyを使って図形の角度を計算します。atan2という関数で角度が得られます。 let base_size = Float( 40 + 10 * k ) 4つのブラー円の大きさです。kを使って少しずつ大きくした円を重ねます。 ...

2023-12-16 · 2023-12-16

2-6. カウンタで彩りを

2-3で並べた円 の色を変えてみましょう。.colorの値の計算にfor文のカウンタx, yを使います。 .colorの値にxとyを用いて計算します。 1 2 3 4 5 6 7 8 9 10 11 12 13 func design( screen:PGScreen ) { for y in 0 ..< 7 { for x in 0 ..< 7 { PGCircle() .color( red: Double( x ) / 7.0, green: Double( y ) / 7.0, blue: Double( x + y ) / 14.0 ) .scale( width:50, height:50 ) .position( cx:-210 + x * 70, cy:-210 + y * 70 ) } } } 「コードを実行」を押します。 目標 丸の色が徐々に変わって表示されたら成功です。 終わったら次のページへ進みます。 ...

2023-12-16 · 2023-12-16

2-6. タッチに集まるパーティクル

前のページ ここでは、もともとある図形をタッチ位置に誘導するエフェクトを表現してみます。今回は、design関数を用います。 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 func design( screen:PGScreen ) { screen.clearColor = .black for _ in 0 ..< 150 { let speed = (1.5...4.0).randomize let radians = (0.0...2.0).randomize * Double.pi let dx = speed * cos( radians ) let dy = speed * sin( radians ) PGAddBlurryCircle() .color( LLColor( 0.4, 0.7, 0.7, 1.0 ) ) .position( cx: (screen.minX + 10 ... screen.maxX - 10).randomize, cy: (screen.minY + 10 ... screen.maxY - 10).randomize ) .deltaPosition( dx:dx, dy:dy ) .scale( square:20 ) .iterate { if $0.position.x - 10 <= Float( screen.minX ) { $0.deltaPosition.x *= -1 } if Float( screen.maxX ) <= $0.position.x + 10 { $0.deltaPosition.x *= -1 } if $0.position.y - 10 <= Float( screen.minY ) { $0.deltaPosition.y *= -1 } if Float( screen.maxY ) <= $0.position.y + 10 { $0.deltaPosition.y *= -1 } if 0 < screen.touches.count { let touch = screen.touches[0] let dx = (touch.x - $0.position.x) * 0.04 let dy = (touch.y - $0.position.y) * 0.04 $0.position.x += dx $0.position.y += dy } } } } func update( screen:PGScreen ) { } design関数に screen.clearColor = .balck を書きます。背景は黒にします。 update関数を用意します。今回update関数は空です。 design関数の背景色の後にfor _ in 0 ..< 150のループを書き、加算合成のブラー円PGAddBlurryCircle()を作ります。 図形の初期化に用いる値を計算し、変数に代入します。 let speed = (1.5...4.0).randomize スピードを計算します。1.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方向の移動量を計算します。 ...

2023-12-16 · 2023-12-16

2-6. どんどん大きく

前ページで、iterate{ } を使って四角を加速させる表現を作りました。 合わせて、スケーリング変化も加速させて、迫ってくる四角を表現しましょう。 前ページと同じコードを書きます。 .completion{ }内の $0 に .deltaScale(dx:dy:) を追加します。値は dw:1.0, dh:1.0 を指定します。 .iterate{ } 内の $0 に .deltaScale(dw:dh:) を追加します。deltaScale.width と deltaScale.height を1.02倍した値を設定します。1フレームごとに拡大量が増えていきます。 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 func design( screen:PGScreen ) { for _ in 0 ..< 20 { PGRectangle() .position( screen.randomPoint ) .deltaPosition( dx:(-1.0...1.0).randomize, dy:(-1.0...1.0).randomize ) .scale( square: 0.0 ) .deltaScale( dw:1.0, dh:1.0 ) .angle( .random ) .deltaAngle( degrees:1.0 ) .color( .random ) .life( .random ) .deltaLife( -0.005 ) .completion { $0 .position( screen.randomPoint ) .deltaPosition( dx:(-1.0...1.0).randomize, dy:(-1.0...1.0).randomize ) .scale( square: 0.0 ) .deltaScale( dw:1.0, dh:1.0 ) .angle( .random ) .color( .random ) .life( 1.0 ) } .iterate { $0 .alpha( $0.life ) .deltaPosition( dx:$0.deltaPosition.x * 1.04, dy:$0.deltaPosition.y * 1.04 ) .deltaScale( dw:$0.deltaScale.width * 1.02, dh:$0.deltaScale.height * 1.02 ) } } } 「コードを実行」を押します。 目標 四角がだんだん加速して迫ってくる動きが描けたら成功です。 終わったら次のページへ進みます。 ...

2023-12-16 · 2023-12-16

2-7. フリーコード

ここまで2-5の図形パターン, 2-6の色パターン などを学んできました。おさらいとして、自由にコードを書いてみましょう。forや``if``を使って複数の図形をたくさん書いてみてください。 四角を描く: PGRectangle() 三角を描く: PGTriangle() 円を描く: PGCircle() ぼかし円を描く: PGBlurryCircle() 繰り返し処理: for a in 0 ..< 繰り返し回数 { 繰り返す処理 } 条件分岐: if 条件 { 条件を満たした時 } else { 条件を満たさない時 } 目標 色々な形を描いたり、繰り返し・条件分岐を使って楽しんでください。 終わったら次のページへ進みます。

2023-12-16 · 2023-12-16

2-7. 触れて弾ける

前のページ 前のページの仕組みを応用して、図形に触れた時反応するエフェクトをつくってみましょう。 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 ) { } design関数に screen.clearColor = .black を書きます。背景は黒にします。 update関数を用意します。今回update関数は空です。 design関数の背景色の後にfor _ in 0 ..< 30のループを書き、加算合成の円PGAddCircle()を作ります。 図形の初期化に用いる値を計算し、変数に代入します。 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方向の移動量を計算します。 ...

2023-12-16 · 2023-12-16