🌱

[振り返り]じゃんけんアプリを作った話

2022/09/25に公開

はじめに

この記事は私が最初にプログラミングで制作物を作った2019年のものを振り返りながらZenn用に書き直しているものです。初学者が0からなにか作ろうとするとこんな感じになるんだなーといった感じに思っていただけると嬉しいです!

元の記事はこちら

https://fanfanfan.hatenadiary.com/entry/2019/12/16/214353

実機もあります

https://fans-jankengame.netlify.app/

「じゃんけんゲーム」を作ってみよう!

プログラミングというものを触れはじめていて、ドットインストールで勉強していた時期でした。

一通りJavaScriptの課題も終わりそうになり、他の課題に進んでもいいけれども、実践JavaScriptみたいなことをやってみたいとエンジニアである夫に相談をしてみました。すると、**「きっと今の技術でもじゃんけんゲームは作れると思うから、作ってみようか!」**と提案されました。

普段何気なくやっているじゃんけんですが、これをゲーム化しようとするのはとても大変なのでは?と思ったのですが、楽しそうなのでチャレンジすることにしました。

まずは画面構成から考えてみよう!

0からプログラミングをやったことのない私でしたので、何からやっていいのか全く見当がつきませんでした。でも、画面なら作れるかな?と思い、画面の構成から考えることにしました。ipad上であーでもないこーでもない…今の技術でできることは……と考えながら1時間程度……できたプロトタイプが以下の画像になります。

image

形にしてみよう

HTML/CSSは少し勉強してたので、たぶんこれもできそう!

ということで、グーグル先生に時々質問しながら悪戦苦闘すること数時間…できた画面が以下のものになります。

image

スタートボタンを押すと以下の画面に遷移します。

image

ここまでできたところで主人に見せてみました。

「懐かしい感じがする」

イケてる画面ではないのは自認してたのですが、今の技術でできるのはこれが限界。

ひとまずこれで次の工程に移ることにします。

「じゃんけんゲーム」の実装

ここからが本当に大変でした。

プログラミング未経験、やったことがあるのは少しの写経のみ。VS Codeを開いて硬直をしてしまいました。

今までやってたのは、動画をみたりソースコードを見ながら書くと組み上がったけれども、今、私はなにもない0の状態から生み出さねばならない。ここで私は1つの決断をします。

「じゃんけん」というワードで検索しない!

おそらく、検索をすると答えが出てしまいそうな気がして、せっかく0から1を作るチャンスを自分で潰してしまう。なんだかもったいない気がして、そのようなことを1つルールに決めました。

しかし、さすがに何をどこから手を出していいのかわからない…とても困った。

そこで主人を捕まえて相談をしてみました。

するとこのようなアドバイスをもらいました。

「紙に日本語で何をすべきなのかを書き出してみましょう。」

「日本語でも言えないことはプログラムにもかけません。」

「そこまで出来たら、あとは実装するだけですよ。やってみましょう!」

ということで、またipadにかじりついて、数時間悩むことに。

悩んだ結果

以下の画像のような、こんな感じだったら動くのかな?を書き出してみました。ここまできたら実装してみるしかない!!!!がんばるぞ!!!!

image

①を実装してみる。

記念すべきうまれてはじめて0から書いたコードを皆さんにもお見せしたいと思います。

グーグル先生に聞きながら一生懸命考えてコードです。

今思い出しても、だいぶ苦労したのを覚えています。

これが私がうまれて初めて書いてみたコードです。

startBtn.addEventListener('click', () => {
document.getElementById('startArea').style.display = "none";
btnOn();
 });

たったこれだけなんですけど、1時間かかってやっと実装したものです。

②を実装してみる。

ここからは苦労の連続でした。

もうどう説明していいのかわからないくらいとても格闘しました。

どうしてもわからなくて2回だけ主人に質問してみました。

「スペルミス」と「かっこの場所違い」を指摘されましたが、それ以外は全部自分で考えて実装しました。

ちょっと長いですが、

ソースコードの全文を載せて見ようと思います。

うるせえ、GitHub見せてくれって人はこちらをどうぞ。

https://github.com/fan-tech/Fan-s-Janken-Game

初学者が悪戦苦闘しながら書くとこうなるの例です。

全文はこちら
'use strict';
{
  const startBtn = document.getElementById('startBtn');
  const npcTarget = document.getElementById('nTarget');
  const target = document.getElementById('target');

  const gooBtn = document.getElementById('gooBtn');
  const chokiBtn = document.getElementById('chokiBtn');
  const paaBtn = document.getElementById('paaBtn');

  const goo = document.getElementById('goo');
  const choki = document.getElementById('choki');
  const paa = document.getElementById('paa');

  const nowResult = document.getElementById('nowResult');
  const pResults = document.getElementById('pResults');
  const nResults = document.getElementById('nResults');

  const resetBtn = document.getElementById('resetBtn');
  const result = document.getElementById('result');
  const resultComment = document.getElementById('resultComment');

  // じゃんけんらんだむ
  let npcJanken;

  // 勝利数管理変数
  let myWin = 0;
  let npcWin = 0;

  // 「ぐー」「ちょき」「ぱー」の中から何か選ばれた時に
  // ランダムでNPCがぐーちょきぱーを選ぶ関数

  function npcChoice() {
    npcJanken = Math.floor(Math.random() * 3 + 1);
    if (npcJanken === 1) {
      target.textContent = "ぐー";
      nTarget.style.background = "#eea85f";
      nTarget.style.opacity = "1.0";
      nTarget.style.fontSize = "40px";

    } else if (npcJanken === 2) {
      target.textContent = "ちょき";
      nTarget.style.background = "#f18f65";
      nTarget.style.opacity = "1.0";
      nTarget.style.fontSize = "40px";
    } else {
      target.textContent = "ぱー";
      nTarget.style.background = "#ab785a";
      nTarget.style.opacity = "1.0";
      nTarget.style.fontSize = "40px";
    }
  };



  // 「ちょき」ボタン無効
  function chokiOff() {
    choki.textContent = '';
    chokiBtn.style.background = 'gray';
    chokiBtn.style.cursor = 'auto';
    chokiBtn.style.pointerEvents = 'none';
  };
  // 「ちょき」ボタン有効
  function chokiOn() {
    choki.textContent = 'ちょき';
    chokiBtn.style.background = '#f18f65';
    chokiBtn.style.cursor = 'pointer';
    chokiBtn.style.pointerEvents = 'auto';
  };

  // 「ぱー」ボタン無効
  function paaOff() {
    paa.textContent = '';
    paaBtn.style.background = 'gray';
    paaBtn.style.cursor = 'auto';
    paaBtn.style.pointerEvents = 'none';
  };

  // 「ぱー」ボタン有効
  function paaOn() {
    paa.textContent = 'ぱー';
    paaBtn.style.background = '#ab785a';
    paaBtn.style.cursor = 'poiter';
    paaBtn.style.pointerEvents = 'auto';
  };
  // 「ぐー」ボタン無効
  function gooOff() {
    goo.textContent = '';
    gooBtn.style.background = 'gray';
    gooBtn.style.cursor = 'auto';
    gooBtn.style.pointerEvents = 'none';
  };

  // 「ぐー」ボタン有効
  function gooOn() {
    goo.textContent = 'ぐー';
    gooBtn.style.background = '#eea85f';
    gooBtn.style.cursor = 'poiter';
    gooBtn.style.pointerEvents = 'auto';
  };

  // 「じゃんけん」ボタンに戻す。
  function jankenReset() {
    target.textContent = "じゃんけん";
    npcTarget.style.background = 'gray';
    npcTarget.style.fontSize = '25px';
    npcTarget.style.opacity = '0.7';
  };

  // 「勝ち」!
  function youWin() {
    nowResult.textContent = 'かち!';
    nowResult.style.backgroundColor = 'red';
    myWin++;
  };

  // 「負け!」
  function youLose() {
    nowResult.textContent = 'まけ!';
    nowResult.style.backgroundColor = 'blue';
    npcWin++;
  };

  // 「あいこ!」
  function aiko() {
    nowResult.textContent = 'あいこ!';
  };
  // 結果画面初期値
  function nowResultReset() {
    nowResult.textContent = "↑選んでね!↑";
    nowResult.style.backgroundColor = 'gray';
  };
  // 結果を更新する

  function nowResultUpdate() {
    pResults.textContent = myWin;
    nResults.textContent = npcWin;
  }

  //画面操作有効/無効化関数
  function btnOff() {
    chokiBtn.style.pointerEvents = 'none';
    gooBtn.style.pointerEvents = 'none';
    paaBtn.style.pointerEvents = 'none';
  };

  function btnOn() {
    chokiBtn.style.pointerEvents = 'auto';
    gooBtn.style.pointerEvents = 'auto';
    paaBtn.style.pointerEvents = 'auto';
  };

  // 終了条件分岐
  function resultCheck() {
    if (myWin === 3) {
      result.style.animationName = 'upToDown';
      result.style.animationDuration = '3s';
      result.style.display = 'block';
      resultComment.textContent = 'あなたの勝ちです!';
    } else if (npcWin === 3) {
      result.style.animationName = 'upToDown';
      result.style.animationDuration = '3s';
      result.style.display = 'block';
      resultComment.textContent = 'あなたの負けです!';
    } else {
      setTimeout(function () {

        jankenReset();
        gooOn();
        paaOn();
        chokiOn();

        nowResultReset();
      }, 4000);
    }
  };


  // ここからはじまる!
  btnOff();

  // ルール説明画面をスタートを押したら消す。
  // ゲームスタート。
  startBtn.addEventListener('click', () => {
    document.getElementById('startArea').style.display = "none";
    btnOn();
  });

  // 「ぐー」を押した時の挙動
  gooBtn.addEventListener('click', () => {
    const myGoo = 1;
    chokiOff();
    paaOff();

    gooBtn.style.cursor = 'auto';
    gooBtn.style.pointerEvents = 'none';

    npcChoice();

    if (npcJanken === 1) {
      aiko();
    } else if (npcJanken === 2) {
      youWin();
    } else {
      youLose()
    }

    nowResultUpdate();

    resultCheck();

    npcJanken = 0;
  });
  // 「ちょき」ボタン押したときの動き
  chokiBtn.addEventListener('click', () => {
    const mychoki = 2;

    gooOff();
    paaOff();

    chokiBtn.style.cursor = 'auto';
    chokiBtn.style.pointerEvents = 'none';

    npcChoice();

    if (npcJanken === 1) {
      youLose();
    } else if (npcJanken === 2) {
      aiko();
    } else {
      youWin();
    }

    nowResultUpdate();

    resultCheck()
    npcJanken = 0;

  });

  // 「ぱー」ボタンを押した時の挙動
  paaBtn.addEventListener('click', () => {
    const myPaa = 3;

    chokiOff();
    gooOff();

    paaBtn.style.cursor = 'auto';
    paaBtn.style.pointerEvents = 'none';

    npcChoice();
    if (npcJanken === 1) {
      youWin();
    } else if (npcJanken === 2) {
      youLose();
    } else {
      aiko();
    }
    nowResultUpdate();
    resultCheck();
    npcJanken = 0;
  });

  // リセットボタン押した時のアレ
  resetBtn.addEventListener('click', () => {
    result.style.display = "none";
    myWin = 0;
    npcWin = 0;
    nowResultUpdate();
    btnOn();
    gooOn();
    chokiOn();
    paaOn();
    jankenReset();
    nowResultReset();
  });

}

今ならもう少し上手にかけるのかな?と思ったり思わなかったりして懐かしい感じがします。

最後にもう1度実機を貼っておきます。

https://fans-jankengame.netlify.app

振り返ってみて

最近0から何かを書くことってあんまりなかったので、再びやってみたいなという気持ちになりました。

もう1回じゃんけんゲーム作るのもきっと面白いんだろうな!たぶん。

今度時間を見つけて作ってみようかな。

プログラミング初めて間もない人が、何かを作るとこういうプロセスでこういうモノができるというひとつの記録でした。

今ならもう少しいい感じにかけるのかな。わからないけど…

Discussion