TODO

目標のゲームを作るために必要そうなものをメモ。

イベント

  • ✔ prompt: 名前の入力など
  • ✔ confirm: はい・いいえ
  • ✔ replace: キャラクターを入れ替える

シーン

  • ✔ title: ゲームタイトル
  • ✔ settings: 言語・音声設定やライセンス表示
  • ✔ chapter: 章切り替え
  • ✔ ending: クリア後の画面
  • battle: 戦闘
  • menu: 装備など
  • continue: ゲームの再開

その他

  • utility: セーブ・ロード
  • utility: 音

年内を目指していたけど、厳しそうなので年度内を目標に。

コメント

触れた人と会話する

前回から少し時間が開いてしまいましたが、今回はキャラクターに話をさせてみます。

event.jsonファイルでデータを定義しています。

{
    "c1" : {
        "type" : "message",
        "message" : {
            "en" : "hello, world.",
            "ja" : "よくきた、○○よ。待って追ったぞ。ここは××研究所。これから旅に出るお主に、託したいものがあって呼んだのじゃ。その宝箱の中身を持って行くがよい。世界の平和を頼んだぞ。"
        }
    }
}

接触時のdelegateメソッドで、playerNodeがc1という名前のNodeに触れた時に、メッセージの内容を表示するようにしています。

- (void)didBeginContact:(SKPhysicsContact *)contact {
    SKPhysicsBody *firstBody, *secondBody;
    
    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    } else {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }
    
    if ((firstBody.categoryBitMask & playerCategory) != 0) {
        if ((secondBody.categoryBitMask & characterCategory) != 0) {
            SJCharacterNode *node = (SJCharacterNode *)secondBody.node;
            NSString *name = node.name;
            NSDictionary *e = [self event][name];
            if ([e[@"type"] isEqualToString:@"message"]) {
                _state = SJShopSceneStateMessage;
                [self messageNode].message = e[@"message"][[SJUtilities lang]];
                [self messageNode].hidden = NO;
            }
        }
    }
}

メッセージの表示は、新たに追加したSJMessageNodeに担当させています。

SKLabelNodeが複数行表示に対応していないため、行数分並べて表示するという泥臭い実装になっています。 特別なことをしていない上に無駄に長いため、引用はやめておきます。

無事、キャラクターに話しかけることができるようになりました。


唐突な会話

次は他のシーンへの遷移を実装します。

ソースコード: sj-prototype-apps/SJRolePlaying at master · tnantoka/sj-prototype-apps

コメント

Spkite Kitの物理エンジン向けデバッグドロー用ライブラリ「PhysicsDebugger」

Sprite Kitには物理エンジンが組み込まれており、簡単に物理シミュレーションが利用できて便利です。
ただ、デバッグ表示用の機能がないため、どこにPhysicsBodyを追加したか、見た目では知ることができません。

そんな不満を解決してくれるのが、PhysicsDebuggerです。

早速使ってみます。

インストール

CocoaPodsに対応してるので簡単です。

# ターミナルを起動してプロジェクトのフォルダまで移動

# CocoaPodsをインストールしてない人
$ gem install cocoapods
$ pod install 

# Podfile
platform :ios, '7.0'

pod 'PhysicsDebugger'

# インストール
$ pod
Analyzing dependencies
Downloading dependencies
Installing PhysicsDebugger (1.0.0)
Generating Pods project
Integrating client project

[!] From now on use `SJRolePlaying.xcworkspace`.

CocoaPodsを初めて使う場合、これ以降.xcodeprojではなく、.xcworkspaceを開く必要があることに注意してください。

利用方法

ヘッダをインポートして、描画対象のノードが作成される前に、initを呼び、 drawPhysicsBodiesを呼びます。

今回は、SJMapNodeに追加してみました。

#import "YMCPhysicsDebugger.h"
#import "YMCSKNode+PhysicsDebug.h"

- (void)createNodeContents {
    
    [YMCPhysicsDebugger init];

    /* ノードの作成・追加 */
    
    [self drawPhysicsBodies];
}

これで実行すると、以下のようにPhysicsBodyに赤枠がついて可視化されます。


赤枠が表示される

感想

手軽に使えて便利でした。

ただ、ちょっとコードに手を加える量が多いかなぁ、という印象。 まぁそれでも、毎回PhysicsBodyと同じ大きさのShapeNodeを作成して追加する、とかに比べればはるかに綺麗ですが。

あと、このライブラリに限った話ではないですが、デバッグドローのぶんNodeの数が増えて動作がもっさりになるので、常に使用しながらの開発は厳しいかもしれません。

しばらく使って様子を見てみようと思います。

コメント

お店の中に他のキャラクターを登場させる

今日はマップ内に他のキャラクターを表示してみます。

前回はSJCharacgterNodeの中に定数でいろいろと持たせていましたが、 characters.jsonというファイルで定義するようにしました。1

{
    "default" : {
        "stop_time" : 0.6,
        "walk_time" : 0.3,
        "speed": 0.2
    },
    "c0" : {
        "name" : "clotharmor",
        "stop_row" : 0,
        "stop_cols" : 2,
        "walk_row" : 1,
        "walk_cols" : 4,
        "up_row" : 3,
        "right_row" : 6,
        "left_row" : 6,
        "size": 64
    },
    "c1" : {
        "name" : "scientist",
        "stop_row" : 0,
        "stop_cols" : 2,
        "walk_row" : 0,
        "walk_cols" : 2,
        "up_row" : 0,
        "right_row" : 0,
        "left_row" : 0,
        "size": 48
    },
    "c2" : {
        "name" : "chest",
        "stop_row" : 0,
        "stop_cols" : 1,
        "walk_row" : 0,
        "walk_cols" : 1,
        "up_row" : 0,
        "right_row" : 0,
        "left_row" : 0,
        "size": 32
    }
}

マップデータでどこに配置するか指定します。

-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,c2,c1,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,-,-,-,-,-,-
-,-,-,-,c0,-,-,-,-,-

SJMapNode内で、cから始まるデータの場合はキャラクターを生成するようにします。

} else if ([col hasPrefix:@"c"]) {
    tileSprite = [[SJCharacterNode alloc] initWithCharacterNamed:col];

    tileSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(TILE_SIZE, TILE_SIZE)];
    tileSprite.physicsBody.affectedByGravity = NO;
    tileSprite.physicsBody.allowsRotation = NO;

    tileSprite.name = col;

} 

SJCharacterNodeではjsonから設定を読み取ります。 この値を定数の代わりに使います。

- (id)initWithCharacterNamed:(NSString *)name {
    
    NSString *path = [[NSBundle mainBundle] pathForResource:CHARACTERS_NAME ofType:@"json"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSError *error = nil;
    NSDictionary *characters = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    if (error) {
        NSLog(@"%@", [error localizedDescription]);
    }
    NSMutableDictionary *character = [characters[@"default"] mutableCopy];

    [character addEntriesFromDictionary:characters[name]];

    CGFloat size = [character[@"size"] floatValue];
    
    if (self = [super initWithColor:nil size:CGSizeMake(size, size)]) {
        _character = character;
        [self createNodeContents];
    }
    return self;
}

完成です。


ひとりじゃない

相変わらず全然お店ではないですが、見た目はゲームっぽくなってきました。

次は会話を実装する予定です。

ソースコード: sj-prototype-apps/SJRolePlaying at master · tnantoka/sj-prototype-apps

  1. Objective-C的にはplistを使うのが定石だと思いますが、個人的にplistが苦手なのでここではJSONにしています。 

コメント

Mac OS X 10.9 Mavericksがリリースされました

ついにリリースされましたね。

正直なところ、そこまで魅力は感じていなかったんですが、まさかの無料ということで早速アップグレードしました。 今まで作ったサンプルが、最新版のXcodeでも問題なく動いていて一安心です。

残念ながら、このタイミングでも、日本語ドキュメント - Apple DeveloperにSprite Kit Programming Guideは追加されませんでした。 こうなると、しばらくは翻訳されなさそうです…。

NDA期間も終わったことだし、今後は機会があればMac向けの情報も扱っていきたいと思います。

コメント

SpriteKitではじめる2Dゲームプログラミング Swift対応 (Smart Game Developer)