スマホ

前田稔のスマホ・ゲームの作り方

スマホでゲームを起動するときは スマホ・ゲーム を参照して下さい。

スマホ・ゲームの基本

HTML と JavaScript を使ってスマホ・ゲームの作り方を説明します。
  1. スマホでホームページが閲覧出来るようなので、HTPP(HyperText Transfer Protocol)を使ったスマホ対応ゲームに挑戦します。
    HTPP を使ったゲームプログラムは、専用ソフトが必要なく HTML の知識と Text Editor があれば誰でも開発することが出来ます。
    このコーナーの html, css, js の文字コードは utf-8 に統一しています。
    このコーナーはゲームを作成するための基本的な説明が主体で、本格的なゲームの作成は読者に任せます。
    掲載しているゲームは JavaScript や PHP で作成した簡単なゲームです。
    実行を確認した環境は ZenfoneGo の Android です。
  2. スマホ・ゲームのページは画面が小さいこともあり、十分な説明が出来ません。
    ゲームの作成方法や解説は 前田稔の JavaScript のページ を参照して下さい。
  3. スマホでゲームを作成するときの要点です。
    1. 画面が小さいので操作が容易なようにレイアウトします。
      文章は簡潔に最低限必要なものに留めて下さい。
    2. 画面が縮小されて操作が難しいので、スマホ専用の sumaho.css を使用します。
      sumaho.css を組み込んで "viewport" を設定して下さい。
      これで文章が短いときには、スマホの文字が大きくなります。
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0" />
      <link rel="stylesheet" href="sumaho.css" type="text/css">
      </head>
      
    3. スマホでは全角でタイプする場合も多く、全角⇒半角変換を行います。
      直接タイプ入力するよりも、選択(タップ)する方が操作性が増します。
    4. パソコンの [戻るアイコン←] はスマホの [戻るボタン] に対応しているのですが、機能に多少の違いがあるようです。
    5. 一般の画像ファイルも使えますが、Animation GIF を使うとアニメーションしながら動きまわります。
      style で画像を描画(移動)するときは <!DOCTYPE html> を指定すると動かなくなるようです。
    6. 三山くずしゲームにサウンドを組み込んだのですが Android では通信料金が発生するのでサウンドの自動再生はされないようです。
      touchstart 等のユーザによる操作のイベントの中で再生処理をする必要があります。
      具体例はページ後部の Sound Test を参照して下さい。
      hoge.addEventListener('touchstart', function()
      { var audio = new Audio ('osrstart.mp3');
        audio.play();
      });      
      
    7. HTML に組み込む sumaho.css のソースコードです。
      詳細は CSSの基本 を参照して下さい。
      @charset "utf-8";
      
      /* 全般的なスタイル */
      *  {
          margin:0; padding:0;    /*マージン・パディングをリセット*/
          color:#333333;          /*文字色*/
         } 
      body {
          background-color:#faf8e0;   /*ページ全体の背景色*/
          margin:0px 10px 10px 10px;
          -webkit-text-size-adjust: 100%!important ;
         }
      h1 {
          margin: 10px 0 10px 0;  /* 上右下左 */
          font-size: 20p;         /* 文字サイズ */
          color: #333333;         /* 文字色を#333333 */
          padding: 5px 0px;       /* 上下5ピクセル、左右0px */
         }
      h2 {
          margin: 8px 0 8px 0;    /* 上右下左 */
          font-size: 18p;         /* 文字サイズ */
          color: #333333;         /* 文字色を#333333 */
          padding: 5px 0px;       /* 上下5ピクセル、左右0px */
         }
      h3 {
          margin: 6px 0 6px 0;    /* 上右下左 */
          font-size: 16p;         /* 文字サイズ */
          color: #333333;         /* 文字色を#333333 */
          padding: 5px 0px;       /* 上下5ピクセル、左右0px */
         }
      ul { margin:0px 10px 0px 16px; }
      ol { margin:0px 10px 0px 16px; }
      li { margin:20px 10px 20px 10px; }
      p  { margin:40px 0px 40px 0px; }
      hr { height:1px; border:solid 1px #cccccc;
           margin:10px 1px 10px 0px;
         }
      /* 範囲設定 */
      div.ff
      {   text-align:left;
          background-color:#ffffff;   /*内容全体の背景色*/
      }
      div.e0
      {   text-align:left;
          background-color:#e0e0e0;
      }
      span.red
      { color:#e02020; }
      span.s1
      { font-size:20pt; }
      span.s2
      { font-size:18pt; }
      span.s3
      { font-size:16pt; }
      img.s1
      {   max-width:100%;
          height:auto;
      }
      img.s2
      {   max-width:75%;
          height:auto;
      }
      img.s3
      {   max-width:50%;
          height:auto;
      }
      a:link {/*未訪問のリンク*/
          color:0000e0;
          font-style:normal;
          text-decoration:underline;
      }
      a:visited {/*訪問後のリンク*/
          color:#934C7B;
          text-decoration:underline;
      }
      a:hover {/*マウスをのせたとき*/
          color:#f000a0;
          font-style:normal;
          text-decoration:underline;
      }
      a:active {/*クリック中*/
          text-decoration:none;
      }
      

Short Source の説明

ゲームのソースコードは、パソコンで起動して右クリックから[ソースの表示]で確認することができます。
または「F12 からデバッグタブ」を選択すると、より詳しい情報が表示されます。
  1. ゲーム説明画面
    ゲームの開始時に説明画面を表示します。
    1. document.write() でメッセージを表示します。
              document.write("・あなたと私がじゃんけんをします<br>");
                ・
                ・
                ・
      
    2. form に[開始]ボタンを設定して "guid_1.html"(自分自身)を呼び出します。
      このとき mode パラメータを渡します。
              document.write('<form action="guid_1.html" method="get">');
              document.write('<input type="hidden" name="mode" value=0>');
              document.write('<input type="submit" value="開始">');
              document.write('</form>');
      
    3. window.location.search.length はパラメータの長さで、3以下のときはパラメータが渡されなかったときです。
          if (window.location.search.length<3)
      
  2. パラメータ
    form にパラメータを設定して、渡されたパラメータを受け取ります。
    1. フォームからパラメータを入力して "guid_2.html"(自分自身)を呼び出します。
      "para_3" は隠しパラメータです。
              document.write('<form action="guid_2.html" method="get">');
              document.write('<input type="text" name="para_1" value=12>');
              document.write('<input type="text" name="para_2" value=abc>');
              document.write('<input type="hidden" name="para_3" value=XYZ>');
              document.write('<input type="submit" value="CALL">');
              document.write('</form>');
      
    2. パラメータを持って呼び出されたときは、受け取ったパラメータを window.alert() で確認します。
              param = new Array();
              var query = window.location.search.substring(1);
              var parameters = query.split('&');
              for(i=0; i<parameters.length; i++)
              {   var element = parameters[i].split('=');
                  var paramName = decodeURIComponent(element[0]);
                  var paramValue = decodeURIComponent(element[1]);
                  param[paramName] = paramValue;
              }
      
              p1 = param["para_1"];
              p2 = param["para_2"];
              p3 = param["para_3"];
              var str = "para_1:" + p1 + "  para_2:" + p2 + "  para_3:" + p3;
              window.alert(str);
      
    3. window.location.search.length はパラメータの長さで、3以下のときはパラメータが渡されなかったときです。
      適当な数字(文字)をタイプして[CALL]をクリックしてください。
      スマホでは全角でタイプする場合も多く、全角⇒半角変換を行った方が良いかも知れません。
      詳細は 全角 ⇔ 半角 を参照して下さい。
  3. 乱数でボタンを並べる
    ボタンの数を乱数で決めて form に並べます。
    1. ボタンを選択して "guid_3.html"(自分自身)を呼び出します。
              num = Math.floor(Math.random()*5)+3;
              document.write('<form action="guid_3.html" method="get">');
              for(i=1; i<num; i++)
              {   document.write('<input type=radio name="val" value=',i,'>',i,' 個取る<br>');  }
              document.write('<input type="submit" value="CALL">');
              document.write('</form>');
      
    2. 選択されたボタンを window.alert() で確認します。
              param = new Array();
              var query = window.location.search.substring(1);
              var parameters = query.split('&');
              for(i=0; i<parameters.length; i++)
              {   var element = parameters[i].split('=');
                  var paramName = decodeURIComponent(element[0]);
                  var paramValue = decodeURIComponent(element[1]);
                  param[paramName] = paramValue;
              }
      
              p1 = param["val"];
              var str = "クリックされたボタン : " + p1;
              window.alert(str);
      
    3. window.location.search.length はパラメータの長さで、3以下のときはパラメータが渡されなかったときです。
  4. 画像を並べる
    石の画像を並べて、マウスのクリックで石を取り除きます。
    1. 石の画像を num 個並べる関数を head の中で定義します。
      最初に呼ばれたときは num には 10 が設定されています。
      石をクリックすると MouseClick() 関数がクリックされた番号で呼び出されます。
      クリックで呼び出されたときは、"石を取り除きました" を表示して残りの石を並べます。
        MouseClick(10);
          ・・・
      function MouseClick(num)
      {   if (num<10) document.write("<h2>石を取り除きました</h2>");
          for(i=0; i<num; i++)
              document.write("<img src='../img/jewel.gif'","onClick=MouseClick(",i,")>");
      }
      
    2. 今回は連続して取り除くことは出来ません。
      連続して取り除くプログラムは head や MouseClick() 関数も含めた HTML 自体を再帰的に呼び出します。
  5. クリックのテスト
    クリック(タップ)された座標をオセロ盤の座標に変換して確認します。
    1. onmousedown でクリック(タップ)を検出して、座標を表示します。
        document.onmousedown =
          function(e)
          { if (!e)  e= window.event;
            xp= Math.floor((e.clientX-20)/38);
            yp= Math.floor((e.clientY-10)/38);
            window.alert("XP:" + xp + "  YP:" + yp);
          }
      
    2. body では "ban.gif" を描画するだけです。
      <img src="ban.gif">
      
  6. タップ座標に画像を移動
    マウスがクリック(タップ)された座標に画像を移動します。
    1. img タグの style で座標を設定して anime1.gif を描画します。
      style で画像を描画(移動)するときは <!DOCTYPE html> を指定すると効かなくなるようです。
      また style で座標を設定すると、HTML のテキストと重なって描画されます。
      この画像には "Enemy" の名前を付けています。
        <img src="anime1.gif" name="Enemy"
          style="position:absolute;left:0px;top:70px;">
      
    2. マウスのクリック(タップ)を検出して、"Enemy" の座標を移動します。
        document.onmousedown =
          function(e)
          { if (!e)  e= window.event;
            xp= e.clientX;
            yp= e.clientY;
            document.Enemy.style.left= xp;
            document.Enemy.style.top= yp;
          }
      
  7. タップで画像を切り替える
    マウスのクリック(タップ)で画像を切り替えます。
    1. アニメーション画像を切り替える手法は [歩く/走る/ジャンプ] や [イベント] が発生した場合などに使います。
      最初は "anime1.gif" を描画します。
      この画像には "anime" の名前を付けています。
      <img src="anime1.gif" name="anime"><br>
      
    2. window.onmousedown = mousedown; で、マウスがクリックされたとき mousedown() 関数を呼び出します。
      num は現在描画中の画像番号で、クリックする毎に 0 と 1 を切り替えます。
      document.anime.src= "anime" + (num+1) + ".gif"; で、"anime" の画像を切り替えます。
        num = 0;    //現在の画像
        window.onmousedown = mousedown;
        function mousedown()
        {   num = (num+1)%2;
            document.anime.src= "anime" + (num+1) + ".gif";
        }
      
  8. 画像の往復運動
    アニメーションしながら、画像が往復運動します。
    1. body の onLoad で setInterval を設定して 25 ミリ秒ごとに moveImage() を呼び出します。
      img タグの style で座標を設定して anime1.gif を描画します。
      この画像には "Enemy" の名前を付けています。
      <body onLoad="setInterval('moveImage()',25)">
      <h2>画像の往復運動</h2>
        <img src="anime1.gif" name="Enemy"
          style="position:absolute;left:0px;top:70px;">
      
    2. moveImage() 関数です。
      document.Enemy は name="Enemy" が設定されたリソースを指します。
      x は画像を描画するX座標で、Enemy.style.left= x; で座標を変えながら移動します。
      v は移動速度で0~120の間を往復運動します。
        x=0;
        v=2;
        function moveImage()
        {
          x+=v;
          if((x>120)||(x<0))  v= -v; 
          document.Enemy.style.left= x;
        }
      
  9. Start/Stop ボタン
    dog0.gif ~ dog4.gif の5枚の画像を切り替えてアニメーションをします。
    アニメーションの Start/Stop ボタンを設定します。
    1. starts() 関数から setInterval を設定して upDate() を呼び出します。
      123 は upDate() を呼びだす時間間隔(ミリ秒)です。
      id = 0;      //Interval のID
      ic = 0;      //ic= 表示する画像番号
      
      //Start ボタンがクリックされたとき
      function starts()
      {   clearInterval(id);
          id=window.setInterval("upDate()",123);
      }
      
    2. Stop ボタンで、Interval をクリアしてアニメーションを停止します。
      //Stop ボタンがクリックされたとき
      function stop()
      {   clearInterval(id); 
          Disp();
      }
      
    3. upDate() 関数で dog0.gif ~ dog4.gif の画像を切り替えます。
      Disp() 関数を呼び出して ic 番目の画像を描画します。
      //ic= 表示する画像番号
      function upDate()
      {   ic = ic+1;
          if (ic > 4) ic=0;
          Disp();
      }
      
    4. ic 番目の画像を描画します。
      このページで使う画像は1枚だけなので、images[0].src は犬の画像です。
      //ic 番目の画像を描画
      function Disp()
      {   document.images[0].src="../img/dog"+ic+".gif";  }
      </script>
      
    5. Start/Stop ボタンを設定して、クリックを検出します。
      今回は画像に名前を設定しないで、images[0]. で参照してみました。
      <table border="0">
          <tr><td><img src="../img/dog0.gif"></td></tr>
      </table>
      <form name="Ctrl">
          <input type="button" value="START" onClick="starts()">
          <input type="button" value="STOP" onClick="stop()">
      </form>
      
  10. 弾丸を発射
    プログラムを起動すると弾丸が左端から右側に向けて発射されます。
    1. body から setInterval() で 25 ミリ秒ごとに move() 関数を呼び出します。
      img タグで "tama.gif" を style を設定して描画します。
      画像には "tama" の名前を付けています。
      <body onLoad="setInterval('move()',25)">
      <img src="tama.gif" name="tama" style="position:absolute;left:0px;top:50px;">
      
    2. move() 関数で弾丸を移動します。
      X座標を 4 アップして tama.style.left に設定します。
      X座標が 600 を超えると弾丸は止まります。
        x= 0;
        function move()
        { x+= 4;
          if (x<600)  document.tama.style.left= x;
        }
      
  11. 弾丸を広がりながら発射
    shat.js を組み込んで、3発の弾丸を広がりながら発射します。
    1. 弾丸を発射するソースコードを定義した shat.js を head 内に組み込みます。
      func() は3発の弾丸を移動する関数です。
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0" />
      <link rel="stylesheet" href="sumaho.css" type="text/css">
      <script src="shot.js" type="text/javascript"></script>
      <script type="text/javascript">
        function func()
        { cls0.move();
          cls1.move();
          cls2.move();
        }
      </script>
      </head>
      
    2. shat.js のソースコードです。
      id は弾丸の id で、x, y が発射する座標で、xd, yd が移動量です。
      this.move で宣言されている関数は shot クラスの内部関数です。
      座標がウインドウの外に出たら描画を停止します。
      600, 400 は画面サイズに合わせて調整して下さい。
        function shot(id, x, y, xd, yd)
        { this.id = id;
          this.x = x;
          this.y = y;
          this.xd = xd;
          this.yd = yd;
          this.flg = true;
      
          this.move = function()
          { if (this.flg)
            { this.x += this.xd;
              this.y += this.yd;
              if (this.x<0 || this.x>600 || this.y<0 || this.y>400)   this.flg = false;
            }
            if (this.flg)
            { document.getElementById(this.id).style.visibility= "visible";
              document.getElementById(this.id).style.left= this.x;
              document.getElementById(this.id).style.top= this.y;
            }
            else  document.getElementById(this.id).style.visibility= "hidden";
          }  
        } 
      
    3. body から setInterval() で 25 ミリ秒ごとに func() 関数を呼び出します。
      cls0, cls1, cls2 の弾丸を生成します。
      <body onLoad="setInterval('func()',25)">
      <script type="text/javascript">
        var cls0 = new shot("tama0", 600, 70, -4, 0);
        var cls1 = new shot("tama1", 600, 70, -4, 1);
        var cls2 = new shot("tama2", 600, 70, -4, 2);
      </script>
      
    4. 3発の弾丸の画像を名前(id)を設定して描画します。
      <img src="tama.gif" id="tama0" style="position:absolute;left:600px;top:70px;">
      <img src="tama.gif" id="tama1" style="position:absolute;left:600px;top:70px;">
      <img src="tama.gif" id="tama2" style="position:absolute;left:600px;top:70px;">
      
  12. 円状に発射
    プログラムを起動すると10発の弾丸が同心円状に発射されます。
    1. shat.js は便利なクラスで、発射座標と方向を指定すれば簡単に弾丸を発射することが出来ます。
      今回は10発の弾丸を同心円状に発射します。
      弾丸を広がりながら発射 を参照して shat.js を head 内に組み込んで下さい。
      func() 関数で弾丸を移動します。
      <script src="shot.js" type="text/javascript"></script>
      <script type="text/javascript">
        function func()
        { for(i=0; i<10; i++) cls[i].move();
        }
      </script>
      </head>
      
    2. body から setInterval() で 25 ミリ秒ごとに func() 関数を呼び出します。
      <body onLoad="setInterval('func()',25)">
      
    3. 画面の中央から、10発の弾丸の移動方向を設定して登録します。
        var cls = new Array();
        for(i=0; i<10; i++)
        { var w = "tama" + i;
          var x = 3 * Math.cos((i*36)/180*Math.PI);
          var y = 3 * Math.sin((i*36)/180*Math.PI);
          cls[i] = new shot(w, 300, 200, x, y);
        }
      
    4. 最初に10発の弾丸に名前(id)を設定して描画します。
      画像の名前(id)は "tama0" ~ "tama9" になります。
        for(i=0; i<10; i++)
        { var w = "tama" + i;
          document.write('<img src="tama.gif" id="', w, '" style="position:absolute;left:300px;top:200px;">');
        }
      
  13. Saund Test
    サウンド(mp3)のテストです。
    1. サウンドを演奏する saisei() 関数です。
      <script type="text/javascript">
      function saisei(file)
      { var audio = new Audio(file);
        audio.play();
      }; 
      </script>
      
    2. ボタンのクリックで saisei() 関数を呼び出します。
      <input type="button" value="開始" onClick="saisei('start.mp3')"><br><br>
      <input type="button" value="勝ち" onClick="saisei('win.mp3')"><br><br>
      <input type="button" value="負け" onClick="saisei('lose.mp3')"><br><br>
      
    3. サウンドの再生は通信料金が発生するので、ユーザによるイベント操作の中で再生する必要があるようです。
  14. CSS Sprite のプログラムは、スマホでは動かないようです。

スマホ・ゲームの説明

  1. 平方根の計算
    平方根を計算します
    説明は 平方根の計算 を参照して下さい。
  2. HI or LOW
    7より大きい/小さいを当てるゲームです
    説明は ハイ・アンド・ローゲーム を参照して下さい。
  3. じゃんけんゲーム
    何で勝つかで得点が変わります
    後出し無しで、正々堂々と闘います
    説明は じゃんけんゲームβ版 を参照して下さい。
  4. スロットマシン
    賭点を設定してスロットマシンを回します
    説明は スロットマシン を参照して下さい。
  5. 石取りゲーム
    山の石を交互に取り除くゲームです
    説明は 石取ゲームβ版 を参照して下さい。
  6. 三山くずしゲーム
    3個の山から交互に石を取り除くゲームです
    説明は 三山ゲームβ版 を参照して下さい。
  7. オセロゲーム
    強くなると嫌われそうなので、このぐらいにしておきます。
    説明は オセロ・ゲーム を参照して下さい。

CSS Sprite

CSS Sprite のプログラムは、スマホでは動かないようです。
  1. CSS 自動アニメーション
    CSS を使って自動でアニメーションします。
  2. CSS Sprite
    CSS で Sprite を切り分けて描画します。
  3. CSS Animation
    Sprite を切り分けて Animation します。

ゲームのプレイは スマホ・ゲーム を参照して下さい。
前田稔(Maeda Minoru)の超初心者のプログラム入門