質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.92%

JavaScript ボタンクリックでマウスストーカーの数を増やしたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 287

score 2

JavaScript触りたての入門者です。未熟な質問ですみません。

やりたいこと

色んなサイトを参考にしながら、「犬がアニメーションしながらついてくるマウスストーカー」をつくりました。
プログラミングはじめて間もないのでメモ多くてすみません...。

<div class="oiinu">
        <script type="text/javascript">

            (function (){  

                var inuspd = 110; //犬の速さ
                var fld2="INU/"; //ファイルパス

                var inuG=[];
                    inuG[0]="mati2.png";
                    inuG[1]="mati2.";
                    inuG[4]="up1.png";
                    inuG[5]="up2.png";
                    inuG[6]="down1.png";
                    inuG[7]="down2.png";
                    inuG[16]="left1.png";
                    inuG[17]="left2.png";
                    inuG[20]="upleft1.png";
                    inuG[21]="upleft2.png";
                    inuG[22]="dwleft1.png";
                    inuG[23]="dwleft2.png";
                    inuG[24]="right1.png";
                    inuG[25]="right2.png";
                    inuG[28]="upright1.png";
                    inuG[29]="upright2.png";
                    inuG[30]="dwright1.png";
                    inuG[31]="dwright2.png";
                    inuG[32]="awake.png";
                    inuG[33]="pata2.png";
                    inuG[34]="kaki1.png";
                    inuG[35]="kaki2.png";
                    inuG[36]="sleep1.png";
                    inuG[37]="sleep2.png";
                    inuG[38]="mati3.png";

                var load=new Array(); //画像先読み込み
                for (var i=0;i<=38;i++){load[i]=new Image();load[i].src=fld2+inuG[i];}
                document.write('<img src="" id="jsinu" style="position:absolute;width:110px;height:110px;">');

                var IID=0,IID2=0;
                var MX = 150, MY = 150;  //マウスカーソルの位置
                var IX = 0, IY = 0;  //犬の左上位置
                var ICYCLE = 250;  //犬の移動周期(ms)  

                //犬の移動量
                var IS = 20
                var IS2 = IS*IS;
                var IS_2 = IS >> 1;

                var IA = 1;  //アニメーションフラグ
                var BI = 0;  //一つ前に犬がしてたこと
                /*
                2進数
                Y軸    移動無し    00
                    上        10
                    下        11
                X軸    移動無し    00??
                    左        10??
                    右        11??
                */
                document.onmousemove=function (e){MX = e.pageX; MY = e.pageY;} 

    /*--------------------------------------犬アニメーション--------------------------------------------*/
            function inumove(){  
                var    DX = MX - IX;
                var    DY = MY - IY;
                var    DX2 = DX*DX;
                var    DY2 = DY*DY;
                DX2 = ( DX2 == 0 && DY2 == 0 ) ? 1 : DX2;
                var    XF = (DX < 0 ) ? -1 : 1;
                var    YF = (DY < 0 ) ? -1 : 1;

                //移動量
                if ( DX2 + DY2 < IS2 ){
                  var    IDX = DX;
                  var    IDY = DY;
                } else {
                  var    IDX = XF*Math.ceil(Math.sqrt(IS2*DX2/(DX2+DY2)));
                  var    IDY = YF*Math.ceil(Math.sqrt(IS2*DY2/(DX2+DY2)));
                }

                if ( IDX == 0 && IDY == 0 ) {     //移動が無い場合
                  clearInterval(IID);
                  inustop();
                } else {            //移動する
                  var Idirect = 0;
                  if ( IDY < 0 && IDY + IS_2 <= 0) Idirect += 2
                  else if ( IDY > 1 && IDY - IS_2 >= 0) Idirect += 3;
                  if ( IDX < 0 && IDX + IS_2 <= 0) Idirect += 8
                  else if ( IDX > 1 && IDX - IS_2 >= 0) Idirect += 12;

                  IA = ( IA == 0 ) ? 1 : 0;
                  BI = Idirect;
                  chimg((Idirect<<1)+IA);
                  IX += IDX;
                  IY += IDY; 
                      jsinu.style.left = IX - 16+"px";
                      jsinu.style.top = IY - 35+"px";
                }        // else
            }        //inumove

            function chimg(num){jsinu.src =fld2+inuG[num];}
    /*--------------------------------ストップ---------------------------*/
            function inustop(){
                IA = 0;
                chimg(0);
                OLDMX = MX;
                OLDMY = MY;
                IA = 0;
                IPC = 0;
                IID2 = setTimeout(inupata,ICYCLE*5);
                    //setTimeout(関数function, 一定時間の指定[, 引数1, 引数2, …]) 一定時間後に処理をおこなう
                mousecheck();
            }
    /*--------------------------------耳パタパタ------------------------*/
            function inupata(){
                IPC++;
                clearTimeout(IID2);
                if ( IPC <= 10 ) {
                  if ( IPC & 1 == 1 ) chimg(33)
                  else chimg(0);
                  IID2 = setTimeout(inupata,ICYCLE>>1);
                } else {
                  IKC = 0;
                  IID2 = setTimeout(inukai,ICYCLE);
                }
                mousecheck();
            }
    /*-------------------------------カイカイ---------------------------*/
            function inukai(){
                IKC++;
                clearTimeout(IID2);
                if ( IKC <= 8 ) {
                  if ( IKC & 1 == 1 ) chimg(34)
                  else chimg(35);
                  IID2 = setTimeout(inukai,ICYCLE>>1);
                } else {
                  IID2 = setTimeout(inuakubi,ICYCLE);
                }
                mousecheck();
            }
    /*---------------------------------あくび---------------------------*/
            function inuakubi(){
                clearTimeout(IID2);
                chimg(38);
                IZC = 0;
                IID2 = setTimeout(inuzzz,ICYCLE<<2);
                mousecheck();
            }
    /*--------------------------寝る------------------------------------*/
            function inuzzz(){
                IZC++;
                clearTimeout(IID2);
                if ( IZC & 1 == 1 ) chimg(36)
                else chimg(37);
                IID2 = setTimeout(inuzzz,ICYCLE<<1);
                mousecheck();
            }

    /*--------------------------起きる----------------------------------*/
            function mousecheck(){
                if ( OLDMX != MX || OLDMY != MY ) {
                  clearTimeout(IID2);
                  clearInterval(IID);
                  inustart();
                }
            }
                IID2=setTimeout("" ,0);

            function inustart(){
                 clearTimeout(IID2);
                 chimg(32);
                     IID = setInterval(inumove,inuspd);//即時関数にする
                 IID2 = setTimeout(IID,ICYCLE*6); //即時関数にする
            }
            inustart();
            }());//即時関数終了

        </script>
    </div>


この犬のマウスストーカーを、
おいで!ボタン
<button id="addbutton">おいで!</button>) を一回クリックすると犬が1匹増え、
またね!ボタン
<button id="removebutton">またね!</button> で1匹減る、という風にしたいのですが、具体的にどうしたらよいのか分からず、行き詰まっています...よい方法はないか、教えていただけませんか。

わからないこと

   <button id="addbutton">おいで!</button>

        <script>
            var addbutton = document.getElementById("addbutton");
            addbutton.addEventListener("click", function(){


この先どうしたらよいのか困っています。

環境

dream weaver2021を使っていて、ブラウザはSafariやChromeです。
どうか、よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mopemope

    2021/01/13 09:59

    コメントありがとうございます。ひどい質問をして本当に申し訳ありませんでした。大幅修正しました。
    JavaScriptに関しては参考先のコードの内容を何とか理解できているだけの状態なのでぐうの字も出ません。
    学校の課題で作っていて、作品の一部の要素として私のMacの中だけで動けば十分なので安全性は気にしていないんです...。今のところ問題なく動いているので、とりあえずいいかなと...
    本当に時間がないため、せめてここだけはというところを藁にもすがる思いで質問してしまいました。

    キャンセル

  • m.ts10806

    2021/01/13 10:06

    質問することは悪いとは思いません。
    ただ、焦って飛ばしたところで「書いたとおりにしか動かないプログラム」において
    それで進むわけがなく、1歩1歩積み重ねていくしかないということ。
    何かを参考にすることは悪いことではないです。
    それが自分のものにならなければ作ろうとしているものが(言い方悪いけど)ゴミになる、だけの話。
    課題である場合、作ったコードの意図を説明できなければ評価はされないと思いますよ。

    キャンセル

  • mopemope

    2021/01/13 23:51 編集

    ベストアンサーの方がとても分かりやすいサンプルを作ってくださったので、自力で「またね」まで実装することができました!

    キャンセル

回答 1

checkベストアンサー

+1

こんにちは。

とりあえず、「おいで」の方のサンプルを示します。
概要としては以下の通りです。

  • 即時関数は再利用できないので、名前を付けました。
  • idは一意的なので、犬画像での使用をやめました。代わりにエレメントを変数で保持しました。
  • document.write() は非推奨なので、ここでは template 要素を使いました。
  • onmousemove では複数のイベントリスナを設定できないので、document.addEventListener() に変更しました。
<div class="oiinu">

<!-- ここから追加 -->
  <template id="jsinu">
    <img src="" style="position:absolute;width:110px;height:110px;">
  </template>
<!-- ここまで -->

        <script type="text/javascript">

//            (function (){  
      function inu() {

// 略

//                document.write('<img src="" id="jsinu" style="position:absolute;width:110px;height:110px;">');
        var jsinu = document.getElementById('jsinu').content.querySelector('img').cloneNode(true);
        document.body.insertAdjacentElement('beforeend', jsinu);

// 略

//                document.onmousemove=function (e){MX = e.pageX; MY = e.pageY;} 
        document.addEventListener( 'mousemove', function (e) { MX = e.pageX; MY = e.pageY; } );


// 略

//            }());//即時関数終了
      };//即時関数終了
        </script>
    </div>

<!-- ここから追加 -->
  <button id="addbutton">おいで!</button>
  <script>
    var addbutton = document.getElementById("addbutton");
    addbutton.addEventListener("click", inu);
  </script>
<!-- ここまで -->

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/13 22:01

    うまく動かなかった理由がわかって、感動しています(涙)おかげで、「またね」の方も作ることができました...!
    悩みに悩んでこの質問を投稿した時、私の知識が無さすぎてガチめに怒られてしまいとても落ち込んでいたので、貴方様が神様にしか見えません。泣きました。まさかサンプルまでいただけるとは...。とても嬉しいです。
    貴重なお時間を回答に割いていただいて、ありがとうございました...!!!

    キャンセル

  • 2021/01/13 23:25

    どういたしまして。

    この状態から「またね」の方を自力で実装できるのであれば、すぐにJavaScriptに習熟できるのではないかと思います。
    偉そうに言いながら、私も初心者と大して変わらないアマグラマなので、お互い頑張りましょう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る