SpriteKit. Warp Transformationを使って画像をねじ曲げる | はじはじアプリ体験記

SpriteKit
【Swift】SpriteKitの使い方。Warp Transformationを使って画像をねじ曲げる。

  • 2016年10月14日
    Swift 3.0で検証
  • Twitterでシェア
  • Facebook
  • LINEで送る

Warp Transformationとは

本記事では、iOS10で登場したWarp Transformation(以下、歪曲変換)について説明する。歪曲変換とは、ノードの一部分をつまんで引き伸ばしたり、縮めたりしたかのように歪曲させる機能である。

これを使えば、木が風に吹かれて曲がったり、衝撃を受けてひん曲がるような表現が可能になる。

パンダを曲げた

 

歪曲変換を試す

実際に歪曲変換を使ってノードの画像を曲げてみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト

事前準備ではパンダを1匹シーンに追加しておいた。このパンダをこれから歪曲させる。

SKSceneにパンダを配置

 

画像を歪曲させるために「つまみ点」を指定する必要がある。つまみ点を指でつまんで画像を引っ張ったり、縮めたりするイメージだ。

歪曲前のつまみ点をSource Position(以下、歪曲前ポジション)、歪曲先のつまみ点をDestination Position(以下、歪曲先ポジション)といい、この設定値をもとにノードが歪曲される。

つまみ点は任意の数だけ追加できるので、本記事では基本の9個のつまみ点を指定する。画像の左下角を(0,0)、右上角を(1.0, 1.0)としてつまみ点を指定する。

歪曲前ポジションには下図の値を指定する。

9個のソースポジション

 

歪曲先ポジションには下図の値を指定する。パンダがくの字に歪曲するのがイメージできる。

Destination Position

 

TestScene.swiftを以下のコードに変更する。つまみ点の配列は上記の⓪地点から順番に格納するので、実際のつまみ点の並び方とイメージが異なる。注意しよう。

歪曲グリッドを作成するときの引数には、つまみ点によって作成されるグリッドの縦横のマス数を指定する。今回の例では2×2マスのグリッドになるので、colums「2」、rows「2」を指定している。

 

下図は実行結果。パンダがくの字になった。

パンダを曲げた

スポンサーリンク

歪曲をループさせる

複数の歪曲をつなげてループさせたらどうのようになるか試してみよう。TestScene.swiftを以下のコードに変更する。

左にくの字、右にくの字、顔を長くするの3つの歪曲アクションを無限ループさせている。歪曲をアニメーションさせるにはノードのwarpGeometryプロパティにつまみ点の無い歪曲グリッドを設定する必要があることを覚えておくこと。

 

以下は実際のプレイ動画。画面をタップするとパンダがダンスしているように歪曲がループする。

 

以下のコードのようにしてアクションインスタンスを1つにしたほうがスマートに実装できそうだが、うまくアニメーションしてくれないので上記コードのような実装にしている。

何か感づいた人は教えて頂けると幸いです。

 

ドラッグで歪曲させる

つまみ点を指でドラッグして自分好みの形に歪曲させてみよう。

下図赤枠の「TestScene.sks」を選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、一覧にある「Color Sprite」をドラッグ&ドロップでパンダ左下のつまみ点まで運ぶ(紫矢印)。

水色枠のアトリビュートインスペクタボタンを押して設定画面を表示する。Nameに「point0」、SizeにW「20」、H「20」を入力する。User Dataにx(Float)、y(Float)を追加する(黄枠)。

つまみノードを配置する

 

残り7個のつまみ点も同じように追加する。コピペで配置してNameだけ変更したほうが作業が楽だ。

9個のつまみノードを配置した結果

 

TestScene.swiftを以下のコードに変更する。

画面に触れた指を移動するたびに、パンダノードを歪曲させるアクションとつまみノードを移動させるアクションを実行している。

 

以下は実際のプレイ動画。

Swift記事一覧へ

コメント

  1. トマト より:

    こんにちは。たまたまこのサイトにたどり着き、耳にしたことのない機能を知ったので、同じことをやってみようとしています。

    コードを見ると、pandaNodeをsceneに挿入していないところをみると、これは.sksファイル上でそれを足しているのでしょうか?また最後の画像では赤いnodeが足されていますが、これはコードでそれらを足しているのではなく、画像上にそれらを足しているのでしょうか?更に、この機能って、GameplayKitをimportしなくても使えるでしょうか?

    • 管理人 より:

      こんにちは

      > pandaNodeをsceneに挿入していないところをみると、これは.sksファイル上でそれを足しているのでしょうか?
      はい。sksファイル上に足しています。

      >これはコードでそれらを足しているのではなく、画像上にそれらを足しているのでしょうか?
      はい。このテストでは画面上でドラッグ&ドロップしてノードを足しています。

      >更に、この機能って、GameplayKitをimportしなくても使えるでしょうか?
      はい。SpriteKitをインポートすれば使えます。

      ページの最初のほうにテスト用プロジェクトのリンクを貼ってあるので、ダウンロードして試してみて下さい。
      プロジェクトの中にはパンダの画像も入っています。

  2. トマト より:

    どうも9つのpointというファイルも.sksファイル上で足しているみたいですね。

    • 管理人 より:

      はい。ドラッグするためのつまみはsksファイル上で足しています。もちろん、ソースコードで足そうと思えば足すことはできます。

      パンダが自動でクネクネするのに指定する9つのポイントはソースコード上で指定しています。

      • トマト より:

        どうもすばやい返信をありがとうございます。
        最後の「ドラッグで歪曲させる」の下にあるコードのsource.append(vector_float2(node.userData!.value(forKey: “x”) as! Float, node.userData!.value(forKey: “y”) as! Float))ですが、自分がdebugすると問題があるようですね。以下のようにすると回避できるようです。自分のXcodeのバージョンは8.3.3です。

        let x = list[i].0
        let y = list[i].1
        node.userData = [“x”: x, “y”: y]
        source.append(vector_float2(Float(x), Float(y)))

  3. タマネギ より:

    いつも記事読ませていただいています。WarpTransformationですが動画でワーピングを行うことはできますか?

    • 管理人 より:

      動画をワーピングさせようとしたことはないですが、とても興味深い視点ですね。
      もしできたら、面白い表現になりそうです。

      ぜひ試してみて、結果を教えて貰えると幸いです。

コメントを残す

お名前