CSS Sprite

CSS(Cascading Style Sheets) を使って画像を切り抜いて描画する手法を CSS Sprite などと呼んでいます。
HTMLでは文書構造のみを定義して、スタイルについてはスタイルシートで指定することが推奨されています。
JavaScript と CSS は別物ですが、JavaScript でゲームを作成するとき CSS の機能が良く使われます。
CSS(Cascading Style Sheets) は実行環境に左右されます。
2014/11 現在、プログラムは Windows8.1 & Internet Explorer11 の環境で確認しています。
2017/07 現在、プログラムは Windows10 & Microsoft Edge 40.15063.0.0 の環境で確認しています。
CSS の基礎は CSS Before CSS After などを参照して下さい。

スタイルシートを使うと様々な利点があるのですが、最もよく使われるものは先に説明した 自由に配置 でしょうか。
Cascading Style Sheets を使うと次のような利点があります。

CSS Sprite を使ったときの注意点です。
通常の HTML で描画したものと CSS Sprite で描画したものが重なったり隠れたりすることがあり、画面のレイアウトに注意が必要です。
画像を切り抜いて描画したとき、全体画像が配置された状態から矩形領域部分だけが描画されます。
  1. 画像を切り抜いて描画


    1. プログラムを起動すると ffx2s.jpg の画像から一部を切り抜いた画像が描画されます。
      "javascript.css" は、私が作成した Javascript ページ用の CSS で HTML と同じフォルダーに格納しています。
      "ffx2s.jpg" は親フォルダーに作成されている img/ に格納されています。
      【css_rect.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <link rel="stylesheet" href="javascript.css" type="text/css">
      <title>css rect</title>
      </head>
      
      <body>
      <img src="img/ffx2s.jpg" style="clip:rect(0px,240px,120px,0px);
        position:absolute">
      
      <img src="img/ffx2s.jpg" style="clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:200px;">
      
      <img src="img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:0px;top:300px;">
      
      <img src="img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:400px;">
      
      </body>
      </html>
      
    2. 画像全体を描画します。
      全体のサイズは 240*120 ピクセルなので、rect では「上, 右, 下, 左」の順に指定します。
      0,0 が左上の座標で、240,120 が右下の座標です。
      position:absolute なので画像は座標 0,0 に描画されます。
      <img src="img/ffx2s.jpg" style="clip:rect(0px,240px,120px,0px);
        position:absolute">
      
    3. 左の人物を切り分けて描画します。
      左の人物の座標は、左上が 0,20 で右下が 120,80 です。
      top:200px; で画像全体の下に描画します。
      <img src="img/ffx2s.jpg" style="clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:200px;">
      
    4. 右の人物を切り分けて描画します。
      右の人物の座標は、左上が 0,120 で右下が 200,80 です。
      top:300px; で左の人物の下に描画します。
      left: の値は左の人物と同じですが、元の全体画像の左端が 0px に合わせられるので、その分右に移動します。
      人物をもっと左に寄せようと思えば、left: の値をマイナスにしなければなりません。
      <img src="img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:0px;top:300px;">
      
    5. 右の人物をもっと左に寄せて描画します。
      left:-100px; で 100 ピクセル左に寄せます。
      画像の切り分けと座標の設定は 数字の画像を切り分けてカウンターを描画 を参考にして下さい。
      <img src="img/ffx2s.jpg" style="clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:400px;">
      

  2. CSS Position

    1. ffx2s.jpg を「縦に pos の位置から 100px 切り取って」描画します。
      【css_pos.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <link rel="stylesheet" href="javascript.css" type="text/css">
      <script type="text/javascript">
        function cut(pos)
        { var s1 = '(0px,' + (pos+100) + 'px,120px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;">';
          var s = '<img src="img/ffx2s.jpg" style="clip:rect' + s1 + '; position:absolute;left:-' + s2;
          document.write(s);
        }
      </script>
      
      <body>
      <script type="text/javascript">
        //cut(20);
        cut(110);
      </script>
      </body>
      </html>
      
    2. 画像を幅 100px で縦に切り取る関数です。
      rect は「上, 右, 下, 左」の順に切り取る位置を指定します。
      window.alert(s); は画像を切り取るソースコードの確認です。
        function cut(pos)
        { var s1 = '(0px,' + (pos+100) + 'px,120px,' + pos + 'px)';
          var s2 = pos + 'px;top:0px;">';
          var s = '<img src="img/ffx2s.jpg" style="clip:rect' + s1 + '; position:absolute;left:-' + s2;
      //window.alert(s);
          document.write(s);
        }
      
    3. cut(20); で左の人物を切り取ります。
      cut(110); で右の人物を切り取ります。
        //cut(20);
        cut(110);
      

  3. CSS Image Scroll


    1. CSS ファイル(jQuery など)を使わずに ffx2.jpg の画像を右端から左に向かって流します。
      【css_image.html】
      <html>
      <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <title>Image Scroll</title>
      <script type="text/javascript">
        function cut(pos, size, left)
        { var s1 = '(0px,' + (pos+size) + 'px,600px,' + pos + 'px)';
          var s2 = 'left:' + (left-pos) + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;' + s2;
          return s;
        }
      </script>
      </head>
      
      <body onLoad="setInterval('scroll()',25)">
      <img src="img/ffx2.jpg" name="img"
        style="clip:rect(0px,0px,600px,0px); position:absolute;left:0px; top:0px;">
      
      <script type="text/javascript">
        var pos = 0;
        var size = 0;
        var left = 800;
        function scroll()
        { size++;
          left--; 
          str = cut(pos, size, left);
          document.img.style = str;
          if (size>=800)
          { size = 0;
            left = 800;
          }
        }
      </script>
      
      </body>
      </html>
      
    2. "img/ffx2.jpg" の画像サイズは「幅=800, 高さ=600」です。
      cut(pos) 関数で「pos の位置から size の幅で切り出し、描画位置を left に設定」します。
        function cut(pos, size, left)
        { var s1 = '(0px,' + (pos+size) + 'px,600px,' + pos + 'px)';
          var s2 = 'left:' + (left-pos) + 'px;top:0px;';
          var s = 'clip:rect' + s1 + '; position:absolute;' + s2;
          return s;
        }
      
    3. cut(pos) 関数を使って画像を右から左にスクロールします。
      size が 800 になると元に戻ります。
        var pos = 0;
        var size = 0;
        var left = 800;
        function scroll()
        { size++;
          left--; 
          str = cut(pos, size, left);
          document.img.style = str;
          if (size>=800)
          { size = 0;
            left = 800;
          }
        }
      

  4. CSS File

    1. CSS File(sample.css) を使って画像を切り抜いて描画します。
      【css_file.html】
      <html>
      <head>
        <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
        <link rel="stylesheet" href="sample.css" type="text/css">
        <title>CSS File</title>
      </head>
      
      <body>
       <img src="img/ffx2s.jpg">
       <img src="img/ffx2s.jpg" class="sample1">
       <img src="img/ffx2s.jpg" class="sample2">
      </body>
      </html> 
      
      【sample.css】
      img.sample1
      { clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:180px;
      }
      img.sample2
      { clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:270px;
      }
      
    2. "sample.css" は css_file.html が格納されているフォルダーに格納します。
      css_file.html の文字コードは utf-8 ですが sample.css は Shift-JIS を使ってみました。
        <meta http-equiv="Content-Script-Type" content="text/javascript" charset="utf-8">
        <link rel="stylesheet" href="sample.css" type="text/css">
      
    3. 画像を切り抜いて描画する CSS Sprite です。
      左の人物では class="sample1" を設定して img.sample1 と関連付けます。
      右の人物では class="sample2" を設定して img.sample2 と関連付けます。
       <img src="img/ffx2s.jpg">
       <img src="img/ffx2s.jpg" class="sample1">
       <img src="img/ffx2s.jpg" class="sample2">
      
    4. "sample.css" の説明です。
      画像のサイズは 240*120 ピクセルです。
      rect() は「上, 右, 下, 左」の順に指定します。
      sample2 では、X座標が -100 に設定されていることに注目して下さい。
      元の画像に対して -100 を指定すると、右の人物と左の人物が並びます。
      img.sample1
      { clip:rect(0px,120px,80px,20px);
        position:absolute;left:0px;top:180px;
      }
      img.sample2
      { clip:rect(0px,200px,80px,120px);
        position:absolute;left:-100px;top:270px;
      }
      

  5. CSS Mapchip


    Mapchip を並べて美人の画像を描画します。
    1. CSS で切り分ける Map Chip(Sprite)の情報は *.css ファイルで定義します。
      Map Chip を組み合わせて画像を構成する並び情報は .js ファイル定義します。
      これらのファイルはテキスト・エディタを使って直接タイプしても良いのですが、私が提供している Map Editor を使うと簡単に作成することが出来ます。
      私のダウンロードサイトから Map Editor をダウンロードして下さい。
      1. Mapedit.exe をダブルクリックで起動して[ファイル][開く]から "JavaS.map" を開くと JavaScript テスト用の BGMAP が表示されます。
        MapChip ファイルは JavaS.gif を使っています。
      2. [ファイル][JavaData 作成] から "javas.css" で保存して下さい。
        "javas.css" と "javas.js" のファイルが作成されます。
        アップロードに備えて、ファイル名は小文字に統一して下さい。
    2. Map Editor の使い方が分かった所で "bijin16.jpg" を切り分けて描画してみましょう。
      Mapedit.exe を使って "bijin.css" と "bijin.js" を作成します。
      bijin16.jpg は 60*60 の Sprite を4行4列に並べた画像です。
      1. Mapedit.exe を起動して[ファイル][Mapchip load(L)]から bijin16.jpg をロードします。
      2. [設定(S)][サイズ]から Map Size を 4,4 に、Mapchip を 60,60 に設定します。
      3. MapChip ウインドウから16枚の画像を順に貼り付けます。
        (元の画像と同じ画面を作成します)
      4. [ファイル][JavaData 作成] から "bijin.css" で保存して下さい。
        "bijin.css" と "bijin.js" のファイルが作成されます。
    3. "bijin.css" と "bijin.js" を使うとプログラムは非常に簡単です。
      "bijin.css" と "bijin.js" を HTML と同じフォルダーに格納します。
      HTML の文字コードに shift_jis を使ってみました。
      <html>
      <head>
      <meta http-equiv="Content-Script-Type" content="text/javascript" charset="shift_jis">
      <link rel="stylesheet" href="bijin.css" type="text/css">
      </head>
      
      <body>
      <script src="bijin.js"></script>
      </body>
      </html>
      
    4. <head> から "bijin.css" をリンクします。
      <link rel="stylesheet" href="bijin.css" type="text/css">
      
    5. <body> に "bijin.js" を組み込みます。
      <script src="bijin.js"></script>
      
    6. Mapedit.exe で作成した "bijin.css" のソースコードです。
      文字コードは shift_jis ですが、そのまま使います。
      #map {
          width: 240px;
          height: 240px;
      }
      #bg {
          width: 240px;
          height: 240px;
      }
      .info {
          clear: both;
          padding: 10px 0;
      }
      .chip {
          float: left;
          width: 60px;
          height: 60px;
          background-image: url("bijin16.jpg");
      }
      .c0 {background-position: -0px -0px;}
      .c1 {background-position: -60px -0px;}
      .c2 {background-position: -120px -0px;}
      .c3 {background-position: -180px -0px;}
      .c4 {background-position: -0px -60px;}
      .c5 {background-position: -60px -60px;}
      .c6 {background-position: -120px -60px;}
      .c7 {background-position: -180px -60px;}
      .c8 {background-position: -0px -120px;}
      .c9 {background-position: -60px -120px;}
      .c10 {background-position: -120px -120px;}
      .c11 {background-position: -180px -120px;}
      .c12 {background-position: -0px -180px;}
      .c13 {background-position: -60px -180px;}
      .c14 {background-position: -120px -180px;}
      .c15 {background-position: -180px -180px;}
      
    7. Mapedit.exe で自動的に作成した "bijin.js" のソースコードです。
      Mapedit.exe で吐き出される文字コードは shift_jis なので、HTML も shift_jis に統一しています。
      var map = [
      0, 1, 2, 3, 
      4, 5, 6, 7, 
      8, 9, 10, 11, 
      12, 13, 14, 15, 
      ];
      document.write('<div class="info">Map Chip<br></div>');
      document.write('<div id="bg">');
      for(i=0; i<map.length; i++)
      { document.write('<div class="chip c', map[i], '"></div>'); }
      document.write('</div>');
      
    8. 苦労して描画したのが元の画像と同じでは、何をしているか解りませんが、この後を楽しみにして下さい。 (^_^;)

  6. CSS Animation

    16枚の Sprite を切り替えながら美人のアニメーションです。
    1. CSS Mapchip では Sprite を並べて元の bijin16.jpg と同じ画像を描画しました。
      次に16枚の Sprite を切り替えながら美人のアニメーションをします。
      全て JavaScript に任せるなら パラパラアニメーション の方が簡単かも知れません。
    2. <head> から "bijin.css" をリンクします。
      <html>
      <head>
      <meta http-equiv="Content-Script-Type" content="text/javascript" charset="shift_jis">
      <link rel="stylesheet" href="bijin.css" type="text/css">
      
    3. setInterval で 200 ミリ秒毎に chenge() 関数を呼び出します。
      div で一枚目の画像(c0)を表示します。
      <body onLoad="setInterval('chenge()',200)">
      <div class="chip c0" id="sample"></div>
      
    4. "bijin.css" を参照して Sprite の位置を pos の配列で定義しています。
      「CSS ファイルで定義された値を取得する」のように "bijin.css" から抜き出す方法もあるのですが、直接タイプする方が簡単です。
      num は現在描画中の Sprite 番号で、0 ~ 15 を繰り返します。
      id="sample" の画像に Sprite の位置(pos[num])を設定します。
      <script type="text/javascript">
      <!--
        pos = ["0 0", "-60 0", "-120 0", "-180 0",
               "0 60", "-60 -60", "-120 -60", "-180 -60",
               "0 -120", "-60 -120", "-120 -120", "-180 -120",
               "0 -180", "-60 -180", "-120 -180", "-180 -180" ];
        num = 0;    //現在の画像
        function chenge()
        { num = (num+1)%16;
          var elementReference = document.getElementById( "sample" );
          elementReference.style.backgroundPosition = pos[num];
        }
      // -->
      </script>
      

  7. CSS ファイルで定義された値を取得する

    詳細は javascriptでスタイルシートを自在に操る を参照して下さい。
    style を定義して、セレクター名, プロパティ名, 値を取得
    "bijin.css" から c0, c1 を探す
    "bijin.css" から Sprite の座標を取得
    // num 番目の background-position-x を取得
    function GetX(num)
    {   var v = document.styleSheets.item(1).cssRules.item(num).style.getPropertyValue('background-position-x');
        return (v);
    }
    // num 番目の background-position-y を取得
    function GetY(num)
    {   var v = document.styleSheets.item(1).cssRules.item(num).style.getPropertyValue('background-position-y');
        return (v);
    }
    

前田稔の超初心者のプログラム入門
超初心者のプログラム入門(JavaScript)