yoppa.org


immediate bitwave

Blog

Swift + Playgraoundメモ 1 – SpriteKitでアニメーション

注意: Swiftのソースは全てXcode 6 Beta 6で確認しています。それ以前のバージョンでの動作は確認していません。また今後のXcodeのバージョンで動く保証もありませんので、ご了承ください。

最近は、XcodeのPlaygroundのようなライブコーディング環境が、これからのプログラミングの姿になっていくのではと勝手に期待しているところもあり、少しずつ勉強していきたいと考えているところ。こうやってブログにメモ的に残すことで自分の知識も整理されるかも、ということで、まだまだ試行錯誤中なのだけれど、現状でわかってきたところなど書いてみる。

Swiftの基本文法は、現状で一番まとまっているのは、やはり本家Appleの資料みたいだ。

現状は、ここ資料を見つつ、あとはStackoverflowなどでググりながら、いろいろ探っている段階。

まずは、SwiftとPlaygroundで、Processing的なアニメーションをつくってみたいなあと思ってちょっと調べてみると、iOSやOS XのSDKには、SpriteKitというのがあって、これを使っていけばSDKの機能を利用しながら効率的にアニメーションが作れそうな感じ。

とりあえず、やってみた。

まずは、Xcodeで新規にPlaygroundプロジェクトを作成。そこに必要なライブラリをimport。SpriteKitとあわせて、Playground用のライブラリXCPlaygroundも入れておく。

import SpriteKit
import XCPlayground

ここにまずビュー(View)というのを生成する必要があるみたい。SpriteKitでは、SKViewというクラスで実装されている。Processingでいうところの size() 的な感じで、幅と高さを指定してSKViewを生成する。

import SpriteKit
import XCPlayground

// あとで使い回せるように幅と高さを定数に
let width:CGFloat = 640
let height:CGFloat = 480

// SpriteKitのViewを生成
let view:SKView = SKView(frame: CGRectMake(0, 0, width, height))

// PlaygroundのTimelineに表示
XCPShowView("Live View", view)

これで、もう画面が生成されている。楽ちんだ!

screenshot_211

ビューを生成したら、ここにシーンを追加してあげる必要があるようだ。シーンはSKSceneで定義する。ここで背景の色なども設定可能。背景を黒にして追加してみる。

import SpriteKit
import XCPlayground

// あとで使い回せるように幅と高さを定数に
let width:CGFloat = 640
let height:CGFloat = 480

// SpriteKitのViewを生成
let view:SKView = SKView(frame: CGRectMake(0, 0, width, height))

// PlaygroundのTimelineに表示
XCPShowView("Live View", view)

// シーンを生成、背景を黒にしてビューに追加
let scene:SKScene = SKScene(size: CGSizeMake(width, height))
scene.backgroundColor = SKColor.blackColor();
view.presentScene(scene)

screenshot_212

これで背景色黒のシーンが生成できた。いよいよ形を描いてみる。形を追加するにはSKSpriteNodeというクラスで形を定義して、最後にシーンにaddChild()すると良いらしい。ちょっとActionScript3風味。

import SpriteKit
import XCPlayground

// あとで使い回せるように幅と高さを定数に
let width:CGFloat = 640
let height:CGFloat = 480

// SpriteKitのビューを生成
let view:SKView = SKView(frame: CGRectMake(0, 0, width, height))

// PlaygroundのTimelineに表示
XCPShowView("Live View", view)

// シーンを生成、背景を黒にしてビューに追加
let scene:SKScene = SKScene(size: CGSizeMake(width, height))
scene.backgroundColor = SKColor.blackColor();
view.presentScene(scene)

// 青い四角を追加
let box:SKSpriteNode = SKSpriteNode(color:SKColor.blueColor(), size:CGSizeMake(200, 200))
box.position = CGPointMake(width/2.0, height/2.0)
scene.addChild(box)

これで青い四角形が画面中央に配置される。文法もさほど難しくない感じ。

screenshot_213

この形をアニメーションしてみたい。SpriteKitに配置したSKSpriteNodeは、SKActionクラスをつかうとあらかじめ用意された動きを簡単に付加できるようだ。試しに四角をぐるぐる回してみる。

まずは、1秒で1回転させてみる。こんな感じ。

import SpriteKit
import XCPlayground

// あとで使い回せるように幅と高さを定数に
let width:CGFloat = 640
let height:CGFloat = 480

// SpriteKitのビューを生成
let view:SKView = SKView(frame: CGRectMake(0, 0, width, height))

// PlaygroundのTimelineに表示
XCPShowView("Live View", view)

// シーンを生成、背景を黒にしてビューに追加
let scene:SKScene = SKScene(size: CGSizeMake(width, height))
scene.backgroundColor = SKColor.blackColor();
view.presentScene(scene)

// 青い四角を追加
let box:SKSpriteNode = SKSpriteNode(color:SKColor.blueColor(), size:CGSizeMake(200, 200))
box.position = CGPointMake(width/2.0, height/2.0)
scene.addChild(box)

// 1秒で1回転
let pi:CGFloat = 3.1415926
box.runAction(SKAction.rotateByAngle(pi * 2.0, duration: 1))

ずっと回転させ続けるには、SKActionのrepeatActionForeverというメソッドをつかうと良いみたい。

import SpriteKit
import XCPlayground

// あとで使い回せるように幅と高さを定数に
let width:CGFloat = 640
let height:CGFloat = 480

// SpriteKitのビューを生成
let view:SKView = SKView(frame: CGRectMake(0, 0, width, height))

// PlaygroundのTimelineに表示
XCPShowView("Live View", view)

// シーンを生成、背景を黒にしてビューに追加
let scene:SKScene = SKScene(size: CGSizeMake(width, height))
scene.backgroundColor = SKColor.blackColor();
view.presentScene(scene)

// 青い四角を追加
let box:SKSpriteNode = SKSpriteNode(color:SKColor.blueColor(), size:CGSizeMake(200, 200))
box.position = CGPointMake(width/2.0, height/2.0)
scene.addChild(box)

// 1秒で1回転のペースで、ずっと回転
let pi:CGFloat = 3.1415926
box.runAction(SKAction.repeatActionForever(SKAction.rotateByAngle(pi * 2.0, duration: 1)))

これで、永遠にぐるぐる回る青い四角形のアニメーションが完成。まだまだ、手探り状態だけれど、なんとなく雰囲気はつかめてきた。

screenshot_215

(たぶん)つづく…