2015年12月

1. ランタイムエラー

やる気なくさすわあ、、


さあいよいよプレイヤー画像を「アニメーション」させるぞお!と思ってさ、コーディングして実行したら、ランタイムエラー。

ゲームは起動できるのに、爆弾をキャッチしようとしたらフリーズ。フリーズキタコレ。超絶ゲームっぽい。いらないよそんなゲームっぽさ。
とにかく、なんでか分からないけど爆弾と接触するとフリーズしちゃう。

エラーコードも謎。


「thread 1 signal sigabrt」

Google翻訳「スレッド1信号SIGABRT」

えーらいこっちゃえーらいこっちゃヨイヨイヨイヨイ。。


thread 1 signal sigabrt」で検索。
ーーーーーーーーーー
Thread 1:signal SIGABRT とは何か?

一言で言えば、iPhoneアプリ開発者が避けては通れぬ「鬼門」である。

もっとも簡潔にいうと、「バグ」でしょう。

Thread 1:signal SIGABRT の原因はアプリごとによって様々あり、具体的にこれだ!というのは特定できないと思う。よって、自分でしっかりプログラムを理解し、何度も書籍を読んだりプログラムを見直したりして、直していくしかない。

直るとわかるのだが、原因は基本的な初歩的な間違いである場合が多い。
ただし、膨大なプログラムソースからその「初歩的な間違い」を探すのはとてもめんどくさい。
ーーーーーーーーーー「iPhoneアプリ開発の基本コード集」というサイトより引用して要約

無理くさくない?
僕には解決不可能な問題っぽくない?


あああ、、どうしよう、、

休憩。



36:24
2. 解決

わっはっは、この僕を悩まそうなんて100年早いわ!


そう言えばコードを載せてなかったね。
まずフリーズするコードを見てあげてよ。どこがダメなのかすぐ分かったらその人にはKissをあげよう。お年玉だね。

MainScene.hより
ーーーーーーーーーー
〜省略〜

    

    // _player変数 と、 getPlayer() メソッド、 setPlayer( Sprite *)メソッド  自動的  実装  れる
    CC_SYNTHESIZE_RETAIN(cocos2d::Sprite *,_player,Player);
    CC_SYNTHESIZE (cocos2d::Vector<cocos2d ::Sprite*>,_fruits,Fruits) ;
    CC_SYNTHESIZEint,_score, Score);
    CC_SYNTHESIZE_RETAIN(cocos2d::Label*, _scoreLabel, ScoreLabel);
    CC_SYNTHESIZEfloat_second, Second);
    CC_SYNTHESIZE_RETAINcocos2d::Label*, _secondLabel, SecondLabel);
    CC_SYNTHESIZEbool_isCrash, IsCrash);

〜省略〜
ーーーーーーーーーー「cocos2d-xではじめるスマートフォンゲーム開発」から引用

MainScene.cppより
ーーーーーーーーーー
〜省略〜

MainScene::MainScene()
_score0)
_playerNULL)
_scoreLabelNULL)
_second(TIME_LIMIT_SECOND)
_secondLabelNULL)
_state(GameState::PLAYING)
_isCrashfalse)
{
}
〜省略〜

bool MainScene::init()
{
〜省略〜
    listener->onTouchMoved = [this,size](Touch* touch,  Event* event) {
        // タッチ位置が動いたとき
        if (!this->getIsCrash()) {  // クラッシュ して ない とき
〜省略〜
            _player->setPosition(newPosition);
        }
    };
〜省略〜
    return true;
}

void MainScene::catchFruit( cocos2d:: Sprite *fruit)
{
    // もし クラッシュ   たら、 フルーツ  取得 でき ない
    if (this->getIsCrash()) {
        return;
    }
〜省略〜

void MainScene:: onCatchBomb()
{
    // クラッシュ 状態   する
    _isCrash = true;

    

    // アニメーション  作成
    Vector < SpriteFrame *> frames;
    auto playerSize = _player->getContentSize();
    const int animationFrameCount = 3// アニメーション  フレーム 

    

    // アニメ   フレーム  読み込む
    for (int i = 0; i < animationFrameCount; i){
        auto rect = Rect( playerSize.  width * i, 0, playerSize. width, playerSize.height);
        auto frame = SpriteFrame:: create( "player_crash.png", rect) ;
        frames. pushBack( frame);}

    

    // アニメーション  作成  する
    auto animation = Animation:: createWithSpriteFrames( frames,  10.0 / 60.0);
    animation->setLoops3); // 3   繰り返し  再生 する
    animation->setRestoreOriginalFrametrue );
    _player->runActionSequence::  createAnimate:: create( animation),CallFunc:: create([ this] {_isCrash =  false;}),NULL));

    

    _score = MAX 0_score - BOMB_PENALTY_SCORE); // 4   引い  0 未満  なっ たら 0    する
    CocosDenshion:: SimpleAudioEngine:: getInstance ()-> playEffect("crash.mp3");
}
ーーーーーーーーーー「cocos2d-xではじめるスマートフォンゲーム開発」から引用

これを実行したらランタイムエラーでフリーズしたわけね。
なんでか分かるわけないよね。ググってもサッパリだった。

でも解決したよ。


休憩後解決編。



42:18
3. 解決編

さてさてサクッと解説しよう。


onCatchBomb() の「 for (int i = 0; i < animationFrameCount; i){ 」の「i」が間違いだった。正確なコードは「for ( int i = 0; i < animationFrameCount; ++i){ 」だったんだよ。
それだけ。それだけだよ。ただここが間違いでもビルドエラーにはならないから、どこを直せばいいのか分からなかったんだよね。「赤字」で示してくれないわけ。

じゃあどうやって気づいたかっていうと、「黄色」で示してくれてた。


「Expression result unused」
「式 結果 未使用の」

よく分かんないけど、ここがダメだったんだね。
ただ「黄色」だからさ、「間違い」ってわけじゃないわけよ。現に他にも黄色の警告はたくさんあるんだけど、今まで問題にならなかった。だから今回もスルーしちゃったわけね。
そんで頭抱えてたんだけど、もしやと思って黄色のコードを見直してみたら上述の間違いに気づいたってわけ。


それでは修正したコードで、実行。

大成功!
って今回も画像では説明しにくいんだよねえ。アニメーションだからさあ。

分かるかな微妙にプレイヤーがアニメーションしてるのが。

んでもってこのアニメーションの最中は移動できないしフルーツをキャッチもできないようになってるよ。もちろん爆弾もキャッチ不可。ゴースト状態だね。


と、こんな感じだね。
コードの攻略は次回からでいいっしょ。正月だしね。関係ないけどね。

それではみなさままた明日。



1. 大晦日

の夜に英語の勉強しようなんて奇特な奴は日本でも僕ぐらいなもんなんじゃない?んなわけないよね。


ーーーーーーーーーー
・reach /riːtʃ「ぅいーちゅ」  
他)〜に着く、(手)を差し出す、〜に手が届く、[+O,for O]〜にOを取ってやる※間違い。正しくは下記、〜に達する   
自)手を差し出す、[+for]〜を取ろうとする、手が届く、達する   
名)届く範囲、伸ばすこと

・read /riːd「ぅいーど」  
他)基本略、[+O,to O]〜にOを読んで聞かせる※間違いだね、〜を読んで理解する   
自)読書する、(+about,of)(〜について)読んで理解する、音読する
ーーーーーーーーーーウィズダム英和辞典から引用して要約して加筆
2016/1/8書式変更

やっばい眠い。。



37:08
2. メームイ

2個しか単語やってないけどw


と、そう言えば上の訳に間違いがあるね。
「[+O,for O]〜にOを取ってやる」
これは正しくは「[+O]〜にOを取ってやる、(+for)(〜に)〜を取ってやる」ってことだよね。
「[+O,to O]〜にOを読んで聞かせる」もそうだね。「[+O]〜にOを読んで聞かせる、(+to)(〜に)〜を読んで聞かせる」ってのが正しいね。
要は「SVOO」なのか「SVO+前置詞」なのかの違いだね。


・愛ゥイーチュ有エロ本、愛ゥイーチュえろ本法有
・愛ゥイード有エロ本、愛ゥイードえろ本等有


流石に今回は優秀賞はないよ。どっちも似たような単語だしさ。

イラストでも書いとこう。



いやあ、新年早々素晴らしいイラストが描けたね。逆の意味で素晴らしいイラストね。


砂利図オール法NOW!
good-by海老わん!andテイク座ニューイヤー!!

「テイク座ニューイヤー」は僕が考えた造語だよ。たぶんそんな表現ないと思うよ。



体重(kg) 73.3

体脂肪率(%) 19.8

BMI 22.9


年末だしさ、久しぶりに測ってみたんだけど、、だいぶ増えたね。当然だけどさ。

体脂肪率はそれほど変わってないのが救いだね。



 



体温(℃) 36.3




お通じ バナナ1.0


やっぱ食べると調子いいよ。




食べたもの

深夜 キムチとネギ入り袋ラーメン×2、ポテチ100g

朝 なし

昼 ハリボーグミ20gくらい

夜 まだ


最近は好きなもの好きなだけ食べてたよ。今日も今から年越し牛丼食べに行くつもりだよ。タップリとね。




歩き、はもう意味ないから記録しません。




体のサイズね。


胸囲(cm) 92

ウエスト(cm) 75〜81 平均78(前回77)

太もも(cm) 54.5

二の腕(cm) 28


ウエストが増えちゃったね。まあしゃーない。




写真も載せとこう。 


※注意※

この先に半裸の男の画像があります。

























前回12/22時点



今回12/31現在



まんまと下腹が出てきてるね。ショックう😨

仕方ない。除染が始まればまた元に戻るっしょ。たぶんね。そう願いたいね。


月末まとめはまた別でやるよ。




部屋の掃除するぞお!
前回から約1ヶ月。たった1ヶ月で酷い有様だよ。こんなんで年は越せない。

 


15:49
っしゃサクッとキッチンの掃除完了!



16:06
っしゃ頑張った。

半分くらいは進んだ?まだまだかな?


16:44
っしゃららら!

もう完了ってことでもいいような気がするけど、もうちょいかな?


16:59
っしゃオッケー。

完璧!
これにて年末大掃除終了!!年越しまくりだぜ👍👍👍




とりあえずBeforeを見せておかないとね。

※注意※
下に汚部屋の写真があります。今回は前回ほど酷くはないです。「散らかってる」って感じ。





























Before画像



頑張るぞ!!


1. 更新だけ

ですしおすし。


今回は爆弾の処理の実装だね。
こいつはかなりややこしそうなんだよね。チラッと教科書見た感じだとさ。
どうやらプレイヤー画像を "アニメーション" させるらしい。

「アニメーション」

そんな恐れ多い技術を使おうなんて考えたこともなかったけど、やっぱ多少は必要だよね。面白いゲーム作るにはさ。


とりあえず休憩だね。
寝る前に少しでも進めときたいところだけど、、



37:18
2. サンプルコード

もう大晦日じゃんね。。


「アニメーション」の前にさ、爆弾をキャッチするとスコアがマイナスされて専用の効果音が鳴るように処理を追加するところだけまずは実装しておこう。

MainScene.hより 
ーーーーーーーーーー
〜省略〜

    /** ゲーム  終了   ときに 呼び出さ  ます 
     */
    void onResult();

    

    /** 爆弾  取っ  しまっ  とき 呼び出さ  ます
     */
    void onCatchBomb();

};

#endif /* defined(__KawazCatch__MainScene__) */
ーーーーーーーーーー「cocos2d-xではじめるスマートフォンゲーム開発」から引用

MainScene.cppより 
ーーーーーーーーーー
#include "SimpleAudioEngine.h"
#include "MainScene.h"

USING_NS_CC;

///フル ーツの画面上端からのマ ージン ( p x )
const int FRUIT_TOP_MARGIN = 40;
/// フルーツ  出現 
const int FRUIT_SPAWN_RATE = 10;
/// 制限 時間
const float TIME_LIMIT_SECOND = 30;
/// 黄金  フルーツ  取っ  とき 点数
const int GOLDEN_FRUIT_SCORE = 5;
 /// 爆弾  取っ  とき  マイナス
const int BOMB_PENALTY_SCORE = 4;

〜省略〜

void MainScene::catchFruit( cocos2d:: Sprite *fruit)
{
    auto audioEngine = CocosDenshion::SimpleAudioEngine :: getInstance();
    // フルーツ タイプ   取得
    FruitType fruitType = static_cast < FruitType >( fruit-> getTag());
    switch (fruitType) {
        case MainScene:: FruitType  :: GOLDEN:
            // 黄金   フルーツ   とき
            _score  += GOLDEN_FRUIT_SCORE;
            audioEngine->playEffect("catch_golden.mp3");
            break;
        case MainScene:: FruitType  :: BOMB:
            // 爆弾    とき
            this->onCatchBomb();
            audioEngine->playEffect("catch_bomb.mp3");
            break;
        default:
            // その他   フルーツ  とき
        _score  += 1;
        audioEngine->playEffect("catch_fruit.mp3");
        break;
    }
    // フルーツ  削除 する
    this->removeFruit( fruit);
    // スコア   ラベル の   表示 更新する
    _scoreLabel->setStringStringUtils ::  toString(_score));
}

〜省略〜

void MainScene:: onCatchBomb()
{
    _score = MAX 0_score - BOMB_PENALTY_SCORE); // 4    引い 0 未満  なっ たら 0     する
    CocosDenshion:: SimpleAudioEngine::  getInstance()-> playEffect("crash.mp3");
}
ーーーーーーーーーー「cocos2d-xではじめるスマートフォンゲーム開発」から引用

resourceファイルに音声データ追加。


実行。

大成功!
まあ金のリンゴと同じようなもんだよね。変動するスコアの値と効果音が変わっただけ。

なんか、攻略が必要なコードなんてないような、、


まあ休憩しようよ。



38:00
3. コード攻略

まあサラサラ〜っとやっとこう。


まずは MainScene.h の void onCatchBomb(); 。
プロトタイプ関数の宣言。爆弾をキャッチすると呼び出されるんだろうね。

続いて MainScene.cpp の const int BOMB_PENALTY_SCORE = 4; 。説明不要だね。

次、catchFruit() の実装としての switch文における this->onCatchBomb(); 。
MainScene.h で宣言したプロトタイプ関数の呼び出しだね。実装は最後に書かれてる。

次、audioEngine->playEffect("catch_bomb.mp3"); 。説明不要だよね。金のリンゴと全く同じ。音声データ名が違うだけ。

次、onCatchBomb() の実装。
最初は _score = MAX 0 _score - BOMB_PENALTY_SCORE); 。
こいつが少しややこしいかな?なんとなく想像はつくだろうけどさ。
MAX() なんて関数は知らないよね。初めて見る。ってか "型" がないってことはこいつは関数じゃなさそうだよね。
こいつは "マクロ" なんだね。マクロってC++のここでやったね。
定義がどこに書いてあるのかは分からないけど、cocos2d.h のどっかにあるんだろうねたぶん。

公式referenceを確認してみよう。
ーーーーーーーーーー
#define MAX ( x , y )
(((x) < (y)) ? (y) : (x))
ーーーーーーーーーーcocos2d-x公式referenceより引用

(((x) < (y)) ? (y) : (x)) ってのがこのマクロのテキストなんだろうね。
< が演算子なのは分かるとして、?と: が何者なのかだよね。

「苦C」に解説があったよ。
ーーーーーーーーーー
?と:    真の時は前式を、偽の時は後式を代入
ーーーーーーーーーー「苦C」より引用

なるほどだね。(((x) < (y)) ? (y) : (x)) で言うと (x) < (y) が 真なら y を、偽なら x を返すわけだね。
これを  _score = MAX 0 _score - BOMB_PENALTY_SCORE); に当てはめると、(0) < (_score -  BOMB_PENALTY_SCORE) が真なら _score - BOMB_PENALTY_SCORE を、偽なら 0 を返すわけだ。
BOMB_PENALTY_SCORE は初っ端に 4 で定数として初期化されてたんだから、つまり「_score - 4」が 0 より大きいか小さいか、正か負かってことを確認したわけだね。
んで、正ならそのまま_score - 4」を返して、負なら「_score  - 4」は返さずに 0 を返すってことになるわけだね。なるほどだね。コメントにも「 // 4  引い 0 未満   なっ たら 0    する」って書いてあるね。オッケー。

そして最後、CocosDenshion:: SimpleAudioEngine::  getInstance ()-> playEffect("crash.mp3"); 。
口を酸っぱくして言うけど、「シンプルトンなクラスを使うときは getInstance() でオブジェクトを作成しろ!」 (ここの2) ってことだったね。それ以外は説明不要だね。

と思ったけど、そういえば音声データの追加なんだけど、catchFruit() 内のswitch文中でも爆弾をキャッチした効果音として audioEngine->playEffect("catch_bomb.mp3"); で catch_bomb.mp3 が追加されてたじゃんね?なのにまた onCatchBomb() でも crash.mp3 っていう別の効果音を追加するのってなんか変じゃね?って感じもするんだけどさ、これはそのまんま「別な効果音」なんだね。
catchFruit() で追加した catch_bomb.mp3 ってのは「プレイヤーがキャッチした音」として鳴る効果音で、onCatchBomb() の crash.mp3 は「キャッチした爆弾が爆発する音」として鳴る効果音なわけよ。
同じじゃね?って感じなんだけど、鳴るタイミングが同じなだけで二つは別な効果音なんだね。実際の音としても catch_bomb.mp3 は「ピヨピヨ」って感じのダメージを喰らった的な音、crash.mp3 はそのまんま「ボカーン」って感じの爆発するような音だよ。全く同じタイミングで鳴るから少し聞き取りづらいけどね。
なぜ効果音を分けるのかは、、たぶんだけど、臨場感? ボカーンだけでもピヨピヨだけでもなんか物足りないじゃんね?
それとなぜ効果音の処理を実装する関数を変えるのか?同じ関数に二つとも並べて書けばいくね?って感じもするけど、その辺りはさ、やっぱ二つは別な効果音なわけだから、処理する関数も変えるべきじゃね?的な?たぶんね。分からないけどね。どっちにしろそんな大した問題ではないよね。


よしよし、オッケー。
今回はこんなもんにしとこう。「アニメーション」は次回ね。今から年末の大掃除やらなきゃだからさ。

それでは皆さん、良いお年を!

、、じゃなかったね。次回も今日中に更新しなきゃなんだから、まだ今年は終わってない。
というわけで、、

それでは皆さん、良い大晦日を!!



↑このページのトップヘ