2016年で一番良かったアルバム – The Best of 2016 Music

年の瀬となり、年賀状も出し終わったので、今年買ってよかったな~、と思ったものを小出しにしてみたいと思います。

ふくろうず / だって、あたしたちエバーグリーン

ふくろうずの5枚目となるフルアルバム。
今年一番聞いたかなーと思います。メジャーデビューしてからいろいろなスタイルを模索していたふくろうずですが、このアルバムはファーストアルバムに近いですね。無理してポップなわけではなく、すこしセンチでひねくれていて、若干サディスティックな歌詞の、ふくろうずらしい良いアルバムでした。

まあアルバム全部買う必要もないと思いますので、オススメ数曲。

  • うららのLa
  • ラジオガール
  • ダイナソー

ラジオガールがいちばん好きですね。

LINEスタンプ第二弾 作成→申請→審査→販売開始までにかかった時間 (2015/4/11)

LINE スタンプ 帰る羊② 社畜

第一弾のリリース直後に申請していたLINEクリエイターズスタンプの第二弾がリリースされました。

http://line.me/S/sticker/1085040

ライン スタンプ 帰る羊②

申請からリリースまでにかかった時間

前回同様、申請してからリリースまで3ヶ月ぐらいかかりました。
今回のほうが期間は長かったです。

「一番最初に出すスタンプの審査が長い」「以降は著作権のチェックが済んでいるの早い」みたいに聞いていたのですが、むしろ2回めのほうが時間がかかりました。チェックの事情よりは、審査の混み具合のほうが影響が大きいように思います。

 

LINEクリエイターズスタンプ用フォーマット

LINEクリエイターズスタンプ用のフォーマットを作成しました。
http://www.hugkey.com/691/

LINEスタンプで一攫千金を目指す方、是非ダウンロードしてご活用下さい。

LINEスタンプフォーマット
LINEスタンプフォーマット

主要な中国のAndroidアプリストアと、そのアカウント取得方法

中国はGoogle Playが無い

中国は国内からGoogle Playにアクセス出来ないという事を今日知りました。(2015/2/16現在)
というわけで、中国のGoogle Play以外の主要なアプリストアの一覧と、そのストアでアカウントをどのように取得するのか。
ID番号が必要であったり、会社の証明書を要求したり、どこも難易度が高いです。
1,2は英語ページがある分、まだましですね。海外向けも意識してくれている。

①MyApp (Tencent)

http://android.myapp.com/
開発者向けページ
http://open.qq.com/
開発者向けページ(英語)
http://open.qq.com/eng/reg
登録にはDeclaration of AuthorizationとCompany Licenseの
写真のアップロードが必要
APKファイルを添えて、登録と同時にアップロード可能

②Qihoo 360 Mobile Assistant

http://zhushou.360.cn/soft/
開発者向けページ
http://dev.360.cn/
開発者向けページ(英語)
http://developer.360.cn/distribution
登録にはDeclaration of AuthorizationとCompany Licenseの
写真のアップロードが必要
APKファイルを添えて、登録と同時にアップロード可能

③Wandoujia

http://www.wandoujia.com/apps
申請ページ(QQまたはWeiboのアカウントでログイン可能?)
http://open.wandoujia.com/home

④MIUI (Xiaomi)

http://app.mi.com/
申請ページ
http://dev.xiaomi.com/
日本の電話番号で登録可能
開発者アカウント登録ページでID番号が必要(個人の場合)
企業の場合は、ビジネスライセンス登録番号、ビジネスライセンスの写真、
税務登録番号、税務登録証明書のコピーの写真が必要

⑤Baidu App Store

http://as.baidu.com/
※開発者アカウント登録に中国の電話番号、IDが必要
アプリ申請ページ
http://app.baidu.com/
開発者アカウント登録ページ
http://app.baidu.com/user/register

⑥91 Mobile Assistant

http://zs.91.com/feature/v4/index_android.shtml
登録にID番号が必要
申請ページ
http://market.sj.91.com/Users/Login.aspx
申請方法
http://ibbs.91.com/thread-2129799-1-1.html

⑦HiMarket

http://apk.hiapk.com/
開発者向けページのログインにBaiduのアカウントが必要

iPhone6 向け ペーパープロトタイプ PDF A4サイズ

iPhone6 ペーパープロトタイプ PDF iOS8

iPhone6サイズのペーパープロトタイプ作成用フォーマットを作成しました。
A4でプリントアウトすると、だいたいiPhone 6と同じ大きさになります。

【ダウンロードはこちらから】

iPhone6_paper_prototype_pdf

iPhone6 ペーパープロトタイプ PDF iOS8
iPhone6 ペーパープロトタイピング PDF iOS8

 

iPhone5, 5sのサイズは、こちらからダウンロードできます。
iPhone5_paper_prototype_pdf

 

 

 

NoPMO App for iPhone / Patience Counter

Starting NoFapp App. Free iPhone App

This is the App for No PMO

If you want to abstain from porn and masturbation, use this app.
This app helps you to quit PMO.
You will gain a lot of benefit by NoPMO.

NoFap App for iPhone
NoPMO App for iPhone

Patience Counter : NoPMO App for iPhone (free)

How to use

Push start button to start recording.

Starting NoFapp App. Free iPhone App
Start App

 

If you Fap, push stop button, and record it.

NoFap App for iPhone
Stop App for iPhone

 

You can also see your all records, and average score.

 

NoFap App iPhone Records History

 

NoFap App for iPhone
NoPMO App for iPhone

Patience Counter : NoPMO App for iPhone (free)

LINEスタンプ 作成→申請→審査→販売開始までにかかった時間

ライン スタンプ 羊

申請していたLINEクリエイターズスタンプがようやくリリースされました。

http://line.me/S/sticker/1039057

ライン スタンプ 羊

申請からリリースまでにかかった時間

申請してからリリースまで3ヶ月ぐらいかかりました。

  • 2014/9/20 申請
  • 2014/10/7 審査中
  • 2014/10/9 審査中
  • 2014/11/13 審査中
  • 2014/12/7 審査完了
  • 2014/12/8 販売開始

審査完了後は、管理画面から「リリース」を押さないと公開されません。
リリースをしたあとは「数分」と書いてあったのですが、実際は2時間ぐらいかかりました。
12時間かかった方もいるそうなので、気長に待ちましょう。

 

LINEクリエイターズスタンプ用フォーマット

LINEクリエイターズスタンプ用のフォーマットを作成しました。
http://www.hugkey.com/691/

LINEスタンプで一攫千金を目指す方、是非ダウンロードしてご活用下さい。

LINEスタンプフォーマット
LINEスタンプフォーマット

アプリ作成でよくある単語の英語、中国語、韓国語訳

ローカライズする時、英語はわりとサンプルが多いのですが、中国語や韓国語は感覚がわからない分ちんぷんかんぷんです。
かといって翻訳に出すほどの量でも、、、ということで色々なアプリから表現を調べてみました。
正しいかどうかは保証しませんが、ご参考程度に。

When you localize your Apps for East Asian region, you may have difficulty translating some basic words into local one.
I listed some basic words of Japanese, Chinese and Korean.

英語 English 日本語 Japanese 中国語(簡体) Chinese(zh-Hans) 中国語(繁体) Chinese(zh-Hant) 韓国語 Korean
OK はい
Cancel キャンセル 取消 取消 취소
Done 完了 完成 完成 완료
Share シェアする 分享 分享 공유하기
Take New Photo 写真を撮る 拍照 拍照 사진을 찍는
Choose From Library ライブラリから選択 从照片库选取 從照片庫選取 라이브러리에서 선택

LINEスタンプフォーマット

LINEスタンプフォーマット

LINEスタンプを下書きする用のフォーマットを作成しました。

 

LINEスタンプフォーマット
LINEスタンプフォーマット

 

20140901_LINEスタンプフォーマット

PDFファイルをダウンロードしてお使いください。ひとコマが幅370高さ320(スタンプ上限サイズ)と同じ比率になっています。

LINEスタンプフォーマット 活用例
活用例

 

クリエイターズスタンプのガイドラインはこちらをご確認下さい。

https://creator.line.me/ja/guideline/

 

 

私の作ったLINEクリエイターズスタンプが販売中です。

http://line.me/S/sticker/1039057
↑ダウンロードはこちらから

ただいまー、帰るよー、おかえり、待ってるね、遅くなりそう、帰れない、など、帰宅時に使えるLINEスタンプです。
来年は未年なので、干支もバッチリ!

スクリーンショット 2014-12-08 12.06.08スクリーンショット 2014-12-08 12.06.24スクリーンショット 2014-12-08 12.06.35

[7:完成] cocos2d-iPhoneとSpriteBuilderでゲームを1週間で作ろう

_scoreLabel

SpriteBuilderとcocos2dを使ったゲーム開発もついに最終回です!長い間お疲れ様でした!

今回は、物理演算を使って当たり判定を導入し、ポイントのカウントもします。最後なので少し書くコードの量が多目ですが、スクリーンショットやサンプルコードを見ながら頑張って実装してみてください。

前回まで

  1. ソフトをインストール。背景画像を設置
  2. 主人公をつくる
  3. 物理演算を導入する
  4. 主人公と背景を動かす
  5. 主人公を飛ばす
  6. 障害物を設置する

当たり判定の実装

Obstacle.mにcollisionTypeを設定します。

 

[code language=”objc” title=”Obstacle.m”]
// CCBファイルからロード
– (void)didLoadFromCCB {
// 上のパイプの当たり判定を設定
_topPipe.physicsBody.collisionType = @"level";
_topPipe.physicsBody.sensor = TRUE;
// 下のパイプの当たり判定を設定
_bottomPipe.physicsBody.collisionType = @"level";
_bottomPipe.physicsBody.sensor = TRUE;
}
[/code]

ここで設定した「level」という名前は、パイプや地面といったキャラクターが触れたら死ぬオブジェクトすべてに適応します。

続いてMainScene.hを編集します。CCPhysicsCollisionDelegateを実装します。
このデリゲートはふたつのオブジェクトが衝突した際に呼ばれます。

[code language=”objc” title=”MainScene.h” highlight=”2″]
#import "CCNode.h"
@interface MainScene : CCNode <CCPhysicsCollisionDelegate>
@end
[/code]

先ほどObstacle.mでも上下のパイプに当たり判定の設定(@levelで指定)をしましたが、MainScene.mでも同様に主人公と地面に対して当たり判定設定を行います。
didLoadFromCCBに追記していきましょう。

[code language=”objc” title=”MainScene.m” highlight=”15,16,21,22,23,24″]
// CCBファイルからロード
– (void)didLoadFromCCB {
// タッチ操作可能にする。
self.userInteractionEnabled = TRUE;
// 地面その1とその2を配列に追加
_grounds = @[_ground1, _ground2];
// 最初の障害物を設置する
_obstacles = [NSMutableArray array];
[self spawnNewObstacle];
[self spawnNewObstacle];
[self spawnNewObstacle];

// 地面の表示順を変更する
for (CCNode *ground in _grounds) {
// 地面の当たり判定設定
ground.physicsBody.collisionType = @"level";
ground.zOrder = DrawingOrderGround;
}
_hero.zOrder = DrawingOrdeHero;

// デリゲートとして設定する
_physicsNode.collisionDelegate = self;
// 主人公の当たり判定設定
_hero.physicsBody.collisionType = @"hero";
}
[/code]

続いて、SpriteBuilderでの設定に移ります。
上下のパイプを選択し、物理演算を可能にします。また、Dynamic→Staticに変更します。

SpriteBuilder SpriteBuilder

最後に衝突時の処理を実装します。

 

[code language=”objc” title=”MainScene.m”]
// 衝突時の処理
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero level:(CCNode *)level {
NSLog(@"Game Over");
return TRUE;
}
[/code]

 

それではビルドして確認してみましょう。

FlappyFly 8

障害物に接触するか、地面に接触すると、「Game Over」とログを出します。

ゲームオーバー時の動作

障害物にあたった際の動きを確認できたので、今度はゲームオーバーとリスタートのしくみを実装します。実際のゲームでは、

  • 地面に落下
  • 画面が揺れる
  • リスタートボタンが表示される
  • リスタートボタンを押したら、ゲームがスタートする

SpriteBuilderで、リスタートボタンを設置します。

SpriteBuilder 8

コネクションとセレクタを設定します。
あとでリスタートボタンが押された時に反応するようXcode側でも設定します。

SpriteBuilder

 

最後に位置を中央に設定し、表記をRestartに変更します。そして、Visibleのチェックを外し、見えないようにします。

SpriteBuilder

リスタートボタンは、ゲームオーバーになった時に表示されるようにします。
Xcodeを開き、MainScene.mに追記していきます。

まずは変数を宣言します。

[code language=”objc” title=”MainScene.m” highlight=”9″]
@implementation MainScene{
CCSprite *_hero; // SpriteBuilderと接続する主人公のスプライト
CCPhysicsNode *_physicsNode; // SpriteBuilderと接続する全画面の物理ノード
CCNode *_ground1; // SpriteBuilderと接続する地面その1
CCNode *_ground2; // SpriteBuilderと接続する地面その2
NSArray *_grounds; // 地面ループ処理用のArray
NSTimeInterval _sinceTouch; // 最後にタッチしてからどれだけ経過したか
NSMutableArray *_obstacles; // 障害物を格納する配列
CCButton *_restartButton; // リスタートボタン
}
[/code]

つぎに、衝突時の処理をするメソッドに、リスタートボタンを表示させるように設定します。

[code language=”objc” title=”MainScene.m” highlight=”4,5″]
// 衝突時の処理
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero level:(CCNode *)level {
NSLog(@"Game Over");
// リスタートボタンを表示させる
_restartButton.visible = TRUE;
return TRUE;
}
[/code]

最後に、リスタートの処理を実装します。

[code]
– (void)restart {
CCScene *scene = [CCBReader loadAsScene:@"MainScene"];
[[CCDirector sharedDirector] replaceScene:scene];
}
[/code]

これでリスタートが実装できました。

FlappyFly

ただ、このままではゲームオーバー後に地を這いながら進んでしまっています。ゲームオーバー後はスクロールが止まるよう修正しましょう。

ゲームオーバーの判定をする変数と、スクロールスピードを格納する変数を新たに宣言します。

[code language=”objc” title=”MainScene.m” highlight=”10,11″]
@implementation MainScene{
CCSprite *_hero; // SpriteBuilderと接続する主人公のスプライト
CCPhysicsNode *_physicsNode; // SpriteBuilderと接続する全画面の物理ノード
CCNode *_ground1; // SpriteBuilderと接続する地面その1
CCNode *_ground2; // SpriteBuilderと接続する地面その2
NSArray *_grounds; // 地面ループ処理用のArray
NSTimeInterval _sinceTouch; // 最後にタッチしてからどれだけ経過したか
NSMutableArray *_obstacles; // 障害物を格納する配列
CCButton *_restartButton; // リスタートボタン
BOOL _gameOver; // ゲームオーバーかどうか
CGFloat _scrollSpeed; // スクロールスピード
}
[/code]

MainScene.mでscrollSpeedと書いた箇所はすべて_scrollSpeedに置き換えます。
また、定数宣言をコメントアウトします。

[code language=”objc” title=”MainScene.m” highlight=”1″]
//static const CGFloat scrollSpeed = 80.f; // スクロール速度の定数を定義
static const CGFloat firstObstaclePosition = 280.f; // 最初の障害物の位置
static const CGFloat distanceBetweenObstacles = 160.f; // 障害物と次の障害物の距離
[/code]

さらに、didLoadFromCCBにスクロールスピードを追記します。

[code language=”objc” title=”MainScene.m” highlight=”6,7″]
// CCBファイルからロード
– (void)didLoadFromCCB {
// タッチ操作可能にする。
self.userInteractionEnabled = TRUE;
// 略…

// スクロールスピードを設定
_scrollSpeed = 80.f;
}
[/code]

続いてゲームオーバー時に実行されるメソッドを作成しましょう。

[code]
// ゲームオーバーになった時に実行する
– (void)gameOver {
if (!_gameOver) {
// スクロールを泊める
_scrollSpeed = 0.f;
// ゲームオーバーのフラグを立てる
_gameOver = TRUE;
// ボタンを見えなくする
_restartButton.visible = TRUE;
_hero.rotation = 90.f;
_hero.physicsBody.allowsRotation = FALSE;
[_hero stopAllActions];
CCActionMoveBy *moveBy = [CCActionMoveBy actionWithDuration:0.2f position:ccp(-2, 2)];
CCActionInterval *reverseMovement = [moveBy reverse];
CCActionSequence *shakeSequence = [CCActionSequence actionWithArray:@[moveBy, reverseMovement]];
CCActionEaseBounce *bounce = [CCActionEaseBounce actionWithAction:shakeSequence];
[self runAction:bounce];
}
}
[/code]

そして、衝突時のメソッドを書き換えます

[code language=”objc” title=”MainScene.m” highlight=”3,4,5,6,7,8″]
// 衝突時の処理
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero level:(CCNode *)level {
// NSLog(@"Game Over");
// // リスタートボタンを表示させる
// _restartButton.visible = TRUE;
// ゲームオーバー処理を実行
[self gameOver];
return TRUE;
}
[/code]

ゲームオーバー時にはタッチに反応しないように修正します。

[code language=”objc” title=”MainScene.m” highlight=”3,4,11″]
// 画面をタッチした時の挙動
– (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
// ゲームオーバー時にはタッチに反応しない
if (!_gameOver){
// 力積を与える
[_hero.physicsBody applyImpulse:ccp(0, 400.f)];
// 角力積を設定
[_hero.physicsBody applyAngularImpulse:10000.f];
// いまタッチしたので、経過時間を0にする
_sinceTouch = 0.f;
}
}
[/code]

これで、ゲームオーバー時にストップするようになりました。

 

スコアを表示して完成!

いよいよ完成です。最後に、スコアを表示するようにしましょう。

SpriteBuilderで画面上にラベルを設置します。位置を調整して、表記を「0」に、サイズを50にします。

LabelTTF

 

続いて、コネクションの設定をします。_scoreLabelと記入して下さい。

_scoreLabel

 

さらにObstacleを開き、パイプとパイプの間においてあるノードに対して、カスタムクラスとしてGoalと名前をつけます。

スクリーンショット 2014-06-29 18.36.35

 

さらに、物理演算を可能にして、Staticにチェックを入れます。

 

Static

続いてXcodeに移り、Goalクラスを作ります。

スクリーンショット 2014-06-29 19.09.01 スクリーンショット 2014-06-29 19.09.33 スクリーンショット 2014-06-29 19.09.46 スクリーンショット 2014-06-29 19.10.03

Goal.mにメソッドを追加します。

 

[code language=”objc” title=”Goal.m”]
// CCBファイルからロード
– (void)didLoadFromCCB {
self.physicsBody.collisionType = @"goal";
self.physicsBody.sensor = TRUE;
}
[/code]

 

続いて、MainScene.mに変数を追加します。

[code language=”objc” title=”MainScene.m” highlight=”4,5″]
@implementation MainScene{
CCSprite *_hero; // SpriteBuilderと接続する主人公のスプライト
// 略…
NSInteger _points; // ポイントをカウント
CCLabelTTF *_scoreLabel; // ポイント表示用のラベル
}
[/code]

そして、これでほんとうに最後。ゴール時のメソッドに追記をします。

[code language=”objc” title=”MainScene.m” highlight=”4,5″]
// ゴールした時に実行する
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero goal:(CCNode *)goal {
[goal removeFromParent];
_points++;
_scoreLabel.string = [NSString stringWithFormat:@"%d", _points];
return TRUE;
}
[/code]

おつかれさまです!以上でFlappuFlyの完成です!
FlappyFly 8

 

 

SpriteBuilderとcocos2dを使ったiphoneアプリ開発講座、いかがでしたでしょうか。

私も現在、SpriteBuilderを使ってゲームアプリを開発しています。簡単ツールを使って、iPhoneアプリをじゃんじゃん量産しましょう!

 

[6:障害物] cocos2d-iPhoneとSpriteBuilderでゲームを1週間で作ろう

Flappy Fly 7

SpriteBuilderをつかって、障害物を設置します。さらに、障害物の上下の高さをランダムにして出現させます。みためだけだと、ほぼ完成と言えるような状態になります。

前回まで

  1. ソフトをインストール。背景画像を設置
  2. 主人公をつくる
  3. 物理演算を導入する
  4. 主人公と背景を動かす
  5. 主人公を飛ばす

SpriteBuilderで障害物オブジェクトを作る

SpriteBuilderで新しくファイルを作ります。 Nodeを選択し、名前はObstacle.ccbとします。         SpriteBuilder SpriteBuilder   続いて、作ったObstacle.ccsに画像やNodeを追加していきます。 まずはObstacle.ccsを開きましょう。(ダブルクリック) SpriteBuilder   続いて、画像を置いていきます。 SpriteBuilder 次に、CCNodeを設置します。 位置やサイズはこの後に設定するので、とりあえず置いてみてください。 SpriteBuilder サイズを調整します。 まずはRootとなるCCNodeのサイズを調整します。(最後に追加したCCNodeではありません。) 幅80, 高さ568と指定します。 CCNode   次に、pipe_topの位置を調整します。 Positionを左上に指定し、Xを50「%」、Yを128に指定します。 Anchor pointのx,yを0.50と0.00にします。 Top 同様にpipe_bottomの位置も調整します。 Positionを左上に指定し、Xを50「%」、Yを228に指定します。 Anchor pointのx,yを0.50と1.00にします。 pipe_bottom 最後にカウント用のCCNodeの設定です。 Positionを左上に指定し、Xを22、Yを574に指定し、サイズを幅36と高さ790にします。 SpriteBuilder   それではこのObstacle.ccbを保存し、MainScene.ccbの上に設置してみましょう。 Obstacle.ccb 上図のように設置できることが確認できたら、設置した障害物を一度削除します。障害物の設置は、SpriteBuilder上ではなく、Xcodeで行います。 それではSpriteBuilderでPublishしたあと、Xcodeに移りましょう。 障害物を格納するための配列を作成します。

[code language=”objc” title=”MainScene.m” highlight=”8″]
@implementation MainScene{
CCSprite *_hero; // SpriteBuilderと接続する主人公のスプライト
CCPhysicsNode *_physicsNode; // SpriteBuilderと接続する全画面の物理ノード
CCNode *_ground1; // SpriteBuilderと接続する地面その1
CCNode *_ground2; // SpriteBuilderと接続する地面その2
NSArray *_grounds; // 地面ループ処理用のArray
NSTimeInterval _sinceTouch; // 最後にタッチしてからどれだけ経過したか
NSMutableArray *_obstacles; // 障害物を格納する配列
}
[/code]

続いて、定数を追加します。

[code language=”objc” title=”MainScene.m” highlight=”2,3″]
static const CGFloat scrollSpeed = 80.f; // スクロール速度の定数を定義
static const CGFloat firstObstaclePosition = 280.f; // 最初の障害物の位置
static const CGFloat distanceBetweenObstacles = 160.f; // 障害物と次の障害物の距離
[/code]

最初の障害物の座標と、障害物と障害物の間の距離を定義します。 続いて、障害物を生成するメソッドを作成します。

[code language=”objc” title=”MainScene.m”]
// 障害物を生成する
– (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// これが一番最初の障害物オブジェクトになります
previousObstacleXPosition = firstObstaclePosition;
}
// CCBファイルから障害物オブジェクトを読み込み、生成します
CCNode *obstacle = [CCBReader load:@"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
[/code]

CCBファイルを読み込んで障害物オブジェクトを生成し、先ほど定義した距離の分だけ離して配置しています。 さて、障害物生成メソッドは作成したので、最初の障害物だけ設置しましょう。 didLoadFromCCBに以下を追加します。

[code language=”objc” title=”MainScene.m” highlight=”7,8,9,10,11″]
// CCBファイルからロード
– (void)didLoadFromCCB {
// 地面その1とその2を配列に追加
_grounds = @[_ground1, _ground2];
// タッチ操作可能にする。
self.userInteractionEnabled = TRUE;
// 最初の障害物を設置する
_obstacles = [NSMutableArray array];
[self spawnNewObstacle];
[self spawnNewObstacle];
[self spawnNewObstacle];
}

[/code]

これで3つの障害物を設置することが出来ました。 Flappy fly 7 それでは、障害物が永遠に出続けるようにアップデートメソッドを更新します。

[code language=”objc” title=”MainScene.m”]
// アップデート
– (void)update:(CCTime)delta {
// 主人公のX座標を右に進める
_hero.position = ccp(_hero.position.x + delta * scrollSpeed, _hero.position.y);
// 略…

// 障害物の新規作成
// 画面外に出た障害物を格納する配列
NSMutableArray *offScreenObstacles = nil;
// _obstaclesの中にある障害物のうち、左の画面外に出たものをoffScreenObstaclesに格納する
for (CCNode *obstacle in _obstacles) {
CGPoint obstacleWorldPosition = [_physicsNode convertToWorldSpace:obstacle.position];
CGPoint obstacleScreenPosition = [self convertToNodeSpace:obstacleWorldPosition];
if (obstacleScreenPosition.x < -obstacle.contentSize.width) {
if (!offScreenObstacles) {
offScreenObstacles = [NSMutableArray array];
}
[offScreenObstacles addObject:obstacle];
}
}
// offScreenObstaclesに入っている障害物を親ノードから取り除く
for (CCNode *obstacleToRemove in offScreenObstacles) {
[obstacleToRemove removeFromParent];
[_obstacles removeObject:obstacleToRemove];
// 障害物を取り除いたら、新しい障害物を生成する
[self spawnNewObstacle];
}
}
[/code]

Flappy Fly 7

障害物の位置をランダムにする

障害物をX軸上に規則的に配置することができたので、今度は障害物のY軸の位置がランダムになるようにしましょう。 そのためには障害物のクラスを作成する必要があります。 SpriteBuilderのObstacle.ccbのCustom ClassにObstacleと記述します。 Obstacle.ccb さらに、Code Connectionの設定も行いましょう。 上側のパイプは_topPipe、下側のパイプは_bottomPipeとします。 Top Pipe Bottom Pipe   保存してPublishしたら、Xcodeでの作業に移ります。 Xcodeでは、新しいクラスを作成します。CCNodeのサブクラスとしてObstacleを作成しましょう。 Xcode Xcode Xcode Obstacleが作成できました。 Xcode 続いて実装をしていきましょう。 3.5インチでも4インチでも大丈夫なよう定数を調整しています。

[code language=”objc” title=”Obstacle.m”]
#import "Obstacle.h"

@implementation Obstacle {
CCNode *_topPipe; // 上のパイプ
CCNode *_bottomPipe; // 下のパイプ
}
#define ARC4RANDOM_MAX 0x100000000
// 上のパイプの最小値。3.5インチiPhoneにも考慮しています
static const CGFloat minimumYPositionTopPipe = 128.f;
// 下のパイプの最大値。3.5インチiPhoneにも考慮しています
static const CGFloat maximumYPositionBottomPipe = 440.f;
// 上下のパイプの間の距離
static const CGFloat pipeDistance = 142.f;
// 上のパイプの範囲を計算する
static const CGFloat maximumYPositionTopPipe = maximumYPositionBottomPipe – pipeDistance;
// 障害物の位置をランダムに設定
– (void)setupRandomPosition {
// 乱数は0.f〜1.fの範囲で変動
CGFloat random = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat range = maximumYPositionTopPipe – minimumYPositionTopPipe;
// 上のパイプの位置を指定
_topPipe.position = ccp(_topPipe.position.x, minimumYPositionTopPipe + (random * range));
// 下のパイプの位置を指定
_bottomPipe.position = ccp(_bottomPipe.position.x, _topPipe.position.y + pipeDistance);
}
@end
[/code]

Obstacle.hにもメソッドの宣言をします。

[code language=”objc” highlight=”5″ title=”Obstacle.h”]
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface Obstacle : CCNode {
}
– (void)setupRandomPosition;
@end
[/code]

最後にMainScene.mを修正しましょう。 障害物を生成する際に、位置がランダムになるよう修正します。 まずはクラスをインポートします。

[code language=”objc” title=”MainScene.m” highlight=”2″]
#import "MainScene.h"
#import "Obstacle.h" // 障害物クラスをインポート
[/code]

続いてメソッドに書き加えましょう。

[code language=”objc” title=”MainScene.m” highlight=”10, 12,13″]
// 障害物を生成する
– (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// これが一番最初の障害物オブジェクトになります
previousObstacleXPosition = firstObstaclePosition;
}
// CCBファイルから障害物オブジェクトを読み込み、生成します
Obstacle *obstacle = (Obstacle *)[CCBReader load:@"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
// 位置をランダムにします
[obstacle setupRandomPosition];
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
[/code]

これで障害物の位置がランダムになりました。 FlappyFly 7

表示順を変更する

障害物が地面の前に出てしまっているので、コードを加えて表示順を調整します。 定数の宣言の下あたりに、以下のコードを加えます。

[code language=”objc” title=”MainScene.m”]
typedef NS_ENUM(NSInteger, DrawingOrder) {
DrawingOrderPipes,
DrawingOrderGround,
DrawingOrdeHero
};
[/code]

さらに、didLoadFromCCBにZ軸の表示順を追記します。

[code language=”objc” title=”MainScene.m” highlight=”13,14,15,16,17″]
// CCBファイルからロード
– (void)didLoadFromCCB {
// 地面その1とその2を配列に追加
_grounds = @[_ground1, _ground2];
// タッチ操作可能にする。
self.userInteractionEnabled = TRUE;
// 最初の障害物を設置する
_obstacles = [NSMutableArray array];
[self spawnNewObstacle];
[self spawnNewObstacle];
[self spawnNewObstacle];

// 地面の表示順を変更する
for (CCNode *ground in _grounds) {
ground.zOrder = DrawingOrderGround;
}
_hero.zOrder = DrawingOrdeHero;
}
[/code]

最後にspawnNewobstacleを修正します。

[code language=”objc” title=”MainScene.m” highlight=”12,13″]
// 障害物を生成する
– (void)spawnNewObstacle {
CCNode *previousObstacle = [_obstacles lastObject];
CGFloat previousObstacleXPosition = previousObstacle.position.x;
if (!previousObstacle) {
// これが一番最初の障害物オブジェクトになります
previousObstacleXPosition = firstObstaclePosition;
}
// CCBファイルから障害物オブジェクトを読み込み、生成します
Obstacle *obstacle = (Obstacle *)[CCBReader load:@"Obstacle"];
obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles, 0);
// 表示順を変更します。
obstacle.zOrder = DrawingOrderPipes;
// 位置をランダムにします
[obstacle setupRandomPosition];
[_physicsNode addChild:obstacle];
[_obstacles addObject:obstacle];
}
[/code]

以上で表示順の設定が終わりました。

 

Flappy Fly 7

次回は当たり判定とゲームオーバー、リスタートの設定を行います。

 

[7:完成] cocos2d-iPhoneとSpriteBuilderでゲームを1週間で作ろう