React.js

初心者向けのReact.jsで作る超簡単な数字当てゲームアプリ

初心者向けのReact.jsで作る超簡単な数字当てゲームアプリ

みなさんこんにちは、からんです。

今回解説するのはReact.jsで作る数字当てゲームです。

仕様

最初の状態が下記になります。

「1」・「2」・「3」のボタンがありますがそれをクリックします。

すると自動的にランダムで数字が選ばれるのですがクリックしたボタンの数字と同じなら「あなたのポイント」と書かれた所にあなたが選んだ数字がポイントが加算されて違うならあなたが選んだ数字の値だけポイントが減っていきます。

これを10回繰り返して最終的なポイントが「あなたのポイント」と書いてある所に表示されてリセットボタンを押すとまた最初の状態に戻ります。

デモ

デモはここから見ることができます。

最初の表示

今回はバベルを使って実装していきますが下記をコピーしてHTMLファイルに貼り付けて下さい。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Reactで作った数当てゲーム</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css" />
  <link href="./css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div id="root"></div>

  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">

  const Point = () => {
    
    //ここに書いていく
    
    
  };

const root = document.getElementById('root');
ReactDOM.render(<Point />, root);

  </script>
</body>
</html>

まずは下記の表示をさせます。

コードを下記にします。

const Point = () => {
   
    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <dl>
          <dt className="random"></dt>
          <dd>
            <button>1</button>
            <button>2</button>
            <button>3</button>
          </dd>
        </dl>
        <p>ボタンを押せるのはあと回です</p>
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point"></dd>
        </dl>
      </div>
    );
};

?・ボタンを押せる回数・「あなたのポイント」が変化する最初の状態

下記の赤枠を変化させます。

変化ができるようにする為に最初の状態をuseState hooksで設定します。コードを下記にします。

const Point = () => {
    const [number,changeNumber] = React.useState('?');
    const [myPoint,myPointChange] = React.useState(0);
    const [count,countDown] = React.useState(10);

    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <dl>
          <dt className="random">{number}</dt>    //{number}を追加
          <dd>
            <button>1</button>
            <button>2</button>
            <button>3</button>
          </dd>
        </dl>
        <p>ボタンを押せるのはあと{count}回です</p>      //{count}を追加
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point">{myPoint}</dd>         //{myPoint}を追加
        </dl>
      </div>
    );
 };

「あなたのポイント」を変化させる

数字が「1」・「2」・「3」のボタンをクリックするとランダムで選ばれる数字を決定できるようにします。

そして自分の選んだ数字とランダムで選ばれる数字が同じだったら自分のポイントにランダムで選ばれたポイントを加えてそうでない場合は自分のポイントからランダムで選ばれたポイントを引きます。

ランダムの数字を選ぶのは配列を使います。

コードを下記にします。

const Point = () => {
    const [number,changeNumber] = React.useState('?');
    const [myPoint,myPointChange] = React.useState(0);
    const [count,countDown] = React.useState(10);

    //ここから追加-
    const selectNumber = (myNumber) => {

      const randomNumber = Math.floor(Math.random()*3);
      const suji = [1,2,3];
      let naturalNumber = suji[randomNumber]; 

      if(myNumber === naturalNumber && myNumber >= 1){
        let plusPoint = myPoint + naturalNumber; 
        myPointChange(plusPoint);
      }else{
        let minusPoint = myPoint - naturalNumber;
        myPointChange(minusPoint);
      };
   }
   //ここまで追加

    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <dl>
          <dt className="random">{number}</dt>
          <dd>
            <button onClick={()=>selectNumber(1)}>1</button>  //onClickメソッドの追加
            <button onClick={()=>selectNumber(2)}>2</button>  //onClickメソッドの追加
            <button onClick={()=>selectNumber(3)}>3</button>  //onClickメソッドの追加
          </dd>
        </dl>
        <p>ボタンを押せるのはあと{count}回です</p>
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point">{myPoint}</dd>
        </dl>
      </div>
    );
};

次は「?」にランダムで選ばれた数字が表示します。

「?」にランダムで選ばれた数字を表示してボタンを押せる回数を減らす

コードを下記にします。

const Point = () => {
    const [number,changeNumber] = React.useState('?');
    const [myPoint,myPointChange] = React.useState(0);
    const [count,countDown] = React.useState(10);

    const selectNumber = (myNumber) => {

      const randomNumber = Math.floor(Math.random()*3);
      const suji = [1,2,3];
      let naturalNumber = suji[randomNumber]; 

      if(myNumber === naturalNumber && myNumber >= 1){
        let plusPoint = myPoint + naturalNumber; 
        myPointChange(plusPoint);
      }else{
        let minusPoint = myPoint - naturalNumber;
        myPointChange(minusPoint);
      };
      
      //ここから追加
      changeNumber(naturalNumber);

      countDown(count=>count-1);
      //ここまで追加
   }

    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <dl>
          <dt className="random">{number}</dt>
          <dd>
            <button onClick={()=>selectNumber(1)}>1</button>  
            <button onClick={()=>selectNumber(2)}>2</button> 
            <button onClick={()=>selectNumber(3)}>3</button>  
          </dd>
        </dl>
        <p>ボタンを押せるのはあと{count}回です</p>
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point">{myPoint}</dd>
        </dl>
      </div>
    );
  };

これで?が変わるようになって「1」・「2」・「3」のどれかの数字を押すたびにボタンを押せる回数が減っていきます。

リセットボタンの表示

このままでは「1」・「2」・「3」のボタンをずーっと押し続けることができてボタンを押す回数が0回になったらリセットして最初に戻ることができるようにします。

現在リセットボタンは非表示ですがボタンを押す回数が0になったら表示されるようにします。

ボタンを押す回数が0かそうでないかで表示の切り分けをしますが三項演算子を使います。

また子コンポーネントを作ります、その際に親コンポーネントから子コンポーネントにprops({button,number})を送ります。

リセットボタンを押した時に最初に表示された状態に戻します。

コードを下記にします。

const Point = () => {
    const [number,changeNumber] = React.useState('?');
    const [myPoint,myPointChange] = React.useState(0);
    const [count,countDown] = React.useState(10);
    const [reset,setReset] = React.useState('');

    const selectNumber = (myNumber) => {

      const randomNumber = Math.floor(Math.random()*3);
      const suji = [1,2,3];
      let naturalNumber = suji[randomNumber]; 

      if(myNumber === naturalNumber && myNumber >= 1){
        let plusPoint = myPoint + naturalNumber; 
        myPointChange(plusPoint);
      }else{
        let minusPoint = myPoint - naturalNumber;
        myPointChange(minusPoint);
      };

      changeNumber(naturalNumber);

      countDown(count=>count-1);
      
      //ここから追加
      if(count === 0){
        onRestart();
      };
      //ここまで追加
      
    };

  //ここから追加
    const onRestart = () => {
      changeNumber('?');
      myPointChange(0);
      countDown(10);
    };

    const Button = ({button,number}) => {  
      return(
        <>
          {
            count === 0
            ?
            <button onClick={onRestart}>リセット</button>
            :
            <div>
              <dl>
                <dt className="random">{number}</dt>
                <dd>
                  <button onClick={()=>selectNumber(1)}>1</button>
                  <button onClick={()=>selectNumber(2)}>2</button>
                  <button onClick={()=>selectNumber(3)}>3</button>
                </dd>
              </dl>
              <p>ボタンを押せるのはあと{count}回です</p>

            </div>
          }
        </>
      );
    };
    //ここまで追加

    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <Button number={number} count={count}/>  //number={number}とcount={count}を追加
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point">{myPoint}</dd>
        </dl>
      </div>
    );
  };

最初はリセットボタンは非表示ですがボタンを押す回数が0になったら下記のように表示されるようにします。

これで完成です。

最後に全てのコードを載せます。

完成系のコード

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Reactで作った数当てゲーム</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css" />
  <link href="./css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div id="root"></div>

  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">

  const Point = () => {
    const [number,changeNumber] = React.useState('?');
    const [myPoint,myPointChange] = React.useState(0);
    const [count,countDown] = React.useState(10);
    const [reset,setReset] = React.useState('');

    const selectNumber = (myNumber) => {

      const randomNumber = Math.floor(Math.random()*3);
      const suji = [1,2,3];
      let naturalNumber = suji[randomNumber]; 

      if(myNumber === naturalNumber && myNumber >= 1){
        let plusPoint = myPoint + naturalNumber; 
        myPointChange(plusPoint);
      }else{
        let minusPoint = myPoint - naturalNumber;
        myPointChange(minusPoint);
      };

      changeNumber(naturalNumber);

      countDown(count=>count-1);
      
      if(count === 0){
        onRestart();
      };
    };

    const onRestart = () => {
      changeNumber('?');
      myPointChange(0);
      countDown(10);
    };

    const Button = ({button,number}) => {
      return(
        <>
          {
            count === 0
            ?
            <button onClick={onRestart}>リセット</button>
            :
            <div>
              <dl>
                <dt className="random">{number}</dt>
                <dd>
                  <button onClick={()=>selectNumber(1)}>1</button>
                  <button onClick={()=>selectNumber(2)}>2</button>
                  <button onClick={()=>selectNumber(3)}>3</button>
                </dd>
              </dl>
              <p>ボタンを押せるのはあと{count}回です</p>

            </div>
          }
        </>
      );
    };

    return(
      <div className="wrap">
        <h2>数当てゲーム</h2>
        <p>選んだ数字とランダム数字が一致すると選んだ数字をポイントに加算。<br/>はずれると選んだ数字の分、ポイントが減ります。<br/></p>
        <Button number={number} count={count}/>
        <dl>
          <dt>あなたのポイント</dt>
          <dd className="point">{myPoint}</dd>
        </dl>
      </div>
    );
  };

const root = document.getElementById('root');
ReactDOM.render(<Point />, root);

  </script>
</body>
</html>