▲前のページへ
次のページへ▼

キャラクタ同期(3) キャラクタの同期


【目次】
自分自身の情報をサーバに転送する
サーバから受信した他プレイヤーの状況をクライアントに反映させる


自分自身の情報をサーバに転送する

 ここから実際のキャラクタ同期処理に移ります。
 まずはローカル環境で動いている「プレイヤー自身のキャラクタ」の情報をサーバに転送しないと
 お話になりませんので、そこから組み込んでいきましょう。

■ サーバに送信するための構造体変数を準備する
  まずはサーバに送信するための構造体変数を準備します。
  Eclipse の prefork_battle_matching プロジェクト内にある Classes/SceneClass04.h を開き、
  以下の変数を宣言してください。
        BTL::BattlePlayerInfo                   m_MyInfo;
  

■ m_MyInfo を初期化する
  宣言した変数について、 Classes/SceneClass04.cpp にある SceneClass04::initializeLogic() 関数で初期化します。
  以下のコードを関数内に加えてください。
        // キャラクタの送信情報
        m_MyInfo.chara_id = ClientScene01::GetCharaId();
  

■ 自分自身の座標をサーバ宛に送信する
  後は、上記で追加した m_MyInfo を使って、自分自身の座標をサーバ宛に送信すれば完了です。
  Classes/SceneClass04.cpp にある SceneClass04::updateLogic() 関数にて以下の処理を実行してください。
        // 自身の目標座標の送信処理
        m_MyInfo.position[0] = m_MyTarget.x;
        m_MyInfo.position[1] = m_MyTarget.y;
        m_MyInfo.position_len = 2;
        ClientScene01::GetClient()->SendPlayerInfo(m_MyInfo);
  


サーバから受信した他プレイヤーの状況をクライアントに反映させる

■ 途中退室したキャラクタを抹消する
  プレイヤーが途中退室したかどうかを検知する方法は様々ありますが、
  最も簡易的で確実なのが、「非プレイヤーキャラクタの位置情報を最後に受信してからどのくらい時間経過したか」を調べる方法です。

  既に「最後に受信した時間」については受信処理時に m_Receive リスト内の receiveTime で計測していますので、
  その値と現在の時間とを比較し、一定以上経過していたら削除するようにしてみましょう。

  ClientScene04.cpp を開き、ClientScene04::updateLogic() 関数に以下の処理を加えてください。
	// キャラクタの消去処理
	for( std::map<uint64, ClientScene04::RecvInfo>::iterator it = m_ReceiveList.begin(); it != m_ReceiveList.end(); )
        {
                // 受信なし状態が5秒以上続いたら、その端末のキャラクタを消す
                if( (double)(clock() - it->second.receiveTime) / CLOCKS_PER_SEC > 5 )
                {
                        it->second.pSprite->removeFromParentAndCleanup(this);
                        it->second.pSprite = NULL;
                        m_ReceiveList.erase(it++);
                }
                else
                {
                        it++;
                }
        }
  

■ 他プレイヤーに対して、アニメーション進行処理を実行する
  途中退室していない他プレイヤーについて、アニメーション進行処理を実行します。
  これも既に ClientScene04::updateCharaAnimで実装済みですので、これを for ループで他プレイヤーの数だけ回すことになります。

  ただし、この時点でキャラクタスプライトを生成していないオブジェクトがある場合には、その他プレイヤーのキャラクタを表示させるための
  画像データを新規に読み込むのを忘れないようにします。

  では、ClientScene04.cpp を開き、ClientScene04::updateLogic() 関数に以下の処理を加えてください。
        // 現時点での全ての接続済みキャラクタに対し、適宜処理を実行する
        for( std::map<uint64, ClientScene04::RecvInfo>::iterator it = m_ReceiveList.begin(); it != m_ReceiveList.end(); it++ )
        {
                // キャラクタスプライトの新規追加
                if( it->second.pSprite == NULL )
                {
                        it->second.pSprite = Sprite::create("chara/chara08.png");
                        it->second.pSprite->setPosition(it->second.target);
                        this->addChild(it->second.pSprite);
                }

                // キャラクタアニメーションの実行
                updateCharaAnim(it->second.pSprite, &it->second.target, Point(it->second.info.position[0], it->second.info.position[1]));
        }
  

  これで、キャラクタ同期にともなう送受信処理本体が完成しました。


▲前のページへ
次のページへ▼