Change before you have to.

androidアプリ開発、iosアプリ開発、rails、deep learning .etc.を使った社会実験。

CAEmitterLayerでゲームオーバーエフェクトを実装してみる

 

非エンジニアでプログラム初心者のニートが30日間でゲームを作るという企画を勝手に進めています。

前回までのあらすじ

iOS Developer登録(申請篇、アクティベート篇、完結篇)

開発環境の整備

オブジェクト指向とは?

いざプログラミング!

iOSアプリで部品を作る

iOSアプリケーションのアニメーションまとめ

iOSアプリケーションのレイヤーまとめ

ゲームのデザインについて

主人公決定

ゲーム中のプレーヤーの表示①:翼を羽ばたかせる

ゲーム中のプレーヤー表示②:画面上を動かす

アニメーション中の衝突検知①(敵機襲来篇)

アニメーション中の衝突検知②(時間間隔篇)

 

年始からプログラミングを始めて既に30日が経過している気がしますが、

そこらへんは軽くスルーして引き続き開発を続けています。

 

今回はプレーヤーが敵機に衝突して

ゲームオーバーになったときのエフェクトについて作成しました。

 

エフェクトにはパーティクルというものがあるということを

グーグル先生に教わりました。

 

 

勉強してみた私なりの解釈では

パーティクルとはエミッターと呼ばれる放出機から爆発の炎のエフェクトや

煙のエフェクトを表現するための描画システムです。

 

具体的なエフェクトの設定はこちらのサイトが参考になりました。

 

まず、基本のやり方を踏襲して簡単なエフェクトクラスを作成してみました。

 

詳細な設定は上記サイトに記載してありますが、

ざっくりやったことを書いてみます。

まず最初にQuartzCoreヘッダーをインポートします。

#import "QuartzCore/QuartzCore.h" 

 

まずはエミッターオブジェクトを

CAEmitterLayer *particleEmitter;

のように宣言してやります。

 

エフェクトクラスの初期化部分はこうしました。

  

particleEmitter = (CAEmitterLayer *) self.layer;

particleEmitter.emitterPosition = CGPointMake(0, 0);//CGPointMake(frame.origin.x, frame.origin.y);//CGPointMake(0, 0);

particleEmitter.emitterSize = CGSizeMake(frame.size.width, frame.size.height);

particleEmitter.renderMode = kCAEmitterLayerAdditive;

              

CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];

emitterCell.birthRate = myBirthRate;//火や水に見せるためには数百が必要

emitterCell.lifetime = 0.5;

emitterCell.lifetimeRange = 0.5;

emitterCell.color = [[UIColor colorWithRed: 0.5 green: 0.1 blue: 0.1 alpha: 0.1] CGColor];

emitterCell.contents = (id) [[UIImage imageNamed: @"Particles_fire.png"] CGImage];

emitterCell.name = @"fire";

emitterCell.velocity = 50;

emitterCell.velocityRange = 20;

emitterCell.emissionLongitude = M_PI_2;

emitterCell.emissionRange = M_PI_2;

emitterCell.scale = 0.3f;

emitterCell.scaleRange = 0;

emitterCell.scaleSpeed = 0.5;

emitterCell.spin = 0.5;

particleEmitter.emitterCells = [NSArray arrayWithObject: emitterCell];

 

 

次にエミッターを返す部分です。

+ (Class) layerClass //3
{
    //configure the UIView to have emitter layer
    return [CAEmitterLayer class];
}

 

 

 

 

パーティクル表示中で放射方向を変えたい場合は

 以下のようにします。

-(void)setEmitDirection:(float)_direction{
    [particleEmitter setValue:[NSNumber numberWithDouble:_direction]
                   forKeyPath:@"emitterCells.fire.emissionLongitude"];

}

 

 

これを外部から呼び出してやれば、 

エフェクトを表示しているUIViewControllerからでも任意方向にリアルタイムで

放射方向を自由に変更出来ます。

 

 

 

また感の良い方なら分かるかもしれませんが

同様に色を変える場合はキーパスを以下のように指定して、

@“emitterCells.fire.color

 

更にバリュー値はid型に変換してあげてこのようにしてあげます。

setValue:(id)[[UIColor colorWithRed: 0.5 green: 0.1 blue: 0.1 alpha: 0.1] CGColor]

 

 

 まずは簡単な主人公が死んだ時の死亡エフェクトを作りました。

死亡エフェクトは中央が白、爆発のふちになる程、赤くなるようにしました。

実際の様子が⬇です。

地味ですね。。真ん中に赤い火の玉のようなものが表示されるだけです。

 

 いろいろ色や形を変えてみたりしました⬇

 

 少しエフェクトっぽく見えてきたでしょうか。

 

以前、敵機が襲来するプログラムを作ったので

そのプログラムと合わせて実際にプレーヤーが敵機に衝突した時に

この赤いパーティクルを表示させてみました。

衝突検知はコチラでやったものを採用しています。

あと、迫力を出すために自動で縦スクロール中の背景イメージも

一旦停止させて横方向に振動させるようアニメーションしてみました。

どうでしょうか。。

 

 

動画撮影と合わせたシミュレーション上での実行結果なので

若干画面がカクカクしていますが、実機では結構滑らかに実行できていました。