Change before you have to.

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

【objective-c】プレーヤーによる攻撃オブジェクトの作成

 

前回までに

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

開発環境の整備

オブジェクト指向とは?

いざプログラミング!

iOSアプリで部品を作る

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

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

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

主人公決定

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

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

ということを行ってきました。

 

objective-cの作法を学ぶこと以上に

成果物の作成にフォーカスするという私のポリシーに反し、

オブジェクト指向について継承関係compositionについて学ぶなど

かなり遠回りしてきました。

 

今回は主人公からビームを出すためにやったことをまとめました。

 

 

前回定義したビームクラスを少し拡張します。

 

ビームクラスについては以下の属性(グローバル変数)を持たせます。

・位置座標(CGPoint型)

・サイズ(int型)

・パワー(攻撃力:int型)

・生死フラグ(Boolean型)

・イメージ(UIImageView型)

 

 

そして主な動作(メソッド)としては以下です。

・初期化メソッドinit(上記属性の設定)

・時間経過メソッドtimePass(位置座標の変化や特殊効果の描画の追加等を実施)

 

 

 

ゲーム側の仕様としてはユーザーが画面をタッチしている間中ビームが出ているようにしたいので

プレーヤーオブジェクトにおいてビームオブジェクトを格納する可変長配列を定義します。

弾丸を格納する弾倉という意味でmagazineと定義しました。

 

こんな感じです。

 

  
NSMutableArray *magazine = [[NSMutableArray alloc]init];

 

宣言したらプレーヤークラスのhファイルとmファイルのそれぞれに

generateBeamメソッドの宣言と定義を記述してやり

そのメソッドの中で下のように弾倉に弾丸を格納しました。

 

hファイル側

  
-(void)generateBeam;

 

mファイル側

  
-(void)generateBeam{
     [magazine addObject:(BeamClass *)beamObject];
}

 

 

このようにhファイルで定義してやることにより、

プレーヤークラスをコンポジションとして保有しているオブジェクトから

このgenerateBeamメソッドを呼び出すことができます。

 

呼び出す時は、以前の記事で書いた(プレーヤークラスがタッチされている間中に呼び出される)メソッドonFlickedFrameにおいて

  
[Player generateBeam];

として呼び出します(Playerはプレイヤーオブジェクト)。

 

 

すると、弾倉に弾丸が充填され、ビームが生成されますので

この弾倉から個別にビームを取り出してやります。

 

そのためにはビームを取得するメソッドが必要なのでPlayerクラスのhファイルとmファイルそれぞれで

 

hファイル

  
-(BeamClass *)getBeam(int num);

 

mファイル

-(BeamClass *)getBeam(int num){
     return [magazine objectAtIndex:num];
}

 

と定義してやります。引数のnumは何番目のビームを取り出すかを表しています。

magazineにビームインスタンスを格納するときに

先ほどaddObjectで新しいものが最後に格納されるように書きましたが、

insertObject:atIndexで第二引数をゼロにしてやれば新しいものが最初に格納されるようにすることも可能です。

 

ここら辺はやりやすい方でいいかなと思ってますが、ゲーム側の設定次第では後者の方が若干取り出しやすいかもしれません。

 

 

ゲーム側でNSTimerオブジェクトを使って定期的に呼び出されるメソッド(例えばupdateTimeとする)を定義してやり、

そのupdateTimeメソッドの中で

  
[Player getBeam:xxx];

を呼び出してやればxxx番目のビームを取得することができます※。

 

 

※この表現は若干正確ではなく、

Playerオブジェクトの状態変化を行うメソッド(例えばupdateStatusとする)を定義し

そのupdateStatusメソッドの中で各ビームインスタンスの位置情報を更新してやるようにすれば

  
[Player updateStatus];

の一行で、定期的に全てのビームクラスの位置情報を変化させることができます。

 

 

 

 

ビームインスタンスの位置情報の更新は例えばこういう感じにしてみました。

-(void)updateStatus{
     for(int i = 0;i < [magazine count];i++){
          [[BeamClass objectAtIndex:i] timePass];
     }
}

 

timePassはこの記事の一番最初に書いたビームクラスのメソッドです。

timePassの中では下から上にビームを動かすために

x座標は変化させずに、y座標だけ少しずつ小さくしていき、

またUIImageView型の位置座標を更新してあげます。

 

今回はこんな感じにしました。

  
-(void)timePass{
     point = CGPointMake(point.x, point.y - 10);//CGPoint型のビーム位置
     image.center = point;//UIImageView型のビームイメージ
}

 

 

以上で大体完了したと思います。

 

ビームクラスを拡張している間に 

以前、こちらの記事に書いたデザイナーさんにお願いしていた背景画像の裏地ができたという報告があり、

せっかくなのでこれを背景画像にセットしてプレーヤーとビームを描画してみた動画が以下です。

 

シミュレータ上の見え方です。

画面上のカーソルの位置が指の位置で

カーソルが丸になった時はタップした時です。

タップと同時にビームが前に出ている様子が分かります。

 

まだまだ見た目はしょぼいですが、なんとなく基本動作は見えてきました。

 

動画ではビームのテストだけだったのでプレーヤーに動きはありませんが、

こちらの記事に書いたソースコードをがっちゃんこすれば

画面内を自由に動けるようになっています。

 

 ゲームの根幹が出来てきました。

次回は背景がスクロールさせたり、敵オブジェクトを配置してみようと思います。

 

続きます。