---
title: {{ page_meta.name }}｜{{ group.public_title }}｜{{ site_settings.logo_alt }}
description: AgoraとReact.jsでWebアプリ（オセロゲーム）を実装した様子を大公開、第二弾です。
---

[Agora Go Real ](https://jp.vcube.com/sdk/blog)

# [{{ page_meta.name }}｜{{ group.public_title }}｜{{ site_settings.logo_alt }}](https://jp.vcube.com/sdk/blog/othello-2)

 作成者: [菊名 良一&礒部 洸生](https://jp.vcube.com/sdk/blog/author/kikuna-isobe)｜Sep 29, 2022 7:32:59 AM

# Agoraの利用用途

- [Agora Video SDK](https://docs.agora.io/en/Video/product_video?platform=All%20Platforms) for Web : 映像音声の送受信、映像音声のミュート・ミュート解除
- [**Agora RTM (Real-time Messaging) SDK **](https://docs.agora.io/en/Real-time-Messaging/product_rtm?platform=All%20Platforms)for Web : オセロゲーム機能、ゲーム参加者数の取得、ゲーム開始情報の送受信  
  (今回はこちらの実装記事です。)

# 実装概要

今回は、[前編の記事](https://jp.vcube.com/sdk/blog/othello-1)までの内容に加えてAgoraRTM SDKを導入し、チャット機能やリアルタイムでのオセロ対戦が出来るようにしていきます。

# 実装

## スタート画面

スタート画面の作成をします。  
「対戦する」又は「観戦する」を押下してメイン画面に入室する実装です。  
プレイヤー名を入力してから、「対戦する」を選択できるように実装しました。  
「対戦する」でゲーム画面に遷移したら、前半の記事で導入したwebRTCを使用して自分の映像が左上、相手の映像は右上に表示されるようになっています。

## チャットの実装

対戦者は映像・音声でコミュニケーション可能ですが、観客もコミュニケーションが取れるよう、テキストチャット機能を追加します。  
チャットの実装には、AgoraのRTMSDKを使用します。  
RTMSDKの機能であるchannel messageの送受信により、リアルタイムチャットを実現します。

※チャット部分の実装コードを抜粋

```

    const myRtmClient: RtmClient = AgoraRTM.createInstance(appId);
    const myRtmChannel: RtmChannel = myRtmClient.createChannel(channel);
    
    function joinRtm(){
     
        myRtmClient.on("ConnectionStateChanged", (newState, reason) => {
          console.log("on connection state changed to " + newState + " reason:" + reason);
        });
        myRtmChannel.on('MemberLeft', memberId => {
          alert("プレイヤーが退出しました");
          leave();
        })
        
        //Log in the Agora RTM system
        myRtmClient.login({uid: "" + client?.uid}).then(function(){
          console.log("AgoraRTM client login success");
          myRtmChannel.join().then(function(){
            console.log("AgoraRTM client join success");
            myRtmChannel.getMembers().then(function(uidList){
              if(localStorage.getItem('role') != 'audience') setRole(uidList);
            })
            receiveChannelMessage();
          }).catch(function (err){
            console.log("AgoraRTM client join failure, ", err);
          });
        }).catch(function(err){
          console.log("AgoraRTM client login failure, ", err);
        });
      }
     
      //チャンネルメッセージの送信
      function sendMessage(){
      
        var form = document.getElementById("messageForm") as HTMLInputElement;
        var message = form.value;
     
        myRtmChannel.sendMessage({ text: message }).then(() => {
          console.log("sendMessage");
          addMessageList("あなた : " + message);
          form.value = "";
        }).catch(error => {
          console.log(error);
        })
      }
     
      //チャンネルメッセージの受信
    function receiveChannelMessage(){
    
    
        myRtmChannel.on("ChannelMessage", function (sentMessage, senderId) {
          var message: string = JSON.parse(JSON.stringify(sentMessage)).text;
          console.log("メッセージ取得");
          console.log("メッセージ受信: " + JSON.stringify(sentMessage) + " from " + senderId);
          addMessageList(message);
          }
        })
    }
     
    //受信したメッセージをチャット欄に追加
    function addMessageList(message: string){
        var comment_element = document.createElement('li');
        comment_element.textContent = message;
        document.getElementById("comments")!.appendChild(comment_element);
    }
    
```

## オセロ対戦部分の実装

オセロのアルゴリズムの大部分は、下記記事を参考にしました。  
参考：[https://magazine.techacademy.jp/magazine/22767](https://magazine.techacademy.jp/magazine/22767)

肝心の「遠隔リアルタイム対戦の実現」においても、RTMSDKを使用します。

自分が石をどこに置いたかの情報をchannel messageに乗せて送る事で、盤面の状況を共有することが出来ます。

石の位置情報messageの内容は`placeOthelloPiece:${置いた場所を示す番号}`とすることで通常チャットと区別して処理します。

```

    //オセロの駒をどこに置いたかを伝え、盤面を相手に同期させる
    function sendPlaceOthelloPieces(index: number){
      myRtmChannel.sendMessage({ text: `placeOthelloPiece:${index}` }).then(() => {
        console.log("sendPlaceOthelloPieces(" + index + ")");
      }).catch(error => {
        console.log("errorだよ:" + error);
      }) 
    }
   
  //メッセージ受信時の挙動に場合分けを追加
    function receiveChannelMessage(){
      myRtmChannel.on("ChannelMessage", function (sentMessage, senderId) {
        var message: string = JSON.parse(JSON.stringify(sentMessage)).text;
        if(message.indexOf("placeOthelloPiece:") === 0){
          placeOpponentOthelloPiece(message);
        }else{
          console.log("メッセージ取得");
          console.log("メッセージ受信: " + JSON.stringify(sentMessage) + " from " + senderId);
          addMessageList(message);
        }
      })
    }
   
  //相手の打ち手を自分の画面で反映させる
  function placeOpponentOthelloPiece(message: string){
    var placeNum: number = Number(message.substring(18));
    onClickSquare(placeNum);     //自分が自分の番に石を置いた時と同じ処理
  }
```

またAgoraの機能とは少し異なりますが、対戦であるため現在どちらの手番であるかを直感的に分かるようにしたり、相手の手番の間は盤面のクリックを無効化するなどの工夫は別途で施す必要があります。

下の図は、実際に社内で対戦した様子です！

# 参照

[Agora.io Developer Center : Agora Web SDK API Reference](https://docs.agora.io/en/Video/API%20Reference/web/index.html)

[Agora.io Developer Center : RTM API Reference](https://docs.agora.io/en/Signaling/signal_web?platform=Web)

[Bootstrap](https://getbootstrap.com/)

# 最後に

ここまでの実装を通して、Agoraを用いる事で映像配信や通信部分の実装工数を抑え、自分達がオリジナリティーをもって実装したい箇所に時間を使えました！

今回はAgoraの中でも基本的な機能のみを用いて制作しましたが、まだAgoraを知ってから日が浅い社員でも満足いくゲームを作成することができました！

皆様も是非Agoraを使って面白いアプリを作っていただければ幸いです。

 

 

※『オセロ』は株式会社オセロが保有する登録商標です。

[完全な記事を表示](https://jp.vcube.com/sdk/blog/othello-2)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "菊名 良一&礒部 洸生"
  },
  "dateModified" : "2022-09-29T08:04:57.334Z",
  "datePublished" : "2022-09-29T07:32:59Z",
  "headline" : "新人がリアルタイムオセロゲームを実装してみた 後編",
  "image" : {
    "@type" : "ImageObject",
    "height" : 546,
    "url" : "https://1970584.fs1.hubspotusercontent-na1.net/hubfs/1970584/solution/sdk/blog/Othello-2/Othello-2_02.png",
    "width" : 900
  },
  "mainEntityOfPage" : "https://jp.vcube.com/sdk/blog/othello-2",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "Agora Go Real"
  }
}
```