Quantcast
Channel: monoe's blog
Viewing all 51 articles
Browse latest View live

HTML5 を使ったシンプルな 2 D ゲームの作り方 (矢印キーとタッチによる制御の実装)

$
0
0

去年末に出演した schoo (スクー) さんの授業で使用したサンプルアプリをもとにした、HTML5 を使ったシンプルな 2 D ゲームの作り方を紹介しています。

どんなゲームを作るのかは 1 回目の記事の中に実際に動作するゲームが埋め込んであるのでぜひ遊んでみてください。なお���開発に必要な画像データは 2 回目の記事からダウンロードできまるので、実際にゲーム開発を体験したい方はそちらから入手してください。


  1. HTML5 を使ったシンプルな 2 D ゲームの作り方(序)
  2. HTML5 を使ったシンプルな 2 D ゲームの作り方(準備編)
  3. HTML5 を使ったシンプルな 2 D ゲームの作り方 (画像のロード)
  4. HTML5 を使ったシンプルな 2 D ゲームの作り方 (アニメーションの実装)

前回の記事では Canvas に表示した画像にアニメーションを実装しましたが、今回はこれをキーボードの矢印キー (カーソルキー) と、画面のタッチでコントロールできるようにしたいと思います。具体的には雪だるまの画像を左右に動かす機能です。

なお、タッチによるコントロールは、モニターがタッチ対応のものでないと使用できませんのでご注意ください。

 

デバイスからのイベントの取得

キーボードや、タッチ対応の画面などからの入力を取得するには、それを受け取るためのイベントハンドラーを実装する必要があります。

キーボードのキーについてのアクションは kdown、keyup 等のイベントで、タッチは touchstart、touchend 等のイベントで取得することができるので、これらを使用してイベントハンドラーを定義していきます。

 

キーイベントの取得と判断

キーボードのキーを押下した際のアクションは、keydown イベントで取得することができますが、押されたキーを判断し、必要なキーのアクションを必要な処理に割り当てる必要があります。押されたキーを示すキーコードは、以下のようにイベントハンドラに渡された引数の which プロパティで取得できるので、これを使用して押されたキーの種別を判断することができます。

document.addEventListener("keydown", function (evnt) {
    var keyCode = evnt.which;
};

今回のゲームで雪だるまを動かすのに使用するキーは、カーソルキーの左と右です。キーコードは数字ですが、数字そのままだとコードを読んだ時にわかりづらいので、以下のようにキーの名前をつけた変数を定義し、値をセットしておきます。この変数は、名前のついているすべての関数の外側/即時実行関数の直下に記述してください。

(function () {
     //矢印キーのコード
     var LEFT_KEY_CODE = 37;
     var RIGHT_KEY_CODE = 39;
     //雪だるまの横位置に加算する変数 
     var key_value = 0;

余談ですが、Internet Explorer 11 では定数を定義するための const が使用できるようになっていますが、書き換えを防止するということ以外では JavaScript ではあまりメリットがない気がするのでそのまま var を使用しています。

キー押下時のイベントを取得する keydown イベントのハンドラーを記述します。イベントハンドラーの中では、左矢印ボタンが押されたら、雪だるま画像 の横位置に加算する値を –3 に (左に移動)、右矢印キーを押されたら 3 を (右に移動) に設定します。

//キーイベントの取得 (キーダウン)
document.addEventListener("keydown", function (evnt) {
    if (evnt.which == LEFT_KEY_CODE) {
        key_value = -3;
    } else if (evnt.which == RIGHT_KEY_CODE) { 
         key_value = 3;
    }
});

//雪だるまが進みっぱなしにならないように、
//キーが上がったら 0 に
document.addEventListener("keyup", function () {
       key_value = 0;
});


雪だるま の横位置を加算しすぎて Canvas からはみ出さないように、横位置 (X) の最大値を設定します。移動できる X の最大値は画像が Canvas の右端についた状態となるので、以下のような計算式で求めることができます。

X = Canvas の幅 - 雪だるまの画像の幅

分かりやすくするためと、再利用を考えて関数を定義します。関数名は getRightLimitPosition とします。

//Player (雪だるまを動かせる右の限界位置)
function getRightLimitPosition(containerWidth, itemWidth) {
        return containerWidth - itemWidth;
}

この getRightLimitPosition 関数を、loadAssets 関数中の、雪だるまの画像をロードしている箇所に追記し、img_snow_man の limit_rightPosition プロパティに返り値をセットするようにします。limit_rightPosition プロパティは、あらかじめ定義はされていませんか、JavaScript では値がセットされたと同時にプロパティが作られるので問題ありません。

//雪だるま画像のロード
img_snow_man = new Image();
img_snow_man.src = '/img/snow_man.png';
img_snow_man.onload = function () {
    img_snow_man._x = getCenterPostion(canvas.clientWidth, img_snow_man.width);
    img_snow_man._y = canvas.clientHeight - img_snow_man.height;
          //右側に動かせる最大値を設定
    img_snow_man.limit_rightPosition = getRightLimitPosition(canvas.clientWidth,
                                                                                                              img_snow_man.width);
    ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);
};

アニメーション フレーム内の処理を行っている renderFrame 関数に、雪だるま画像の横位置を書き換えるコードを追記します。

function renderFrame() {
    //img_snow の y 値(縦位置) が canvas からはみ出たら先頭に戻す
    if (img_snow._y > canvas.clientHeight) { img_snow._y = 0 };
    //canvas をクリア
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    //img_snow の y 値を増分
    img_snow._y += 2;
         //img_snow_man の x 値が動作範囲内かどうか
    if ((img_snow_man._x < img_snow_man.limit_rightPosition && key_value > 0)
      || (img_snow_man._x >= 3 && key_value < 0)) {
           //img_snow_man の x 値を増分
           img_snow_man._x += key_value;
     }   
   //画像を描画
   ctx.drawImage(img_snow, img_snow._x, img_snow._y);
   ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);
   //ループを開始
    requestId = window.requestAnimationFrame(renderFrame);
}

default.html を選択し、キーボードの [F5] キーを押下してページを実行します。画像が表示されたら Canvas 部分をクリックし、左右のカーソルキーを押下してみてください。キーに合わせて雪だるまの画像が左右に動作します。


タッチイベントの取得と判断

タッチデバイスからのイベントは touchstart、touchend イベントで取得することができます。雪だるまの動きをどう左右に割り振るかは、Canvas の左側をタッチしたら左へ、右側をタッチしたら右へ動くようにします。

//Canvas へのタッチイベント設定
canvas.addEventListener("touchstart", function (evnt) {
    if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
            key_value = -3;
    } else {
            key_value = 3;
    }
});

//雪だるまが進みっぱなしにならないように、
//タッチが完了したら 0 に 
canvas.addEventListener("touchend", function (evnt) {
    key_value = 0;
});

なお、このコードが正常に動作するには、変数 canvas に HTML エレメントの Canvas のインスタンスが格納されている必要があるので、loadAssets 関数の実行が完了している必要があります。よって、DOMContentLoaded イベント ハンドラー内の loadAssets 関数の呼び出し箇所に上記のコードを記述すればいいのですが、コードが煩雑になるので、新たに setHandlers という関数を作成してその中に前述のキーイベントのハンドラーもまとめ、DOMContentLoaded イベントハンドラーからは、その setHandlers 関数を呼ぶようにします。具体的には、以下のコードとなります。

//DOM のロードが完了したら実行 
document.addEventListener("DOMContentLoaded", function () {
      loadAssets();
      setHandlers(); 
});

//雪だるまを動かすためのイベントハンドラーをまとめた関数
function setHandlers() {
    //キーイベントの取得 (キーダウン)
    document.addEventListener("keydown", function (evnt) {
        if (evnt.which == LEFT_KEY_CODE) {
            key_value = -3;
        } else if (evnt.which == RIGHT_KEY_CODE) {
            key_value = 3; 
        } 
    });

    //雪だるまが進みっぱなしにならないように、 キーが上がったら 0 に 
    document.addEventListener("keyup", function () {
       key_value = 0;
    });

    //Canvas へのタッチイベント設定
    canvas.addEventListener("touchstart", function (evnt) {
       if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
            key_value = -3;
       } else {
            key_value = 3;
       }
    }); 

    //雪だるまが進みっぱなしにならないように、 タッチが完了したら 0 に 
   canvas.addEventListener("touchend", function (evnt) {
       key_value = 0;
    });
}


ここまでの main.js 全体のコードは以下のとおりです。

(function () {
    //矢印キーのコード
    var LEFT_KEY_CODE = 37;
    var RIGHT_KEY_CODE = 39;
    var key_value = 0;

    //全体で使用する変数
    var canvas = null;
    var ctx = null;
    var img_snow = null;
    var img_snow_man = null;

    //DOM のロードが完了したら実行
    document.addEventListener("DOMContentLoaded", function () {
        loadAssets();
        setHandlers();
    });

    //雪だるまを動かすためのイベントハンドラーをまとめた関数
   function setHandlers() {
        //キーイベントの取得 (キーダウン)
        document.addEventListener("keydown", function (evnt) {
            if (evnt.which == LEFT_KEY_CODE) {
                key_value = -3;
            } else if (evnt.which == RIGHT_KEY_CODE) {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 キーが上がったら 0 に
        document.addEventListener("keyup", function () {
            key_value = 0;
        });

        //Canvas へのタッチイベント設定
        canvas.addEventListener("touchstart", function (evnt) {
            if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
                key_value = -3;
            } else {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 タッチが完了したら 0 に
        canvas.addEventListener("touchend", function (evnt) {
            key_value = 0;
        });
    }

    function loadAssets() {
        //HTML ファイル上の canvas エレメントのインスタンスを取得 
        canvas = document.getElementById('bg');
        //アニメーションの開始
        canvas.addEventListener("click", renderFrame);
        //2D コンテキストを取得
        ctx = canvas.getContext('2d');
        //image オブジェクトのインスタンスを生成
        img_snow = new Image();
        //image オブジェクトに画像をロード
        img_snow.src = '/img/snow.png';

        /*画像読み込み完了のイベントハンドラーに Canvas に
           画像を表示するメソッドを記述 */
        img_snow.onload = function () {
            img_snow._x = getCenterPostion(canvas.clientWidth, img_snow.width);
            img_snow._y = 0;
            //canvas 上で image を描画
            ctx.drawImage(img_snow, img_snow._x, img_snow._y);
        };
        //雪だるま画像のロード
        img_snow_man = new Image();
        img_snow_man.src = '/img/snow_man.png';
        img_snow_man.onload = function () {
            img_snow_man._x = getCenterPostion(canvas.clientWidth, img_snow_man.width);
            img_snow_man._y = canvas.clientHeight - img_snow_man.height;
            img_snow_man.limit_rightPosition = getRightLimitPosition(canvas.clientWidth,
                                                                                                                       img_snow_man.width);
            ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);
        };
    };

    function renderFrame() {
        //img_snow の y 値(縦位置) が canvas からはみ出たら先頭に戻す
        if (img_snow._y > canvas.clientHeight) { img_snow._y = 0 };
        //canvas をクリア
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //img_snow の y 値を増分
        img_snow._y += 2;
        //img_snow_man の x 値が動作範囲内かどうか
        if ((img_snow_man._x < img_snow_man.limit_rightPosition && key_value > 0)
         || (img_snow_man._x >= 3 && key_value < 0)) {
            //img_snow_man の x 値を増分
            img_snow_man._x += key_value;
        }
        //画像を描画
        ctx.drawImage(img_snow, img_snow._x, img_snow._y);
        ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);
        //ループを開始
        requestId = window.requestAnimationFrame(renderFrame);
    }

    //中央に配置する画像の X 座標を求める関数
    function getCenterPostion(containerWidth, itemWidth) {
        return (containerWidth / 2) - (itemWidth / 2);
    };

    //Player (雪だるまを動かせる右の限界位置)
    function getRightLimitPosition(containerWidth, itemWidth) {
        return containerWidth - itemWidth;
    }
})();


default.html を選択し、キーボードの [F5] キーを押下してページを実行し、画像が表示されたら Canvas 部分をクリックしてください。

以下は、実際に動作するサンプルです。ゲーム画面をクリックしてアニメーションが動き出したら、カーソルキー、タッチで 雪だるま が左右に動作するのを確認してください。


まとめ

今回は、ゲーム中の雪だるまの画像をキーボードの矢印キー (カーソルキー) と、画面のタッチでコントロールできるようにしました。

次はゲームにおいて重要な要素である衝突判定を実装します。

⇒「HTML5 を使ったシンプルな 2 D ゲームの作り方 (当たり判定の実装)」へ

Web Statistics

HTML5 を使ったシンプルな 2 D ゲームの作り方 (当たり判定の実装)

$
0
0

去年末に出演した schoo (スクー) さんの授業で使用したサンプルアプリをもとにした、HTML5 を使ったシンプルな 2 D ゲームの作り方を紹介しています。

どんなゲームを作るのかは 1 回目の記事の中に実際に動作するゲームが埋め込んであるのでぜひ遊んでみてください。なお、開発に必要な画像データは 2 回目の記事からダウンロードできますので、実際にゲーム開発を体験したい方はそちらから入手してください。


  1. HTML5 を使ったシンプルな 2 D ゲームの作り方(序)
  2. HTML5 を使ったシンプルな 2 D ゲームの作り方(準備編)
  3. HTML5 を使ったシンプルな 2 D ゲームの作り方 (画像のロード)
  4. HTML5 を使ったシンプルな 2 D ゲームの作り方 (アニメーションの実装)
  5. HTML5 を使ったシンプルな 2 D ゲームの作り方 (矢印キーとタッチによる制御の実装)

前回の記事では雪だるまをキーボードの矢印 (カーソル) キーで操作する機能を実装しました。

今回の記事では、降ってきた雪の結晶と雪だるまが当たったかどうか判断する処理を実装します。


当たり判定

「当たり判定」とは、文字どおりゲームにおいてキャラクター同士が衝突したかどうかを判断するもので、シューティングゲームのような、ユーザーがゲーム内のキャラクターを操作するタイプのゲームでは不可欠なものです。

当たり判定の方法はいろいろあり、形状が複雑なものに対し厳密に行おうとすると非常に大変です。また、実際のそこまでは必要がないということもあります。例えば、以下の図のアミカケの部分は、当たり判定をする単純な 3 つのパターンを示してしますが、X と Y の値で判断できる 1 や 2 が簡単です。

image

今回は最も単純な、1 のタイプで、2 つの画像が重なったら当たりと判定する方法で実装します。

image

この判断は以下の式で行うことができます。

当たり/はずれ = ((targetA.x <= targetB.x and targetA.width + targetA.x >= targetB.x)
                or  (targetA.x >= targetB.x and targetB.x + targetB.width >= targetA.x) )
                and ( (targetA.y <= targetB.y and targetA.height + targetA.y >= targetB.y)
                or (targetA.y >= targetB.y and targetB.y + targetB.height >= targetA.y))

この式を JavaScript の if 文の書式に直し、ヒットと判断されたら画面に文字を出力する関数を定義します。名前は isHit としましょう。

//当たり判定
    function isHit(targetA, targetB) {
        if ((targetA._x <= targetB._x && targetA.width + targetA._x >= targetB._x)
                || (targetA._x >= targetB._x && targetB._x + targetB.width >= targetA._x)) {
                   if ((targetA._y <= targetB._y && targetA.height + targetA._y >= targetB._y)
                       || (targetA._y >= targetB._y && targetB._y + targetB.height >= targetA._y)) {
                          ctx.font = "bold 20px 'MS ゴシック'";
                          ctx.fillStyle = "red";
                          ctx.fillText("ヒットしました", getCenterPostion(canvas.clientWidth, 140), 160);
            }
        }
    }

この関数を、アニメーションのフレームを処理している renderFrame 関数内の window.requestAnimationFrame メソッドを呼び出しの手前に記述します。

   //当たり判定
  isHit(img_snow, img_snow_man);
    //ループを開始
    requestId = window.requestAnimationFrame(renderFrame);
}

ここまでの main.js 全体のコードは以下のとおりです。

(function () {
    //矢印キーのコード
    var LEFT_KEY_CODE = 37;
    var RIGHT_KEY_CODE = 39;
    var key_value = 0;

    //全体で使用する変数
    var canvas = null;
    var ctx = null;
    var img_snow = null;
    var img_snow_man = null;

    //DOM のロードが完了したら実行
    document.addEventListener("DOMContentLoaded", function () {
        loadAssets();
        setHandlers();
    });

    function setHandlers() {
        //キーイベントの取得 (キーダウン)
        document.addEventListener("keydown", function (evnt) {
            if (evnt.which == LEFT_KEY_CODE) {
                key_value = -3;
            } else if (evnt.which == RIGHT_KEY_CODE) {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 キーが上がったら 0 に
        document.addEventListener("keyup", function () {
            key_value = 0;
        });

        //Canvas へのタッチイベント設定
        canvas.addEventListener("touchstart", function (evnt) {
            if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
                key_value = -3;
            } else {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 タッチが完了したら 0 に
        canvas.addEventListener("touchend", function (evnt) {
            key_value = 0;
        });
    }

    function loadAssets() {
        //HTML ファイル上の canvas エレメントのインスタンスを取得 
        canvas = document.getElementById('bg');
        //アニメーションの開始
        canvas.addEventListener("click", renderFrame);
        //2D コンテキストを取得
        ctx = canvas.getContext('2d');
        //image オブジェクトのインスタンスを生成
        img_snow = new Image();
        //image オブジェクトに画像をロード
        img_snow.src = '/img/snow.png';

        /*画像読み込み完了のイベントハンドラーに Canvas に
           画像を表示するメソッドを記述 */
        img_snow.onload = function () {
            img_snow._x = getCenterPostion(canvas.clientWidth, img_snow.width);
            img_snow._y = 0;
            //canvas 上で image を描画
            ctx.drawImage(img_snow, img_snow._x, img_snow._y);
        };
        //雪だるま画像のロード
        img_snow_man = new Image();
        img_snow_man.src = '/img/snow_man.png';
        img_snow_man.onload = function () {
            img_snow_man._x = getCenterPostion(canvas.clientWidth, img_snow_man.width);
            img_snow_man._y = canvas.clientHeight - img_snow_man.height;
            img_snow_man.limit_rightPosition = getRightLimitPosition(canvas.clientWidth,
                                                                                                                     img_snow_man.width);
            ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);
        };
    };

    function renderFrame() {
        //img_snow の y 値(縦位置) が canvas からはみ出たら先頭に戻す
        if (img_snow._y > canvas.clientHeight) { img_snow._y = 0 };
        //canvas をクリア
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //img_snow の y 値を増分
        img_snow._y += 2;
        //img_snow_man の x 値が動作範囲内かどうか
        if ((img_snow_man._x < img_snow_man.limit_rightPosition && key_value > 0)
         || (img_snow_man._x >= 3 && key_value < 0)) {
            //img_snow_man の x 値を増分
            img_snow_man._x += key_value;
        }
        //画像を描画
        ctx.drawImage(img_snow, img_snow._x, img_snow._y);
        ctx.drawImage(img_snow_man, img_snow_man._x, img_snow_man._y);

        //当たり判定
        isHit(img_snow, img_snow_man);
        //ループを開始
        window.requestAnimationFrame(renderFrame);
    }

    //中央に配置する画像の X 座標を求める関数
    function getCenterPostion(containerWidth, itemWidth) {
        return (containerWidth / 2) - (itemWidth / 2);
    };

    //Player (雪だるまを動かせる右の限界位置)
    function getRightLimitPosition(containerWidth, itemWidth) {
        return containerWidth - itemWidth;
    }

    //当たり判定
    function isHit(targetA, targetB) {
        if ((targetA._x <= targetB._x && targetA.width + targetA._x >= targetB._x)
                || (targetA._x >= targetB._x && targetB._x + targetB.width >= targetA._x)) {

            if ((targetA._y <= targetB._y && targetA.height + targetA._y >= targetB._y)
                || (targetA._y >= targetB._y && targetB._y + targetB.height >= targetA._y)) {
                ctx.font = "bold 20px 'MS ゴシック'";
                ctx.fillStyle = "red";
                ctx.fillText("ヒットしました", getCenterPostion(canvas.clientWidth, 140), 160);
            }
        }
    }
})();


default.html を選択し、キーボードの [F5] キーを押下してページを実行し、画像が表示されたら Canvas 部分をクリックしてください。

アニメーションのが開始されたらカーソルキー(矢印キー) で雪だるまを動かし、雪だるまが雪の結晶とぶつかったときだけ画面に文字が表示されるのを確認してください。

以下は、実際に動作するサンプルです。ゲーム画面をクリックして動作を確認してみてください。


まとめ

今回は、雪の結晶画像と雪だるまが当たったかどうかを判定する機能を組み込みました。これで基本的なアクションゲームの仕組みはそろったことになります。次回は、雪の結晶画像を増やし、ランダムに降らせる処理を追加します。

ただし、そろそろ de:code 2015の準備に取り掛からなければならないので、更新には時間があくかもしれません。

ある程度ゲームができた以降は、Azure Web Apps へのデプロイや、Univarsal Windows Apps への展開、Apache Cordova を使用した iOS、Android アプリ化 と Firefox OS 用アプリ、Chrome Apps 化なども考えていますので、お楽しみに。(ほんとに全部書けるんだろうか)


Web Statistics

Web コンテンツを開発するための Node.js 簡易 Web サーバー

$
0
0

de:code 2015にご参加された皆様、ありがとうございました。ご参加されなかった皆様も、そのうちスライドや動画が公開されると思いますので、ぜひご覧ください。

de:code が終わって、前回の記事の続きで「HTML5 を使ったシンプルな 2 D ゲームの作り方(複数インスタンスの生成)」を書こう、と思ったのですが、このシリーズを書いている間に build 2015があり、その中で、Windows はもちろん、Mac、Linux 環境でも使用できるコーディングツール Visual Studio Codeが発表されました。

そして、そのタイミングで公開された Visual Studio 日本チームブログの記事では、このブログの「「HTML5 を使ったシンプルな 2 D ゲーム…」の記事を紹介してくれているのですが、紹介文にはこう書いてありました。

「(Visual Studio 2013 Community / Visual Studio Code で解説していますが、Visual Studio 2015 でも大丈夫です )」

「(Visual Studio 2013 Community /Visual Studio Codeで解説していますが、Visual Studio 2015 でも大丈夫です )」

(え、そうなの!?)

….すみません。Visual Studio Codeだけ” では、以下でやっている内容を実施することはできません。

  1. HTML5 を使ったシンプルな 2 D ゲームの作り方(序)
  2. HTML5 を使ったシンプルな 2 D ゲームの作り方(準備編)
  3. HTML5 を使ったシンプルな 2 D ゲームの作り方 (画像のロード)
  4. HTML5 を使ったシンプルな 2 D ゲームの作り方 (アニメーションの実装)
  5. HTML5 を使ったシンプルな 2 D ゲームの作り方 (矢印キーとタッチによる制御の実装)

なぜならば、ここで作っているゲームはサーバーサイドのロジックは使用していないものの、Web サーバーでホストされないと動作しないからです。

しかし Visual Studio Codeは、IDE である Visual Studio とは違い Web サーバーはついていません。よって自分で Web サーバーを用意する必要があります。

このブログでも IIS Express の入手から単体で起動する方法を紹介していますが、慣れていない方には少々ハードルが高いようです。

そこで、もう少し手軽に使える Web サーバーがあったらいいナー、ってことで、Node.js で簡易的な Web サーバーを書いてみました。

実際のコードと使い方を以下に示しますのでご興味があればお試しください。Node.js なので、Windows はもちろん、Mac でも Linux でも動作しますよ。

 

Web コンテンツを開発するための
Node.js 簡易 Web サーバー

Node.js で作成した簡易的な Web サーバーです。使用するには、以下のコードをテキストエディタに貼り付け、webServer.jsという名前で保存してください。なお、文字エンコードは UTF-8 にしてください。

/*Web コンテンツを開発するための Node.js 簡易 Web サーバー サンプル*/

//Web サーバーが Listen する IP アドレス
var LISTEN_IP = '127.0.0.1';
//Web サーバーが Listen する ポート
var LISTEN_PORT = 8086;
//ファイル名が指定されない場合に返す既定のファイル名
var DEFAULT_FILE = "default.html";

var http = require('http'),
    fs = require('fs');

//拡張子を抽出
function getExtension(fileName) {
    var fileNameLength = fileName.length;
    var dotPoint = fileName.indexOf('.', fileNameLength - 5 );
    var extn = fileName.substring(dotPoint + 1, fileNameLength);
    return extn;
}

//content-type を指定
function getContentType(fileName) {
    var extentsion = getExtension(fileName).toLowerCase();
    var contentType = {
        'html': 'text/html',
        'htm' : 'text/htm',
        'css' : 'text/css',
        'js' : 'text/javaScript; charset=utf-8',
        'json' : 'application/json; charset=utf-8',
        'xml' : 'application/xml; charset=utf-8',
        'jpeg' : 'image/jpeg',
        'jpg' : 'image/jpg',
        'gif' : 'image/gif',
        'png' : 'image/png',
        'mp3' : 'audio/mp3',
        };
        var contentType_value = contentType[extentsion];
        if(contentType_value === undefined){
            contentType_value = 'text/plain';};
    return contentType_value;
}

//Web サーバーのロジック
var server  = http.createServer();
server.on('request',
    function(request, response){
        console.log('Requested Url:' + request.url);
        var requestedFile = request.url;
        requestedFile = (requestedFile.substring(requestedFile.length - 1, 1) === '/')
? requestedFile + DEFAULT_FILE : requestedFile;
        console.log('Handle Url:' + requestedFile);
        console.log('File Extention:' + getExtension( requestedFile));
        console.log('Content-Type:' + getContentType( requestedFile));
        fs.readFile('.' + requestedFile,'binary', function (err, data) {
            if(err){
                response.writeHead(404, {'Content-Type': 'text/plain'});
                response.write('not found\n');
                response.end();   
            }else{
                response.writeHead(200, {'Content-Type': getContentType(requestedFile)});
                response.write(data, "binary");
                response.end();
            }
        });
    }
);

server.listen(LISTEN_PORT, LISTEN_IP);
console.log('Server running at http://' + LISTEN_IP + ':' + LISTEN_PORT);

 

Node.js が動作するか確認

Node.js がインストールされているかを確認します。コマンドプロンプトを起動し、以下のコマンドを実行してバージョンが返れば Node.js がインストールされています。

node –v

 

Apache Cordova の開発環境や、Visual Studio Code がインストールされている環境には Node.js がインストールされています。

Node.js がインストールされない場合は、以下のサイトからインストーラーを入手してセットアップを行ってください。

Node.js のインストールは公式ページの [INSTALL] ボタンをクリックしてインストーラーを実行し、ウィザードにしたがって作業を進めれば OK です。

詳細なインストーラーの手順については、以下の記事の「Node.js のインストール」で紹介していますので、心配な方はご覧ください。

 

webServer.js の配置と実行

Web サーバーのサンプルコードを張り付けて作ったファイル webServer.js  を Web サイトとして扱いたいフォルダのルートにあたるディレクトリに配置します。

webServer.js  を実行するには、コマンドプロンプトを起動し、作業フォルダを cd コマンドで webServer.js を配置したフォルダにするか、または、エクスプローラーのメニュー[ファイル] – [コマンドプロンプトを開く] を実行します。

image

コマンドプロンプトで以下のコマンドを実行します。

node webserver.js

webServer.js のプロセスはローカル IP の 8086 でリスンを開始するので、Web ブラウザを起動し、アドレスバーに以下のように URL を指定します。

 http://127.0.0.1:8086/ファイル名

webServer.js が正常に動作していればリクエストされたファイルの内容が Web ブラウザーに表示されます。ちなみに、ファイル名を指定しないと default.html を返すようになっています。

ポート番号はわかりやすいものをつけているだけなので、もし他のサービスと競合するようであれは、ソースを編集して変えていただいて結構です。4126 (ヨイフロ) なんて分かり易くて良いかもしれませんね。

webServer.js の改造について

webServer.js は Node.js で書かれており、あくまでもサンプルコードとして掲示しておりますので、Node.js の API リファレンスを参考にお好きに改変していただいて構いません。

webServer.js  の配布ももちろん OK です。

そのかわり動作保障とかサポートはありませんので、あしからず :-P

 

Web Statistics

2016 年 1 月 12 日でサポート終了となるバージョンの Internet Explorer でアクセスすると、その旨をひかえめに教えてくれるバーを表示するスクリプト

$
0
0

昨年の 8 月にアナウンスされ、すでに多くの方がご存じのとおり、来年 (2016) の 1 月 12 日からは、Internet Explorer のサポートポリシーが変更され、その Windows で動作する最も高いバージョンの Internet Explorer しかサポートされなくなります。
(※タイトルのサポート終了日付が間違っておりましたので修正しました。どうもすみません)

具体的には以下の組み合わせのものだけがサポートされるようになります。

Windows Internet Explorer 延長サポート終了
Windows Vista SP2 Internet Explorer 9 2017年 4 月 11 日
Windows Server 2008 SP2
Windows 7 SP1 Internet Explorer 11 2020年 1 月 14 日
Windows Server 2008 R2 SP1
Windows Server 2012 Internet Explorer 10 2023年 1 月 10 日
Windows 8.1
(Windows8はWindows8.1へのアップグレードが必要)
Internet Explorer 11
Windows Server 2012 R2 Internet Explorer 11
Windows 10Internet Explorer 11(最低でも10年)

(2016年1月12日以降、サポートされる
Windows と Internet Explorer の組み合わせ)

 

これにより、HTML5 が動作せず、他の Web ブラウザーとの振る舞いも異なる旧い時代の Internet Explorer のサポートが終了することになります。(※Vista の Internet Explorer 9 はまだ機能が充分でないというのがありますが、それはまぁ、Vista ですし…アレですよ。質問しないでくださいね♡)

とにかく、来年の 1 月以降は、Web 制作において「IE ハック」などど呼ばれる、いわゆる “Internet Explorer のためだけに行う激しくマイナスな感情をともなう特別な作業”、というものは必要なくなるはずです。

そうです、もう二度と attachEvent や @cc_on 、<!--[if (IE)]> といった記述をすることはなく、html5shiv.js を参照することもなく、Polyfill  や Progressive Enhancement  という言葉も、もはや、将来子供にしてやる苦労話の一つとして記憶の彼方に追いやることができるのです。

多くの Web 製作者の方々は IE、レガシーブラウザー対応という、なんら将来の投資に 1 ミリも値しない不毛な作業から解放され、人生をもっと豊かで有意義なものにできることでしょう。

しかし、ほんとうにそんなにうまく事が運ぶのでしょうか?

 

どうするの? メーカーのサポート終了後の Old IE 対応

レガシー IE のサポートが終わったからといって、レガシー IE 対応がすぐに無くなることはないでしょう。

なぜならはメーカーのサポートが終了しても レガシー IE を使い続けるユーザーがおり、それらユーザー対しても品質を低下させることなく Web コンテンツを提供したいという意思が働く場合はレガシー IE 対応を続けることになります。

たとえば、広告によって収入を得る Web サイトの場合は PV は直接収入に関係するものですから、ユーザーがメーカーのサポートが終了した Web ブラウザーを使用しているからといって、その割合が多い場合には対応せざるを得ないでしょう。

しかし、そういった時代遅れのレガシーブラウザを手厚く保護すればするほど、ユーザーは不便を感じず、ブラウザーをバージョンアップすることなく使い続け、結果、いっこうに減らないレガシーブラウザのユーザーのために、Web 製作者は今までと変わらない不毛な作業を続けることになるのです。まさにこれは負の連鎖と言えるでしょう。

こういった負の連鎖はどこかで断ち切らなければなりません。しかし、ユーザーがメーカーもサポートをやめた時代遅れの Web ブラウザーを使い続けているからといって、ないがしろにすることはできません。古いブラウザーを使ってはいても、自分たちの Web サイトに来てくれて、広告をクリックしてくださる大切なお客様なのです。

ではどうすれば良いでしょうか?

理想的なのは、ユーザーが自分の意思で Internet Explorer 11 にアップグレードするなどして、レガシーブラウザーからモダンブラウザーに移行することです。

ではどうすればユーザーにレガシーブラウザーの使用をやめさせることができるでしょうか?

それにはまず、そういったユーザーがなぜレガシーブラウザーを使い続けるのかを考える必要があります。

 

ユーザーがサポート切れのレガシーブラウザーを使い続ける理由

ユーザーがサポート切れのレガシーブラウザーを使い続ける理由はいろいろあるでしょう。

使用している OS が古すぎてレガシーブラウザーしかインストールできない、特定のバージョンの Internet Explorer に特別な思い入れがある (例 : 亡くなった奥さんが愛用していた)、宗教上の理由、など様々な理由が考えられます。

しかし、私が思うに、そういったユーザーの大部分は、たんにサポートの終了期限を知らないか、知っていても、サポート切れた Web ブラウザーを使用し続けることがどれだけ恐ろしいことかご存知ないだけだと思うのです。

つまり、正しい情報が、正しく、そしてあまねく伝わりさえすれば、そういったユーザーのけして少なくない数の人たちが、ブラウザーをアップデートしてくれると思うです。

 

ユーザーにレガシー IE のサポート終了を知らせるには

マイクロソフトでは、以下のように TechNet に大きくレガシー IE のサポート終了を知られる掲示をしたり、我々もセッションや、ブログなどでこの件を発信していますが、残念ながら、我々がリーチできるのは、IT に興味をもっている方々くらいです。

image

お仕事などで IT にかかわらない方々はこういった情報に触れることはないと思いますので、皆さまの周りで Internet Explorer 11  以前のブラウザーを使用している方がいらっしゃいましたら、もうすぐサポートが終了する旨をお伝えいただくとともに、ぜひともブラウザーのアップデートを勧めていただければと思います。

 

ユーザーが使用している IE が、
来年の 1 月 12 日でサポートが終了するバージョンだった場合
お知らせバーを表示するスクリプト

ユーザーの使用している Web ブラウザーが来年 (2016 年) の 1 月 12 日でサポートが終了するバージョンだった場合に、画面上部に控えめのその旨を知らせるメッセージバーを表示するスクリプトを作成してみました。

すでにこのページにも仕込んであり、該当する Internet Explorer と Windows の組み合わせでアクセスすると以下のようなバーが表示されます。

image

青いバーは、バーのどこかをクリックすると消えます。

Internet Explorer 11 で試す場合には F12 開発者ツールでドキュメントモードを変更してその挙動を確認してみてください。

ただし、Windows 10 + Internet Explorer 9 のようなありえない組み合わせではバーは表示されません。Windows 10 で試す場合には、ドキュメントモードを IE8 以前のものにするか、エンタープライズモードを使用してください。

このスクリプトのソースコードは以下のとおりです。

//レガシーな Internet Explorer のサポート終了を知らせるバーを表示する
(function () {
    //サポート終了日
    var SUPPORT_LIMIT_DATE = '2016/01/12';
    //Windows 7 の検出用
    var WIN7_STRING = 'Windows NT 6.1';
    //IE11> の IE の検出用
    var MSIE_STRING = 'MSIE';
    //レガシーIEサポート終了のお知らせブログの URL
    var CAUTION_URL = 'http://bit.ly/change_iesupport';
    //IE11 のダウンロードページ
    var IE_DL_URL = 'http://bit.ly/dl_ie_jp';
    var CAUTION_TITLE_STRING = '最新の Internet Explorer をご利用ください';
    var DL_TITLE_STRING = 'Internet Explorer のダウンロード - Microsoft Windows';
    var user_agent = bypassBrowserCheck();
    var legacyIE = false;
    var div = null;

    //情報バーを生成して表示
    function show_limit_bar() {
        //サポート終了日をさかいに表現を変える
        var isGoneSiting = (new Date() >= new Date(SUPPORT_LIMIT_DATE)) ? 'ました。' : 'ます。';
        var LIMIT_BAR_INNER_HTML = '<div style="'
            + 'background-color:blue;color:white;'
            + 'position:absolute;top:0px;left:0px;padding:10px;'
            + 'width:100%;font-size:10px;cursor:pointer;">'
            + 'ご使用になっている Web ブラウザーのサポートは 2016 年 1 月 12 日で終了し'
            + isGoneSiting
            + '<a title="' + CAUTION_TITLE_STRING
            + '" href="' + CAUTION_URL + '" target="_blank">'
            + '<span style="color:yellow;">詳しくはこちらをご覧ください。</span></a>'
            + '最新のブラウザーは<a title="' + DL_TITLE_STRING
            + '" target="_blank" href="' + IE_DL_URL
            + '"><span style="color:yellow;">ここから入手</span></a>してください。'
            + '</div>';
        div = document.createElement('div');
        div.innerHTML = LIMIT_BAR_INNER_HTML;
        try {
            if (legacyIE) { div.attachEvent('onclick', remove_limit_bar); }
            else { div.addEventListener('click', remove_limit_bar, false); }
            document.body.appendChild(div);
        } catch (err) {
            //エラーを上げないためなのでなにもしない
        }
    }

    //情報バーを削除
    function remove_limit_bar() {
        document.body.removeChild(div);
    };

    //レガシー IE を検出
    if (!window.addEventListener) {
        //IE9 以前
        legacyIE = true;
        window.attachEvent('onload', show_limit_bar);
    } else {
        if (user_agent.indexOf(WIN7_STRING) > -1
                && user_agent.indexOf(MSIE_STRING) > -1) {
            window.addEventListener('load', show_limit_bar, false);
        }
    };

    //dev.modern.ieのSiteScan の [ブラウザー検出] で不合格とならないため
    function bypassBrowserCheck() {
        var STRING_USERANENT_MEYHOD = 'navigator$userAgent';
        return eval(STRING_USERANENT_MEYHOD.replace('$','.'));
    };
})();


 

上記コードはサンプルコードとして掲載していますので、とくに動作保証は致しません。

その代わりといってはなんですが、改変や配布は自由にしてただいて構いませんので、ご自由にお使いいただければと思います。

また、手っ取り早くご自分のページで試したい場合は、以下の参照タグを HTML の適当な場所に記述すればバーが表示されるようになります。


 

このファイルはミニファイされており、コードの使用している変数名および関数名のスコープも、逐次実行関数内で閉じていますので、名前空間を汚染することはありませんので安心してお使いください。

 

まとめ

今回は、ユーザーの使用している Web ブラウザーが来年 (2016 年) の 1 月 12 日でサポートが終了するバージョンだった場合に、画面上部に控えめにその旨を知らせるメッセージバーを、あくまでも控えめに表示するスクリプトを紹介しました。

繰り返しになりますが、皆さまの周りで Internet Explorer 11  以前のブラウザーを使用している方がいらっしゃいましたら、もうすぐサポートが終了する旨をお伝えいただくとともに、ぜひともブラウザーのアップデートを勧めていただければと思います。

Web Statistics

HTML5 を使ったシンプルな 2 D ゲームの作り方(効果音を鳴らす)

$
0
0

このシリーズまだやってたの!?、と声が聞こえてきそうなくらい前回から間が空いてしまいましたが約半年ぶりに HTML5 を使用したシンプルな 2D ゲームの作り方の第 10  回めをお送りします。

どんなゲームを作るのかは 1 回目の記事の中に実際に動作するゲームが埋め込んであるのでぜひ遊んでみてください。なお、開発に必要な画像データは 2 回目の記事からダウンロードできますので、実際にゲーム開発を体験したい方はそちらから入手してください。

  1. HTML5 を使ったシンプルな 2 D ゲームの作り方(序)
  2. HTML5 を使ったシンプルな 2 D ゲームの作り方(準備編)
  3. HTML5 を使ったシンプルな 2 D ゲームの作り方 (画像のロード)
  4. HTML5 を使ったシンプルな 2 D ゲームの作り方 (アニメーションの実装)
  5. HTML5 を使ったシンプルな 2 D ゲームの作り方 (矢印キーとタッチによる制御の実装)
  6. HTML5 を使ったシンプルな 2 D ゲームの作り方 (当たり判定の実装)
  7. HTML5 を使ったシンプルな 2 D ゲームの作り方 (複数のSpriteの生成)
  8. HTML5 を使ったシンプルな 2 D ゲームの作り方 (ランダムな動作と FPS の制御)
  9. HTML5 を使ったシンプルな 2 D ゲームの作り方(スプライトを使った画像の切り替え)

前回までの記事で、1. 入力装置からのプレイヤーの操作2. 複数のターゲットの生成とランダムな動作3.当たり判定、4. スプライト(キャラクター)の変更といったおおよそアクションゲームに必要な機能の実装が完了しました。

今回は当たり判定時の効果の追加ということで、雪だるまと雪の結晶がヒットした際に音を出すようにしたいと思います。

 

HTML5 を使用したオーディオファイルの再生

HTML5 ファイルで MP3 などのオーディオファイルを再生する方法はいくつかありますが、単に再生するだけであれば Audio オブジェクトを使用するのが簡単です。わざわざ audio タグを記述しなくても以下のような JavaScript でオーディオファイルを再生することができます。

var audioObj = new Audio(‘your_audio_file_url.mp3’);
audioObj.play();

 

HTML5 の Audio オブジェクトのより詳しい使い方については以下のドキュメントを参照してください。

 

オーディオファイルの入手と配置

使用するオーディオファイルは以下の OneDrive のシェアから snow_game_audio.zipをダウンロードしてください。

snow_game_audio.zip を解凍すると audio という名前のフォルダが出てくるので、これを Visual Stuio のソリューションエクスプローラーにドラッグドロップして追加します。

以下のようになれば配置は完了です。

image

コードの追加

雪の結晶に雪だるまが当たった際に音を鳴らすだけなので、当たり判定処理の中に前述のコード記述すれば良いと思われるかもしれませんが、そう簡単ではありません。

例えば、雪の結晶は複数あるので、それらに同時にぶつかった際にはそれぞれに音を出す必要があります。

また、ゲームの処理はすべてアニメーションのためのフレーム(繰り返し処理)の中で動作しているため、そのまま単に音を鳴らす処理を記述しただけでは同じ処理が何度も繰り返されることになるので、それを防ぐための処理を実装する必要があります。

ここからは、前回までのコードにそういった点を考慮した実装を行っていきます。

 

Sprite クラスへの Audio プロパティの追加

ゲーム画面内で動作する Sprite (キャラクター) のクラス(※)に Audio オブジェクトのインスタンスを格納するためのプロパティと、フレーム処理の中でオーディオの繰り返し再生を避けるためのプロパティを定義します。
(※厳密にいうと JavaScript に”クラス”は無いので”関数”なのですが、理解しやすさを優先してこう呼びます。)

具体的には以下のように Spriteクラスを定義しているコードの、プロパティとして外部変数を定義している箇所に、Audio オブジェクトのインスタンスを格納するための変数 audioと 繰り返し再生を避けるために再生済みを示すフラグ audioPlayedを定義します。

//Sprite クラスの定義
   var Sprite = function (img, width, height) {
       this.image = img; //image オブジェクト
       this.height = img.height;
       this.width = img.width;
       this.x = 0;   //表示位置 x
       this.y = 0;  //表示位置 y
       this.dx = 0; //移動量 x
       this.dy = 0; //移動量 y
       this.audio = null; //Audio オブジェクト
       this.audioPlayed = false; //音が複数回鳴るのを防ぐ
       var _offset_x_pos = 0;
       var that = this;
~ 略 ~

 

Audio オブジェクトのインスタンス生成と格納

雪の結晶用の Sprite クラスのインスタンスが生成されるタイミングで Audio オブジェクトのインスタンス生成してプロパティに格納します。

個別の Sprite クラスに Audio オブジェクトを持たせるのはそれぞれに独立した再生を行わせるためです。

具体的なコードの追加箇所は loadAssets関数内で img_snowオブジェクトの onload イベントハンドラを定義している以下の箇所です。

function loadAssets() {
    //HTML ファイル上の canvas エレメントのインスタンスを取得  
    canvas = document.getElementById('bg');
    //アニメーションの開始
    canvas.addEventListener("click", loadCheck);
    //2D コンテキストを取得 
    ctx = canvas.getContext('2d'); 
    //image オブジェクトのインスタンスを生成 
    img_snow = new Image(); 
    //image オブジェクトに画像をロード 
    img_snow.src = '/img/sp_snow.png';

    /*画像読み込み完了のイベントハンドラーに Canvas に 
       画像を表示するメソッドを記述 */ 
    img_snow.onload = function () {
        for (var i = 0; i < SNOWS_COUNT; i++) {
            var sprite_snow = new Sprite(img_snow, SNOW_PIC_WIDTH, SNOW_PIC_HEIGHT);
            sprite_snow.dy = 1;
            sprite_snow.dx = NEIGHBOR_DISTANCE;
            sprite_snow.x = i * sprite_snow.dx;
            sprite_snow.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
            //Audio オブジェクトのインスタンスをセット
            sprite_snow.audio = new Audio("audio/kiiiin1.mp3");
            snow_sprites.push(sprite_snow);
            sprite_snow = null;
        }
};

 

オーディオ オブジェクトの再生

雪の結晶の Sprite オブジェクトの audio プロパティに設定されたオーディオ オブジェクトを再生します。

これは単に当たり判定の処理である isHit関数内で playメソッドを実行し、フレーム処理による繰り返し再生を避けるためのフラグである audioPlayedプロパティを true に設定する処理と if 文を記述するだけです。

具体的には以下のような記述となります。

//当たり判定
function isHit(targetA, targetB) {
    if ((targetA.x <= targetB.x && targetA.width + targetA.x >= targetB.x)
            || (targetA.x >= targetB.x && targetB.x + targetB.width >= targetA.x)) {

        if ((targetA.y <= targetB.y && targetA.height + targetA.y >= targetB.y)
            || (targetA.y >= targetB.y && targetB.y + targetB.height >= targetA.y)) {
            ctx.font = "bold 20px 'MS ゴシック'";
            ctx.fillStyle = "red";
            ctx.fillText("ヒットしました", getCenterPostion(canvas.clientWidth, 140), 160);
            targetA.imageIndex = SNOW_CLASH;
             //衝突音を鳴らす
          if (!targetA.audioPlayed) {
                targetA.audio.play();
                targetA.audioPlayed = true;

            }
        }
    }
}

 

再生済みフラグのリセットと再生の終了

雪の結晶が画面から消え、表示位置をリセットするタイミングで再生済みフラグである audioPlayedプロパティを fase に変更します。

また同時に、今回は再生時間の短いオーディオファイルであるためあまり必要ないのですが、再生を停止するための pauseメソッドを実行します。

これらの処理はフレーム毎に呼び出される renderFrame 関数内に以下のように記述します。

function renderFrame() {
    if (timeKeeper.nextFrameJob()) {
        //canvas をクリア
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //sprite_snow_man の x 値が動作範囲内かどうか
        if ((sprite_snow_man.x < sprite_snow_man.limit_rightPosition && key_value > 0)
            || (sprite_snow_man.x >= 3 && key_value < 0)) {
            //img_snow_man の x 値を増分
            sprite_snow_man.x += key_value;
        }

        var length = snow_sprites.length;
        for (var i = 0; i < length; i++) {
            var snow_sprite = snow_sprites[i];
            //snow_sprite の y 値(縦位置) が canvas からはみ出たら先頭に戻す
            if (snow_sprite.y > canvas.clientHeight) {
                snow_sprite.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                snow_sprite.imageIndex = SNOW_BLUE;
                //オーディオ再生を停止
                snow_sprite.audio.pause();
                //オーディオ再生済フラグのリセット
                snow_sprite.audioPlayed = false;
            }else {
                if (loopCounter == SWITCH_PICTURE_COUNT 
                    && snow_sprite.imageIndex != SNOW_CLASH) {
                        snow_sprite.imageIndex = (snow_sprite.imageIndex == SNOW_BLUE)
                        ? SNOW_WHITE : SNOW_BLUE;
                } 
            };
                
            //snow_sprite の y 値を増分
            snow_sprite.y += snow_sprite.dy;
            //画像を描画
            snow_sprite.draw();

            //当たり判定
            isHit(snow_sprite, sprite_snow_man);
                snow_sprite = null;
            }
            //画像を描画
            sprite_snow_man.draw();

            //処理数のカウント
            if (loopCounter == SWITCH_PICTURE_COUNT) { loopCounter = 0; }
            loopCounter++;

            window.requestAnimationFrame(renderFrame);
        } else {
            window.requestAnimationFrame(renderFrame);
        }
    }


 

ここまでの作業で、雪の結晶が雪だるまに衝突した際に音ができるようになりました。

以下の黒いボックスをクリックして、実際の動作を確認してください。(矢印キー[←][→]で雪だるまが左右に移動します。スマートフォンの場合はタッチで操作が可能です)


 

今回作業を行った main.js 全体のコードは以下のとおりです。

(function () {
    //矢印キーのコード
    var LEFT_KEY_CODE = 37;
    var RIGHT_KEY_CODE = 39;
    var key_value = 0;

    //全体で使用する変数
    var canvas = null;
    var ctx = null;
    var img_snow = null;
    var img_snow_man = null;

    //画面の書き換え数をカウントする
    var loopCounter = 0;

    //雪の結晶画像を切り替える閾値
    const SWITCH_PICTURE_COUNT = 24;

    //1 秒間に実行されるフレーム数
    const GAME_FPS = 48;

    //表示する雪の結晶の数
    const SNOWS_COUNT = 6;

    //移動開始位置を得るための係数
    const SNOW_START_COEFFICIENT = -50;

    //隣り合う 雪の結晶画像の x 位置の差分
    const NEIGHBOR_DISTANCE = 58;

    //雪だるまの Sprite のインスタンスを格納する配列 
    var sprite_snow_man = null;

    //雪の Sprite のインスタンスを格納する配列 
    var snow_sprites = [];

    //スプライト画像のインデックス
    const SNOW_BLUE = 0;
    const SNOW_WHITE = 1;
    const SNOW_CLASH = 2;

    //���の結晶の画像サイズ
    const SNOW_PIC_HEIGHT = 32;
    const SNOW_PIC_WIDTH = 32;

    //雪ダルマの画像サイズ
    const SNOW_MAN_PIC_HEIGHT = 80;
    const SNOW_MAN_PIC_WIDTH = 80;

    //Sprite クラスの定義
    var Sprite = function (img, width, height) {
        this.image = img; //image オブジェクト
        this.height = img.height;
        this.width = img.width;
        this.x = 0;   //表示位置 x
        this.y = 0;  //表示位置 y
        this.dx = 0; //移動量 x
        this.dy = 0; //移動量 y
        this.audio = null; //Audio オブジェクト
        this.audioPlayed = false; //音が複数回鳴るのを防ぐ
        var _offset_x_pos = 0;
        var that = this;

        //使用するインデックスを設定するための Setter/Getter
        var _imageIndex = 0;
        Object.defineProperty(this, "imageIndex", {
            get: function () {
                return _imageIndex;
            },
            set: function (val) {
                _imageIndex = val;
                _offset_x_pos = width * _imageIndex;
            }
        });

        //Sprite を描画するメソッド
        this.draw = function () {
            ctx.drawImage(img, _offset_x_pos, 0, width, height, that.x, that.y, width, height);
        };
    }

    //FPS をコントロールするための timeKeeper クラス
    function TimeKeeper(frameCount) {
        var bofore_animation_time = 0;
        var frameInterval = (600 / frameCount);
        //window.performance オブジェクトに対応していないブラウザへの対応
        var getNow = (window.performance.now) ?
            function () { return window.performance.now(); }
            : function () { return (new Date()).getTime(); }
        //FPS として指定したフレームごとの時間が経過したら true を返す
        this.nextFrameJob = function () {
            var now_the_time = getNow();
            var renderFlag = !(((now_the_time - bofore_animation_time) < frameInterval)
                && bofore_animation_time);
            if (renderFlag) bofore_animation_time = now_the_time;
            return renderFlag;
        };
    }

    //TimeKeeper クラスのインスタンスを格納
    var timeKeeper = new TimeKeeper(GAME_FPS);


    //DOM のロードが完了したら実行
    document.addEventListener("DOMContentLoaded", function () {
        loadAssets();
        setHandlers();
    });

    function setHandlers() {
        //キーイベントの取得 (キーダウン)
        document.addEventListener("keydown", function (evnt) {
            if (evnt.which == LEFT_KEY_CODE) {
                key_value = -3;
            } else if (evnt.which == RIGHT_KEY_CODE) {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 キーが上がったら 0 に
        document.addEventListener("keyup", function () {
            key_value = 0;
        });

        //Canvas へのタッチイベント設定
        canvas.addEventListener("touchstart", function (evnt) {
            if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
                key_value = -3;
            } else {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 タッチが完了したら 0 に
        canvas.addEventListener("touchend", function (evnt) {
            key_value = 0;
        });
    }

    function loadAssets() {
        //HTML ファイル上の canvas エレメントのインスタンスを取得 
        canvas = document.getElementById('bg');
        //アニメーションの開始
        canvas.addEventListener("click", loadCheck);
        //2D コンテキストを取得
        ctx = canvas.getContext('2d');
        //image オブジェクトのインスタンスを生成
        img_snow = new Image();
        //image オブジェクトに画像をロード
        img_snow.src = '/img/sp_snow.png';

        /*画像読み込み完了のイベントハンドラーに Canvas に
           画像を表示するメソッドを記述 */
        img_snow.onload = function () {
            for (var i = 0; i < SNOWS_COUNT; i++) {
                var sprite_snow = new Sprite(img_snow, SNOW_PIC_WIDTH, SNOW_PIC_HEIGHT);
                sprite_snow.dy = 1;
                sprite_snow.dx = NEIGHBOR_DISTANCE;
                sprite_snow.x = i * sprite_snow.dx;
                sprite_snow.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                //Audio オブジェクトのインスタンスをセット
                sprite_snow.audio = new Audio("audio/kiiiin1.mp3");
                snow_sprites.push(sprite_snow);
                sprite_snow = null;
            }
        };
       
        //雪だるま画像のロード
        img_snow_man = new Image();
        img_snow_man.src = '/img/snow_man.png';
        img_snow_man.onload = function () {
            sprite_snow_man = new Sprite(img_snow_man, 
                                                       SNOW_MAN_PIC_WIDTH, SNOW_MAN_PIC_HEIGHT);
            sprite_snow_man.x = getCenterPostion(canvas.clientWidth, img_snow_man.width);
            sprite_snow_man.y = canvas.clientHeight - img_snow_man.height;
            sprite_snow_man.limit_rightPosition = getRightLimitPosition(canvas.clientWidth, 
                                                                                      img_snow_man.width);
        };
    };

    //ゲームで使用する Splite オブジェクトが準備されたかどうかを判断
    function loadCheck() {
        if (snow_sprites.length && sprite_snow_man) {
            //準備ができたらアニメーションを開始
            window.requestAnimationFrame(renderFrame);
        } else {
            //まだの場合はループして待機
            window.requestAnimationFrame(loadCheck);
        }
    }

    function renderFrame() {
        if (timeKeeper.nextFrameJob()) {
            //canvas をクリア
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            //sprite_snow_man の x 値が動作範囲内かどうか
            if ((sprite_snow_man.x < sprite_snow_man.limit_rightPosition && key_value > 0)
             || (sprite_snow_man.x >= 3 && key_value < 0)) {
                //img_snow_man の x 値を増分
                sprite_snow_man.x += key_value;
            }

            var length = snow_sprites.length;
            for (var i = 0; i < length; i++) {
                var snow_sprite = snow_sprites[i];
                //snow_sprite の y 値(縦位置) が canvas からはみ出たら先頭に戻す
                if (snow_sprite.y > canvas.clientHeight) {
                    snow_sprite.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                    snow_sprite.imageIndex = SNOW_BLUE;
                    //オーディオ再生の終了
                    snow_sprite.audio.pause();
                    //オーディオ再生済フラグのリセット
                    snow_sprite.audioPlayed = false;
                }else {
                    if (loopCounter == SWITCH_PICTURE_COUNT
                        && snow_sprite.imageIndex != SNOW_CLASH) {
                            snow_sprite.imageIndex = (snow_sprite.imageIndex == SNOW_BLUE)
                                ? SNOW_WHITE : SNOW_BLUE;
                    }
                };
               
                //snow_sprite の y 値を増分
                snow_sprite.y += snow_sprite.dy;
                //画像を描画
                snow_sprite.draw();

                //当たり判定
                isHit(snow_sprite, sprite_snow_man);
                snow_sprite = null;
            }
            //画像を描画
            sprite_snow_man.draw();

            //処理数のカウント
            if (loopCounter == SWITCH_PICTURE_COUNT) { loopCounter = 0; }
            loopCounter++;

            window.requestAnimationFrame(renderFrame);
        } else {
            window.requestAnimationFrame(renderFrame);
        }
    }

    //中央に配置する画像の X 座標を求める関数
    function getCenterPostion(containerWidth, itemWidth) {
        return (containerWidth / 2) - (itemWidth / 2);
    };

    //Player (雪だるまを動かせる右の限界位置)
    function getRightLimitPosition(containerWidth, itemWidth) {
        return containerWidth - itemWidth;
    }

    //雪の結晶の縦位置の初期値をランダムに設定する
    function getRandomPosition(colCount, delayPos) {
        return Math.floor(Math.random() * colCount) * delayPos;
    };

    //当たり判定
    function isHit(targetA, targetB) {
        if ((targetA.x <= targetB.x && targetA.width + targetA.x >= targetB.x)
                || (targetA.x >= targetB.x && targetB.x + targetB.width >= targetA.x)) {

            if ((targetA.y <= targetB.y && targetA.height + targetA.y >= targetB.y)
                || (targetA.y >= targetB.y && targetB.y + targetB.height >= targetA.y)) {
                ctx.font = "bold 20px 'MS ゴシック'";
                ctx.fillStyle = "red";
                ctx.fillText("ヒットしました", getCenterPostion(canvas.clientWidth, 140), 160);
                targetA.imageIndex = SNOW_CLASH;

                if (!targetA.audioPlayed) {
                    targetA.audio.play();
                    targetA.audioPlayed = true;
                }
            }
        }
    }
})();


 

まとめ

ここまでの機能実装で、アクションゲームに最低限必要なアニメーションキャラクターの操作当たり判定キャラクター画像の変更オーディオ再生といった機能が実装できました。

ゲームの終了、リセット、点数の加算や表示といった機能は、これまで応用で実装可能だと思います。

今回作成したこの単純なゲームでも画像を入れかえることによって、例えば降ってくるお金を拾うゲームや、逆に爆弾をよけ続けるゲーム、タッチ機能を使い、蟻の群れを指でつぶすといったゲームを作成可能です。

以下にこれまで作業した内容のサンプルプロジェクトをダウンロード可能としましたので、ぜひ改造していろいろなものを作成してみてください。


Web Statistics

オンラインコンテンツが使用している JavaScript ライブラリを手元で置き換えて検証する方法について

$
0
0

前回の記事では、Edge 対応こと、Web ブラウザー同士の相互運用性を高める方法として以下の 5 つの点について紹介しました。

  1. ドキュメントモードの指定を行わない
  2. 新しい JS ライブラリ/フレームワークを使用する
  3. ブラウザープラグインを使用しない
  4. CSS ベンダープレフィックスを使用しない
  5. ブラウザーの検出を使用しない

今回は上記の項目、「 2 新しい JS ライブラリ/フレームワークを使用する」に対応する際、検証方法を楽にする手段として、オンライン上にある Web コンテンツが使用している JavaScript ライブラリを手元で置き換えて検証する方法について紹介します。

これには Fiddler という無償の HTTP デバッガーツール使用します(※)

(※) Fiddler を使用したオンライン上のファイルの置き換え方法については、すでに幾人かの方がブログで書かれているので、いまさらという感じもしますが、お客様の手順を紹介する際に、他人様のブログ記事を紹介するのもなんだかアレなので、記事を投稿することにしました。

実習用のページも用意しましたので、ぜひお試しくださいませ。

その前に Fiddler について簡単に紹介しておきましょう。

 

Fiddler とは?

Fiddler はプロキシ型の HTTP デバッガです。Web サーバーとクライアントの間を流れる HTTP パケットをキャプチャすることはもちろん、改ざんしたり、ステップ実行したりといったことも可能です。

Fiddler については、以前このブログで使い方を含めた詳しい紹介を行っていますので、詳細についてはそちらの記事をご覧くださいませ。

 

Fiddler の入手

Fiddler は以下のサイトから無償入手することができます。

Fiddler は Windows OS でしか動作しませんでしたが、最近は Mac や Linux で用の Mono ベースの Alpha 版が公開されています。

 

Edge の HTTP 通信をキャプチャするための準備

キャプチャの対象となる Web ブラウザーが Edge の場合は、Fiddler の設定に若干手を加える必要があります。

Edge は、これまでの Windows 用デスクトップアプリケーションとは異なる UWA (Universal Windows Application) として作られており、HTTP 通信の仕組みが異なるため Fiddler の既定の設定では通信をキャプチャすることができないためです。

Fiddler で Edge の HTTP 通信を行えるようにするには、以下の手順で設定を追加します。

Edge の HTTP パケットキャプチャの準備手順

  1. Fiddler を起動します。
     
  2. ツールバーの [WinConfig] ボタンをクリックします。

    image

  3. 「このアプリが PC に変更を加えることを許可しますか?」というメッセージボックスが表示されるので [はい] ボタンをクリックします。
     
  4. [AppContainer Loopback Exemption Utility] ダイアログボックスが表示されるので、同ダイアログボックスのリスト内の「Microsoft Edge」のチェックボックスにチェックを入れ [Save Change] ボタンをクリックします。

    image

以上の手順で Edge の HTTP 通信をキャプチャできるようになりました。

なお、この設定は Internet Explorer では必要ありません。

キャプチャする対象が Firefox の場合は、以下のドキュメントの内容を参考に Fiddler の Firefox 用アドインを有効にしてください。

 

オンライン上のファイルの置き換え

Fiddler を使用してオンライン上のファイルの置き換えを行うには、Auto Responder タブの機能を使用します。

image

Auto Responder タブでは Web クライアントのリクエストに対するルールを設定することができます。条件を設定し、レスポンスの改ざんなども行えます。

ここからは、こちらで用意した実習用のページを使用して、実際に手を動かしながら Fiddler の機能を実感いただければと思います。

以下の実習用のページには、jQuery のバージョン 1.7 が使用されています。

また jQueryUI は 1.8 を使用しており、サッカーボールの画像はマウスでドラッグアンドドロップで動かすことができます。

image

このページを使用している jQuery のライブラリを、 Fiddler を使用して  jQuery の最新のバージョンのものに置き換えます。

準備として、以下のページから jQuery の最新のバージョンをダウンロードしておいてください。

 

Auto Responder タブの機能を使用したファイルの置き換え手順は以下の通りです。

ファイルの置き換え手順

  1. Fiddler を起動します。
     
  2. 以下の URL にアクセスします。

    http://osamum-web2.azurewebsites.net/jq.html

  3. Fiddler の画面左側にある Web セッションリストに jquery-1.7.min.js へのリクエストがあることを確認します。

    image

  4. Fiddler の画面右側にあるタブ付きビューで [Auto Responder] タブをアクティブにします。
     
  5. 同タブ内の [Enable automaticresponses] チェックボックスにチェックをつけます。
     

    image

  6. Web セッションリストにある jquery-1.7.min.js へのリクエストを、[Auto Responder] タブ内のリストにドラッグアンドドロップして追加します。
     

    image

  7. 追加したリストアイテムを選択し、同タブの下にある [Rule Editor] の 2 つのコンボボックスの上のほうを以下のように設定し直します。
     

    元の値 : EXACT:http://osamum-web2.azurewebsites.net/js/jquery/jquery-1.7.min.js
         ↓
    変更後 : jquery-1.7.min.js

  8. [Rule Editor] の下のコンボボックスでは、ドロップダウンリストを表示し、リストの一番下にある [Find a file…] を選択するとファイルを選択するダイアログボックスが表示されるので、あらかじめダウンロードしておいた最新の jQuery の *.js ファイルを参照します。
    設定が完了した [Rule Editor]  は以下のようになります。
     

    image

    設定が完了したら [Save] ボタンをクリックして設定を保存します。

ブラウザーを更新し、ページ内の jQuery のバージョンが 1.7 ではなく新しいものになっていることを確認してください。

image

なお、検証が終わったら [Enable automaticresponses] チェックボックスのチェックをすぐに外すようにしてください。チェックがついたままだと、他の Web サイトに正しくアクセスできない場合があります。

 

余力のある人は

上記の手順では jQuery のバージョンを 2.1.4 に変えましたが、これだとサッカーボールがドラッグアンドドロップで動かなくなってしまいました。

これは jQueryUI のバージョンが古いためです。jQueryUI のサイトから現在最新のバージョン 1.11.4 をダウンロードして前述の手順で置き換えると正常に動作するようになります。

image

また、サッカーボールの画像 ball.jpg をローカルの画像に差し替えてみても良いかもしれません。

 

まとめ

今回は Fiddler を使用してオンライン上のファイルを入れ替える方法を紹介しました。

この方法を使用すると、実際にホストされているコンテンツをそのままに検証することができます。

また Fiddler は非常にたくさんの機能を持っていますので、ぜひ活用してみてください。

 

Web Statistics

Clicky

2016 年 1 月 12 日でサポート終了となるバージョンの Internet Explorer でアクセスすると、その旨をひかえめに教えてくれるバーを表示するスクリプト

$
0
0

昨年の 8 月にアナウンスされ、すでに多くの方がご存じのとおり、来年 (2016) の 1 月 12 日からは、Internet Explorer のサポートポリシーが変更され、その Windows で動作する最も高いバージョンの Internet Explorer しかサポートされなくなります。
(※タイトルのサポート終了日付が間違っておりましたので修正しました。どうもすみません)

具体的には以下の組み合わせのものだけがサポートされるようになります。

Windows Internet Explorer 延長サポート終了
Windows Vista SP2 Internet Explorer 9 2017年 4 月 11 日
Windows Server 2008 SP2 2020年 1 月 14 日
Windows 7 SP1 Internet Explorer 11
Windows Server 2008 R2 SP1
Windows 8.0 Internet Explorer 10 2023年 1 月 10 日
Windows Server 2012 Internet Explorer 10
Windows 8.1 Internet Explorer 11
Windows Server 2012 R2 Internet Explorer 11
Windows 10 Internet Explorer 11 (最低でも10年)

(2016年1月12日以降、サポートされる
Windows と Internet Explorer の組み合わせ)

 

これにより、HTML5 が動作せず、他の Web ブラウザーとの振る舞いも異なる旧い時代の Internet Explorer のサポートが終了することになります。(※Vista の Internet Explorer 9 はまだ機能が充分でないというのがありますが、それはまぁ、Vista ですし…アレですよ。質問しないでくださいね♡)

とにかく、来年の 1 月以降は、Web 制作において「IE ハック」などど呼ばれる、いわゆる “Internet Explorer のためだけに行う激しくマイナスな感情をともなう特別な作業”、というものは必要なくなるはずです。

そうです、もう二度と attachEvent や @cc_on 、<!–[if (IE)]> といった記述をすることはなく、html5shiv.js を参照することもなく、Polyfill  や Progressive Enhancement  という言葉も、もはや、将来子供にしてやる苦労話の一つとして記憶の彼方に追いやることができるのです。

多くの Web 製作者の方々は IE、レガシーブラウザー対応という、なんら将来の投資に 1 ミリも値しない不毛な作業から解放され、人生をもっと豊かで有意義なものにできることでしょう。

しかし、ほんとうにそんなにうまく事が運ぶのでしょうか?

 

どうするの? メーカーのサポート終了後の Old IE 対応

レガシー IE のサポートが終わったからといって、レガシー IE 対応がすぐに無くなることはないでしょう。

なぜならはメーカーのサポートが終了しても レガシー IE を使い続けるユーザーがおり、それらユーザー対しても品質を低下させることなく Web コンテンツを提供したいという意思が働く場合はレガシー IE 対応を続けることになります。

たとえば、広告によって収入を得る Web サイトの場合は PV は直接収入に関係するものですから、ユーザーがメーカーのサポートが終了した Web ブラウザーを使用しているからといって、その割合が多い場合には対応せざるを得ないでしょう。

しかし、そういった時代遅れのレガシーブラウザを手厚く保護すればするほど、ユーザーは不便を感じず、ブラウザーをバージョンアップすることなく使い続け、結果、いっこうに減らないレガシーブラウザのユーザーのために、Web 製作者は今までと変わらない不毛な作業を続けることになるのです。まさにこれは負の連鎖と言えるでしょう。

こういった負の連鎖はどこかで断ち切らなければなりません。しかし、ユーザーがメーカーもサポートをやめた時代遅れの Web ブラウザーを使い続けているからといって、ないがしろにすることはできません。古いブラウザーを使ってはいても、自分たちの Web サイトに来てくれて、広告をクリックしてくださる大切なお客様なのです。

ではどうすれば良いでしょうか?

理想的なのは、ユーザーが自分の意思で Internet Explorer 11 にアップグレードするなどして、レガシーブラウザーからモダンブラウザーに移行することです。

ではどうすればユーザーにレガシーブラウザーの使用をやめさせることができるでしょうか?

それにはまず、そういったユーザーがなぜレガシーブラウザーを使い続けるのかを考える必要があります。

 

ユーザーがサポート切れのレガシーブラウザーを使い続ける理由

ユーザーがサポート切れのレガシーブラウザーを使い続ける理由はいろいろあるでしょう。

使用している OS が古すぎてレガシーブラウザーしかインストールできない、特定のバージョンの Internet Explorer に特別な思い入れがある (例 : 亡くなった奥さんが愛用していた)、宗教上の理由、など様々な理由が考えられます。

しかし、私が思うに、そういったユーザーの大部分は、たんにサポートの終了期限を知らないか、知っていても、サポート切れた Web ブラウザーを使用し続けることがどれだけ恐ろしいことかご存知ないだけだと思うのです。

つまり、正しい情報が、正しく、そしてあまねく伝わりさえすれば、そういったユーザーのけして少なくない数の人たちが、ブラウザーをアップデートしてくれると思うです。

 

ユーザーにレガシー IE のサポート終了を知らせるには

マイクロソフトでは、以下のように TechNet に大きくレガシー IE のサポート終了を知られる掲示をしたり、我々もセッションや、ブログなどでこの件を発信していますが、残念ながら、我々がリーチできるのは、IT に興味をもっている方々くらいです。

image

お仕事などで IT にかかわらない方々はこういった情報に触れることはないと思いますので、皆さまの周りで Internet Explorer 11  以前のブラウザーを使用している方がいらっしゃいましたら、もうすぐサポートが終了する旨をお伝えいただくとともに、ぜひともブラウザーのアップデートを勧めていただければと思います。

 

ユーザーが使用している IE が、
来年の 1 月 12 日でサポートが終了するバージョンだった場合
お知らせバーを表示するスクリプト

ユーザーの使用している Web ブラウザーが来年 (2016 年) の 1 月 12 日でサポートが終了するバージョンだった場合に、画面上部に控えめのその旨を知らせるメッセージバーを表示するスクリプトを作成してみました。

すでにこのページにも仕込んであり、該当する Internet Explorer と Windows の組み合わせでアクセスすると以下のようなバーが表示されます。

image

青いバーは、バーのどこかをクリックすると消えます。

Internet Explorer 11 で試す場合には F12 開発者ツールでドキュメントモードを変更してその挙動を確認してみてください。

ただし、Windows 10 + Internet Explorer 9 のようなありえない組み合わせではバーは表示されません。Windows 10 で試す場合には、ドキュメントモードを IE8 以前のものにするか、エンタープライズモードを使用してください。

このスクリプトのソースコードは以下のとおりです。

//レガシーな Internet Explorer のサポート終了を知らせるバーを表示する
(function () {
    //サポート終了日
    var SUPPORT_LIMIT_DATE = ‘2016/01/12′;
    //Windows 7 の検出用
    var WIN7_STRING = ‘Windows NT 6.1′;
    //IE11> の IE の検出用
    var MSIE_STRING = ‘MSIE';
    //レガシーIEサポート終了のお知らせブログの URL
    var CAUTION_URL = ‘http://bit.ly/change_iesupport';
    //IE11 のダウンロードページ
    var IE_DL_URL = ‘http://bit.ly/dl_ie_jp';
    var CAUTION_TITLE_STRING = ‘最新の Internet Explorer をご利用ください';
    var DL_TITLE_STRING = ‘Internet Explorer のダウンロード – Microsoft Windows';
    var user_agent = bypassBrowserCheck();
    var legacyIE = false;
    var div = null;

    //情報バーを生成して表示
    function show_limit_bar() {
        //サポート終了日をさかいに表現を変える
        var isGoneSiting = (new Date() >= new Date(SUPPORT_LIMIT_DATE)) ? ‘ました。’ : ‘ます。';
        var LIMIT_BAR_INNER_HTML = ‘<div style="’
            + ‘background-color:blue;color:white;’
            + ‘position:absolute;top:0px;left:0px;padding:10px;’
            + ‘width:100%;font-size:10px;cursor:pointer;">’
            + ‘ご使用になっている Web ブラウザーのサポートは 2016 年 1 月 12 日で終了し’
            + isGoneSiting
            + ‘<a title="’ + CAUTION_TITLE_STRING
            + ‘" href="’ + CAUTION_URL + ‘" target="_blank">’
            + ‘<span style="color:yellow;">詳しくはこちらをご覧ください。</span></a>’
            + ‘最新のブラウザーは<a title="’ + DL_TITLE_STRING
            + ‘" target="_blank" href="’ + IE_DL_URL
            + ‘"><span style="color:yellow;">ここから入手</span></a>してください。’
            + ‘</div>';
        div = document.createElement(‘div’);
        div.innerHTML = LIMIT_BAR_INNER_HTML;
        try {
            if (legacyIE) { div.attachEvent(‘onclick’, remove_limit_bar); }
            else { div.addEventListener(‘click’, remove_limit_bar, false); }
            document.body.appendChild(div);
        } catch (err) {
            //エラーを上げないためなのでなにもしない
        }
    }

    //情報バーを削除
    function remove_limit_bar() {
        document.body.removeChild(div);
    };

    //レガシー IE を検出
    if (!window.addEventListener) {
        //IE9 以前
        legacyIE = true;
        window.attachEvent(‘onload’, show_limit_bar);
    } else {
        if (user_agent.indexOf(WIN7_STRING) > -1
                && user_agent.indexOf(MSIE_STRING) > -1) {
            window.addEventListener(‘load’, show_limit_bar, false);
        }
    };

    //dev.modern.ieのSiteScan の [ブラウザー検出] で不合格とならないため
    function bypassBrowserCheck() {
        var STRING_USERANENT_MEYHOD = ‘navigator$userAgent';
        return eval(STRING_USERANENT_MEYHOD.replace(‘$’,’.’));
    };
})();

 

上記コードはサンプルコードとして掲載していますので、とくに動作保証は致しません。

その代わりといってはなんですが、改変や配布は自由にしてただいて構いませんので、ご自由にお使いいただければと思います。

また、手っ取り早くご自分のページで試したい場合は、以下の参照タグを HTML の適当な場所に記述すればバーが表示されるようになります。

 

このファイルはミニファイされており、コードの使用している変数名および関数名のスコープも、逐次実行関数内で閉じていますので、名前空間を汚染することはありませんので安心してお使いください。

 

まとめ

今回は、ユーザーの使用している Web ブラウザーが来年 (2016 年) の 1 月 12 日でサポートが終了するバージョンだった場合に、画面上部に控えめにその旨を知らせるメッセージバーを、あくまでも控えめに表示するスクリプトを紹介しました。

繰り返しになりますが、皆さまの周りで Internet Explorer 11  以前のブラウザーを使用している方がいらっしゃいましたら、もうすぐサポートが終了する旨をお伝えいただくとともに、ぜひともブラウザーのアップデートを勧めていただければと思います。

Web Statistics

Clicky

なぜサポートが終了した Web ブラウザーを使うと危険なのか?

$
0
0

前回の記事でも紹介させていただいたように来年 (2016) の 1 月 12 日をもって、IE9 以前の Internet Explorer はサポートが終了します。

image

しかし、機能が停止したりするわけではありませんので、事情を知らないユーザーはそのままサポートが切れたバージョンの Internet Explorer を使用し続けてしまう可能性があります。もしくは、サポートが切れていることを知っていても、アップグレードが面倒でそのまま使用し続けてしまう人もいるでしょう。

しかし、それは非常に大きなセキュリティ的なリスクを背負うことになります。

それでは、サポート期間の過ぎた Internet Explorer = ソフトウェアを使用し続けることはなぜ危険なのでしょうか?

今回は、既にさまざまなところで語られ、誰もがなんとなーく知っているはずの、サポート期間の切れたソフトウェアを使用し続ける危険性について、 初心者むけでなく、詳しい人向けに Internet Explorer を例に詳しく紹介します。

 

そもそも ”サポート期間” とは?

サポート期間とは、メーカーが出荷された製品に対し、ユーザーからの問い合わせの対応や不具合修正、新機能の追加といった、さまざまなケアを行う期間です。

マイクロソフトではサポート期間の全体をサポート ライフサイクルと呼び、その期間は 2 に分けられます。前半のフェーズをメインストリーム サポート フェーズ、後半のフェーズを延長サポート フェーズと呼んでいます。

この 2 つのフェーズについて簡単に説明しましょう。
(※)ここから、マイクロソフトのサポート フェーズついて紹介しましすが、興味がない方は「サポート期間が終了すると」に読み進んでください。

 

メインストリーム サポート フェーズ

メインストリーム サポート フェーズでは、製品の使い方などについての問い合わせ、いわゆるインシデント サポート (無償サポート有償サポート時間制サポート) およびセキュリティ更新プログラム サポートが提供されます。また、契約によってはセキュリティ関連以外の修正プログラムを要求できたりもします。

メインストリーム サポートフェーズの期間は、ビジネス、開発者向け、コンシューマー向け、オンライン製品とで詳細が異なりますが、Windows の場合は最低でも 5 年間はメインストリーム サポートが提供されます。

メインストリーム サポートが終了すると、 延長サポート フェーズに入ります。

 

延長サポート フェーズ

延長サポートフェーズでは、新機能の追加や、無償サポートはなくなりますが、有償サポートとセキュリティ更新プログラム サポートは引き続き提供されます。

延長サポートフェーズも、ビジネス、開発者向け、コンシューマー向け、オンライン製品とで詳細が異なりますが、Windows の場合はメインストリーム サポートと同様に最低でも 5 年間は延長サポートが提供されます。

なお、延長サポート フェーズは、一般ユーザー向け製品、ハードウェア製品、またはマルチメディア製品に対しては適用されませんので注意が必要です。

マイクロソフトのサポート ライフサイクルについては、以下のページで詳しく紹介されていますので、ぜひご覧ください。

 

サポート期間が終了すると

サポート期間が終了すると、有償、無償問わず、サポート期間中に提供されていたさまざまなサービスがすべて利用できなくなります。

たとえば、使用方法についての問い合わせもできなくなりますし、製品の不具合を報告しても、サポートが終了したバージョンについては修正は行われません。

なにより大きいのはセキュリティパッチが提供されなくなることでしょう。サポート切れの製品を使用する際の最大のリスクはここにあると言っても過言ではありません。とくに、インターネットに接続する Web ブラウザーにとっては致命的です。

セキュリティパッチとはなんなのか?、それが提供されないとなぜ困るのか?、について簡単に説明しましょう。

 

セキュリティパッチと Windows Update

さまざまな技術の進歩により、コンピューター上のデータはもちろん、プログラムやプロトコルの詳細な解析が以前よりも簡単になった結果、それらについての脆弱性も発見しやすくなりました。

ここでいう脆弱性とは、セキュリティ的な弱点となる不具合や仕様上の問題点です。自宅に鍵のかからないドアがあるとイメージするとわかりやすいかもしれません。

これら脆弱性に関する情報は、メーカーが見つけた場合には修正を行うことで製品の安全性向上に役立ちますが、第三者が見つけた場合には悪用される場合があります。

ソフトウェア製品の出荷後に脆弱性が見つかった場合に、それらを修正する目的で提供されるのがセキュリティパッチです。

マイクロソフトでは、毎月定期的に行われる Windows Update を利用してセキュリティの更新を行っていますが、深刻な脆弱性が見つかった場合には緊急パッチをリリースします。

Windows Update では、セキュリティパッチの配信だけでなく Windows 既定のアンチウィルス ソフトウェアである Windows Defender (旧 Microsoft Security Essentials ) の定義ファイルの更新や、ソフトウェアの不具合修正、機能追加なども行われます。

Windows Update はまさに Windows の恒常性を保つための仕組みであり、セキュリティパッチは、その中の免疫系といえるでしょう。

サポート期間が終了すると、Windows Update によるアップデートは行われなくなります。つまり、サポート期間が終了した Windows 関連のソフトウェアははこうした恒常系を保つための仕組みから外れることになります。

たとえば、来年 (2016) の 1 月 12 日以降、Windows 7 上で Internet Explorer 8 を使用していた場合、Windows 7 に対して行われる Windows Update に Internet Explorer 8 に関するものはいっさい含まれなくなります。

また、サポート期間が終了した製品が Windows そのものだった場合は、土台となる OS 自体が恒常性を保つための仕組みを失うことになるので、その上で動作するその他のソフトウェアが最新であっても、使用に関しなんらかのリスクを負うことになります。また、メーカーのサポートの対象とならない可能性もあります。

 

サポート期間が終了した Web ブラウザーを使用する危険性

サポート期間が終了し、セキュリティパッチが提供されなくなると、新たに脆弱性が見つかってもそのまま放置されることになり、悪意ある第三者の侵入や攻撃をみすみす許すことにつながります。

これは、自宅に修理不能な鍵のかからないドアがあり、それを多くの泥棒が既に知っている(※)とイメージするとわかりやすいかもしれません。
(※)脆弱性の情報はさまざまなところで公開されています。

昨年 (2014) サポートが終了した、Windows XP が稼働しているコンピューターはまさにこの状態であるといえるでしょう。たまに「Windows XP 使っているけどぜんぜん平気」いう方がいらっしゃいますが、それはたんに、鍵のかからない家にまだ泥棒が入っていないだけか、既に入られているのに気が付かないかのどちらかに過ぎず、けして安全であるとは言えません。

Web ブラウザーも同様です。とくに Web ブラウザーはインターネット上にあるマークアップやスクリプト、プラグインなど不特定多数の 動的な処理 の対象となるデータを扱うため、マルウェアへの感染など、最もリスクが高まるといっても過言ではないでしょう。

 

マルウェアとは

マルウェア(Malware)とは、コンピューターウィルスやワームといった、コンピューターやその使用者に害をなす目的で作られた悪質なコードの総称です。

マルウェアによる影響は、種類によってさまざまですか、クレジットカード番号やアカウント情報、第三者の閲覧を想定していないプライベートな写真や動画といった個人情報の盗難や流失、遠隔操作、DOS 攻撃の踏み台や、ページの改ざん、コンピューターの破壊など、ソフトウェアの技術を用いて悪事をなすにおいて考えうる邪悪な行為のすべてが網羅されます。

これらマルウェアの分類については、日本ネットワークセキュリティ協会(JNSA) のページにわかりやすく記載されていますので、ぜひご一読されることをお勧めします。

 

Web 感染型ウイルス

マルウェアには、「Web 感染型ウイルス」と呼ばれる Web サイトを閲覧するだけで感染するものがあり、近年ではこれを利用した「ガンブラー」というものが猛威を振るい、さまざまなところで大きな被害を出しました。

「ガンブラー」とは、ガンダムのプラモデルのことではありません。前出の「Web 感染型ウイルス」と「Web サイトの改ざん」を組み合わせて、数多くのコンピューターにウィルスを感染させようとする攻撃手法です。英語では Gumblar と書きます。

ガンブラーは特定のウィルスではないため被害状況も様々です。ニュース記事では、有名企業や政党の Web サイトの改ざんなどが話題になりましたが、それ以外にも一般ユーザーの多くがウィルスに感染しており、気づかないうちに情報を盗まれていた可能性もあります。

ガンブラーについては、情報処理推進機構 (IPA) の以下のページに概要、手口、被害、対策がよくまとめられておりますのでぜひご覧くださいませ。

マルウェアの及ぼす脅威の性質は、テロリストが家族を人質に取っておよそ実現不可能な無茶な要求を突きつける (たとえば、TVチャンピオンの大食い王決定戦に飛び入り参加して三位以内に入賞しろ、など)といったような、分かりやすいものではなく、不可知の領域でひっそりと行われる性質のため、被害を被って初めて気が付くといったことがほとんどです。

 

マルウェアの脅威から身を守るには

マルウェアからコンピューターを守るには、脆弱性をできるだけ早く解消していくことが重要です。

使用しているソフトウェアに脆弱性が残ったままではアンチウィルスソフトもそれほど有効ではありません。アンチウィルスソフトが検出できるウィルス プログラムは、パターンファイルに情報があるか、検出ロジックに合致するものだけであり、特定の脆弱性を狙ってくるすべてのウィルス プログラムを検出できるわけではないからです。

前述したとおり、Windows OS の脆弱性の解消は Windows Update によって行われます。これは Windows 本体だけでなく Edge や Internet Explorer、Office 製品なども含まれます。

これら製品”以外”のソフトウェアは個別にアップデートを行う必要があります。たとえば、Adobe さんの Flash プレイヤーには最新版やセキュリティパッチのリリースを通知し、アップデートを行う機能が搭載されていますので、こういったものを利用します(※)。
(※)こうしたインストーラーの中には、不必要なソフトウェアのインストールまで行うものもあるので、インストーラーを操作する際には十分に注意してください。

こういったソフトウェアのアップデートは可能な限り早く適用することをお勧めします、

しかしながら、企業の IT 管理者の立場からすると、これらソフトウェアのアップデートについては、管理しているシステムで検証を行い、正常動作がきちんと確認できない限りは適用できないということもあるでしょう。

しかし、Code Red のときのように、セキュリティパッチの適用を先延ばしにしたがために甚大な被害を被るということも考えられます(※)ので、セキュリティパッチの「緊急度」をご考慮のうえ充分判断していただければと思います。
(※)ちなみに Code Red 発生当時、私は別の会社で Windows 2000 Server + IIS で Web サーバーを運用していましたが、全てのサーバーにセキュリティパッチを適用していたのでなんともありませんでした。

また、サポートの終了した Windows XP 等を使用されている方は、すぐにでもサポート期間内にある OS にアップグレードすること強くお勧めします。

繰り返しになりますが、サポート期間が終了したソフトウェアを製品を使用しているということは、修理不能な穴の開いた家に住んでいるのと同じです。

Windows XP が稼働しているコンピューターを目の前にした悪意ある第三者の気持ちを、胸に七つの傷がある有名な漫画の主人公の言葉を借りて表すならば、「お前はもう、(※自主既定)でいる」といったところでしょう。

 

Web サイトを運営されている皆さまへ

冒頭で紹介しましたように、来年 (2016) の 1 月 12 日をもって、IE9 以前の Internet Explorer はサポートが終了します。

これらの Web ブラウザーは Web 標準の準拠度合も低く、HTML5 も動作しないレガシーブラウザーです。

よって、メーカーのサポート期間に準するのであれば、こうした古い Internet Explorer 向けに行ってきた特別な対応というのはしなくてもよくなるはずです。

たしかに、サポート期間が終了しても IE8 やそれ以前の IE を使用し続けるユーザーは、少ないながらいらっしゃることでしょう。

そういったユーザーの PV や広告のクリック数を失わないようにするために、いままでと変わらない品質のコンテンツを提供しなければという気持ちは理解できます。

しかし、そういった時代遅れのレガシーブラウザを手厚く保護すればするほど、ユーザーは不便を感じず、ブラウザーをバージョンアップしないままサポート期間の切れた安全でない Web ブラウザーを使い続けてしまうことでしょう。これはユーザーにとって非常にリスクの高いことです。

また、ユーザーがサポート期間の切れた Web ブラウザーを使い続けることは、Web サイト側にもリスクとなる可能性があります。

たとえば、想定外の事情により自社サイトの一部のページが、マルウェアを感染させるように改ざんされていた場合、それが古い陳腐化された攻撃の手法であったとしても、セキュリティパッチが提供されない古い IE では高い確率で被害を受けることでしょう。

つまり間接的に加害者になってしまうこともありうるのです。そういった事実があきらかになれば、Web サイトの運営にもなんらかのマイナスの影響を与える可能性があります。

 

ユーザー = たいせつなお客様のために

ここまで、Web サイトを閲覧するユーザーががサポート期間が終了した IE を使用していることについてのリスクを紹介してきましたが、もちろん、ただむやみに「サポートの切れた古い IE 向けの対応をすべきでない」と言いたいわけではありません。

ご理解いただきたいのは、サポート期間の終了した古い IE に対し、いままでと同じような品質でコンテンツが閲覧できるように精一杯の労力を注いでケアをしても、それはユーザーのためにはならないということです。

もし、自分のサイトを訪問してくださるユーザーを大切なお客様であると捉えられているならば、サポート期間が終了した IE を使用しているユーザーに対しては、ブラウザーのアブグレードを促すなんらかのメッセージを出していただければと思います。

このブログの記事でも 2016 年 1 月 12 日でサポート終了となるバージョンの Internet Explorer でアクセスすると、その旨をひかえめに教えてくれるバーを表示するスクリプトのサンプルコードを公開してしますので、よろしければぜひご利用いただければと思います。(※このページにも実装されています。)

 

まとめ

今回の記事では、サポート期間が終了した Internet Explorer を使用するとなにが危険なのか?、どう危険なのか? について紹介しました。

記事で紹介したように、コンピューターが常時インターネットにつながり、信用が担保できない不特定多数のさまざまなサイトと情報をやり取りしている現在、メーカーからのセキュリティパッチを含むアップデートを継続的に受け取れることは非常に重要です。

とくに、Web に関しては、ブラウザーそのものとは関係なく、SSLcookie といった長年使用されている技術の仕様自体に脆弱性が見つかっており、これらを個人が全て把握して対策を施すというのは現実的ではなく、そもそも、そういた労力を注いでまでサポート切れの製品を使わなければならない理由はないでしょう。

また、マルウェアやハッキングについても日々新しい手法が生み出され、それを防ぐ側とのイタチごっこが続いています。

インターネットにおける脅威というものは、宇宙空間から異星人が攻めてくる、といったような絵空事ではなく、現実に目の前存在し、今まさにお使いのコンピューターがそれを防いでいる状態のものです。

これらハッキング、マルウェア、インターネット関連の脆弱性についての情報は、一般社団法人 JPCERTコーディネーションセンター(JPCERT/CC)独立行政法人情報処理推進機構 (IPA) のページで公開されているのでぜひまめにチェックされることをお勧めします。

それから Internet Explorer のアップグレードをくれぐれもお忘れなく。

(あと、できれば Windows 10 にもね)

 

Web Statistics

Clicky


完全なる余談 : Internet Explorer の自動アップデートについて

$
0
0

最近、旧バージョンの Internet Explorer がサポート切れになるというテーマばかりで恐縮なのですが、この記事はそれらにまつわる付録と思って読んでくださいませ。

前回の記事でも(その前の記事でも)書いたとおり、来年 (2016) の 1 月 12 日からは、Internet Explorer のサポートポリシーが変更され、以下の表にあるとおり、その Windows 上で動作する最も高いバージョンの Internet Explorer しかサポートされなくなります。

Windows Internet Explorer 延長サポート終了
Windows Vista SP2 Internet Explorer 9 2017年 4 月 11 日
Windows Server 2008 SP2 2020年 1 月 14 日
Windows 7 SP1 Internet Explorer 11
Windows Server 2008 R2 SP1
Windows 8.0 Internet Explorer 10 2023年 1 月 10 日
Windows Server 2012
Windows 8.1 Internet Explorer 11
Windows Server 2012 R2
Windows 10 (最低でも10年)

(2016年1月12日以降、サポートされる
Windows と Internet Explorer の組み合わせ)

 

上記の表の青字の部分については、OS 既定の Internet Explorer のバージョンではないため Windows 8 以前のお使いの方は Internet Explorer をアップグレードする必要が出てくる可能性があります。

ここまでを読んで、Windows に詳しい方であれば、「Internet Explorer って、途中から自動アップグレードになったんじゃなかったんだっけなァ?」と思われる方もいることでしょう。

そのとおりです。自動アップグレードの仕組みがあるにもかかわらず、さまざまニュース記事でいまだに Internet Explorer 8 のシェアがそこそこ残っていることや、Web サイトを運営されている方々から「IE8 使ってる人、まだけっこういるんですよねぇ」と言くたびに 21世紀を迎えて 15 年を経た今でもこんなミステリーが残っていたのか! とただただ驚くばかりです。

ちなみに StatCounter によれば 2015 年 9 月の日本における Internet Explorer のシェアは 1.83% のようです。(画像をクリックすると実際にグラフにアクセスできます)

StatCounter-browser_version-JP-monthly-201409-201509 (1)

いっぼう、ニュース記事などによると、Net Applications の発表では 2015 年 9 月の Internet Explorer 8 のシェアは 11.71% もあるとのことです。しかし、どこの地域のデータなのか記載されていないので日本ではなくワールドワイドでデータの可能性があります。

こういったデータは、抽出するソースによって結果が変わってきますので、Web コンテンツ作成の際にレガシーブラウザー対応をするかしないか判断するにおいては、自分の Web サイトの実際のデータをしっかり確認することをお勧めします。

 

Internet Explorer の自動アップグレードとはなんだったのか?

Internet Explorer の自動アップグレードとは、Windows Update を使用して Internet Explorer を自動的に最新のバージョンにアップグレードする機能です。

2011 年 12月 16 日、 今はなき Exploring IE ブログ にて全世界の Windows XP、Windows Vista、Windows 7 に対し、それぞれの Windows がサポートする最新の Internet Explorer への自動アップグレードを開始する旨が発表されました。

Internet Explorer の自動アップグレードは全世界において 1 月中旬から地域別に段階的に実行され、日本では 3 月中旬より対象の Windows に対し、順次自動アップグレードが適用されました。

しかし、この自動アップグレードが適用されないケースもありました。

 

Internet Explorer の自動アップグレードがされない理由

Internet Explorer の自動アップグレードの対象は、Windows Vista の場合は SP2 から、Windows 7 は SP1 からであるため、それらサービスパックをインストールしていない場合は Internet Explorer が古いままの可能性があります。

Blocker Tookit や管理ソリューションで管理されていたり、以前の自動更新の際に新しいバージョンの Internet Explorer のインストールを拒否されていた場合も自動アップグレードは行われません。

つまり、いまだに Internet Explore 7 や 8 を使い続けている方は、これらのいづれかのケースに当てはまっていると考えられます。

これらに該当する方々は Internet Explorer のアップグレードを手動で行う必要がありますが、手動といってもむつかしいことはありません。Internet Explorer のダウンロードサイトからインストーラーをダウンロードして実行するだけです。

ただし、お使いの Windows Vista および Windows 7 に必要なサービスパック (SP) がインストールされていないと新しい Internet Explorer をインストールすることはできません。とくに Windows Vista の SP2 は、公開された時期の関係で、SP2 が適用済の単体パッケージは存在しませんので、理屈からいえばかならず SP2 を適用する必要があります。これらサービスパックの適用は、メーカーからサポートを受けるための条件にもなっていますので、ぜひ適用してください。

企業などの、管理された IT 環境によって古いバージョンの Internet Explorer の使用を義務付けられている、というわけでもなく、ただなんとなく旧バージョンの Internet Explorer をご使用になられている方は、ぜひここで一度、胸に手をあてて、「なぜ自分は、時代遅れで性能も低くHTML5 も動作しないうえに、とくに他人への自慢のタネになると思えない古い Internet Explorer をいまだに使い続けているのか?」について冷静に考えていただきたいところです。(さらにもうひとつ、申し加えるなら、ただ単に古いだけのものに Vintage としての価値はありませんよ、ということです)

とくに理由が見つからないようであれば、ここはぜひ、速やかに最新に Internet Explorer か Windows 10 へのアップグレードをお願いいたします。

 

Window 10 における Edge と Internet Explorer 11 のアップデート

Windows 10 でも Edge や Internet Explorer 11 のアップデートは Windows Update により行われます。

ただし、Edge はたゆまない機能追加が行われますが、Internet Explorer 11 は不具合の修正やセキュリティ情報の更新くらいで、今後機能が追加されたり不具合以外での仕様変更もありません。

これら Windows Update の設定は、スタートボタン – [設定] – [更新とセキュリティ] メニューを選択することで表示される、[選択]ダイアログボックスの [Windows Update] タブで行います。

同タブ内の [詳細オプション] リンクをクリックすると、

image

Windows Update に関する詳細オプションを設定する画面が表示され、アップデートがかかったさいに必要となる再起動の日時が指定できたり、エディションによっては Window 10 の新しい機能がリリースされた際のアップグレードを延期することができます。

image

Windows Update で提供される既定のアップデートは、Current Branch と呼ばれ、セキュリティパッチや更新プログラム(機能追加やバグフィックス)が含まれています。

そして Windows 10 Pro 以上のエディションでは、企業内の管理された IT 環境などで、アップデートに対する検証作業にかかる期間の余裕を持たせる目的で、アップデートの適用をある期間延期する Current Branch for Business (CBB) という機能が搭載されています。

さらに Windows 10 Enterprise では、なにか特定の目的に固定されて使用されるような、環境のクリーンさが重要視されるシステム向けに、一切の機能追加を行わず、セキュリティパッチやバグフィックスのみを適用する Long Term Servicing Branch(LTSB) が用意されています。

マイクロソフトが推奨するアップデートは、既定の設定であるアップデートをいち早く適用する Current Branch  ですが、エンタープライズ環境向けに、上記のような Current Branch for Business や Long Term Servicing Branch といった機能が用意されています。

これらのエンタープライズ環境向けの機能につきましては、以下のドキュメントをご参照くださいませ。

最後に、Windows 10 の更新は、上記のような機能を使用して延期することは可能ですが、アップデートを適用しない、という選択はできません。

いつかはかならずアップデートが適用されますので、速やかなアップデート、事前の検証が必要な場合には速やかな検証をお願いいたします。

 

まとめ

今回の記事では Internet Explorer の自動アップグレードについて紹介しました。

じつはこの内容は、前回の記事「なぜサポートが終了した Web ブラウザーを使うと危険なのか?」の一部となる予定だったのですが、冗長になりそうだったのとテーマから外れているのでカットした部分になります。

Windows 10 がリリースされたあと、いまさら Internet Explorer の自動アップグレードを紹介しても….、とは思いましたが、せっかく書いたので投稿してみました。

なにかのお役に立てれば幸いです。

Web Statistics

Clicky

ドキュメント『モダンブラウザーの今と、Web標準に対応したWebコンテンツの作り方』公開!

$
0
0

Windows 10 がリリースされて以来、わたくしエバンジェリスト 物江と、元・エバンジェリスト春日井(現・Windows プロダクトマネージャー) が、セミナーなどで紹介してきましたWindows 10 に搭載される Web ブラウザーについての内容をドキュメント (pdf) としてまとめました。

これまで発信してきました Edge と Internet Explorer についての情報の集大成ともいえる内容です。

EdgeIE

“Windows 10 から搭載された新しい Web ブラウザー Microsoft Edge とはなんなのか?”

“これまで Windows の Web を支えてきた  Internet Explorer は
いったいどうなってしまったのか?“

“Edge 対応した Web コンテンツとは?”

Windows 10 に搭載される新旧 2 つの Web ブラウザーについての疑問と謎、そして不思議、そのすべてについての答えが、このドキュメントに記述されている、
かもしれません。

すでに Windows 10 をお使いの人も、これからお使いになる人も、使う予定はないけれどなんとなく興味がある人も、興味はないけれど仕事で必要な人も、ぜひお手に取ってご覧ください。

ダウンロードはこちらから↓

[Web 制作者必見!] モダンブラウザーの今と、Web標準に対応したWebコンテンツの作り方
~Microsoft EdgeとInternet Explorer 11がもたらす業務改善~

職場での話題、ご家族の団らん、お友達との会話にぜひご活用いただければと思います。

 

Web Statistics

Clicky

これからどうする? モダン Web とCSS ベンダープレフィックス

$
0
0

これらのバージョンの Internet Explorer は、Web 標準にもそれほど準拠しておらず、HTML5 もサポートしない、いわゆるレガシーブラウザと呼ばれるものです。

Mozilla Firefox や Google Chrome といった他の Web ブラウザーは、自動更新によりアップデートされていく仕組みとなっており(※)、基本的にはレガシーなバージョンは存在しないので、いままでレガシーブラウザと言えば、これら旧バージョンの Internet Explorer のことを指していました。
(※いちおう、Internet Explorer にも自動更新の仕組みは導入されていました)

上記のような状況につき、誤解を恐れずに言えば、来月中旬以降、レガシーブラウザをサポートする必要はなくなります。

レガシーブラウザをサポートする必要がなくなれば、いままで当たり前のように行っていた、互換性確保のための IE ハックやポリフィル (Polyfill) といった作業は必要なくなり、Web コンテンツの品質を上げるためのより本質的な作業に注力することができます。

こういったレガシーブラウザ向けの対応以外でも、今現在は当たり前に使用されているものの、すでに役割を終えつつあるものがあります。

そのひとつが CSS ベンダープレフィックスです。

 

CSS ベンダープレフィックスとは

CSS ベンダープレフィックスは、まだ HTML5 の仕様が草案状態だった時代に、同じく草案状態であった CSS3 のプロパティを記述する際に使用した、実際の指定の前につける –moz- や –webkit といった接頭辞のことをいいます。

これらベンダープレフィックスは、その指定が、各ベンダー独自の拡張であることを示すために付けられました。

ベンダープレフィックスが付加された設定によって実行される機能は、ブラウザーベンダーが、実験用としてブラウザーに早期実装したものであり、扱いとしては各ブラウザーの独自(拡張)機能ということになります。

つまり、そもそもが、仕様が定まっていないものを早期に実装して検証すための「お試し用」のものなので、ブラウザーベンダーの意図を正しく理解しているのであれば、HTML5 の勧告が済んでなお、使用し続けるべきものではないといえるでしょう。

W3C でも、CSS3 の仕様が草案(Working Draft) から勧告候補 (Candidate Recommendation)になった際には、ベンダープレフィックスを外すことが推奨されていました。

にもかかわらず、今現在、ベンダープレフィックスは当たり前のように使用され、場合によっては、さも相互運用性を高めるかのような説明がされている場合もありますがそれは正しくありません。

たしかに、ベンダープレフィックスを使用しても、今現在、Web ブラウザーは CSS3 の指定と同様の描画を行います。しかしそれは、あくまでも CSS3 の指定に似た Web ブラウザーの独自機能を使用しているのであり Web 標準に準拠した CSS3 を使用していることにはなりません。

 

CSS ベンダープレフィックスを使用し続けることの懸念

ベンダープレフィックスを使用し続けることの懸念点は、ベンダープレフィックスがブラウザーベンダーの独自の拡張機能であるために、いつまでサポートされるかわからないということです。

実際のところ、Firefox は Firefox 13 の時代に「-moz-border-radius」や「-moz-box-shadow」といった設定のサポートを終了しています。

つまり、ベンダープレフィックスのそもそもの意味を正しく理解せず、あたかも Web 標準に従った機能のごとく曲解して使用し続けていると、Web ブラウザーがベンダープレフィックスのサポートを終了した際には一気に大がかりな修正を行う必要に迫られる可能性があります。

こういった状況を避けるには、かならず最後にベンダープレフィックスを使用しないプロパティを書くようにします。

たとえば以下の例では、最後にベンダープレフィックスのない border-radius: 8px; を指定していますが、この指定がないと現在の Firefox では border-radius は適用されません。

-o-border-radius: 8px;
-ms-border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;

ただし、上記の設定も現在ではひどく無駄の多いものといえます。

なぜならば、現在の Web ブラザーは標準的な CSS3 の設定をサポートしているので、ベンダープレフィックスの付いている部分は完全に無駄になります。

これらの無駄な設定は Web ブラウザーの動作自体には影響を及ぼしませんが、データ量は膨らみます。とくに従量課金制であったり、パケット量の上限設定のある通信環境を使用するモバイル機器を使用するユーザーには、そのまま金銭的コストとして跳ね返ってきます。

 

CSS ベンダープレフィックスと相互運用性

今現在でも CSS ベンダープレフィックスが必要な指定はわずかながら存在します。

しかしながら、以下のリンク先の表にあるように、現在ベンダープレフィックスを必要とするような設定は、その他のほとんどの Web ブラウザーがサポートしていないので、相互運用性をきちんと考えるのであればそういった設定の使用は避けるべきでしょう。

Can I use... Support tables for HTML5, CSS3, etc

 

Web サイトの CSS ベンダープレフィックス設定をチェックできるツール

Microsoft Edge Dev のサイトにある SiteScan を使用すると、Web ブラウザーの相互運用性について、その他の意識すべき点と併せて CSS ベンダープレフィックスの設定チェックも行われるのでぜひお試しください。

Browser Testing Report: Browser Test & Performance Testing : Microsoft Edge Dev

以下のように検出されます。(クリックすると拡大した図がご覧になれます)

image

まとめ

前述したとおり、現在の Web ブラウザーは標準的な CSS3 の設定はサポートしており、ベンダープレフィックスは必要ありません。

また、Internet Explorer 以外の Web ブラウザーは自動更新によりビルドがアップデートされるため、更新の失敗や、意図的な設定がされている特殊な例を除いてはベンダープレフィックスを必要とするものはほとんど残っていないと考えられます。

ベンダープレフィックスはいつまでサポートされるのか?、そういった不確定な要素を排除し、ユーザーのパケットを無駄に消費しないためにもベンダープレフィックスを取り外すことをお勧めします。

(そういえば先日「Sass 使用しているので自動でベンダープレフィックスがつく」という人がおりましたが、そういう方は一緒に Compass や Autoprefixer などを使用していないか確認してくださいませ)

また、”ベンダープレフィックスを外すのはまだちょっとこわいな~”という人は、忘れずにベンダープレフィックスのない設定(プロパティ)を追加するようにしてください。

 

Web Statistics

 

Web ブラウザーや OS のシェアが確認できる Web サービスまとめ

$
0
0

ちなみに Windows 10 のダウンロード数とか Microsoft ID の数だとかについては。マイクロソフトの公式ページである Microsoft by the Numbers で公開されていますので、マイクロソフトについてのなんらかの数字を調べたい場合には、まずはこちらをご覧になるのが良ろしいでしょう。

image
(Microsoft by the Numbers)

 

シェアの情報を参照する前に

インターネットでは、ニュース記事をはじめさまざまな製品のシェアについての情報が公開されていますが、まず意識すべきことはその情報のソースはどこで、どのような方法で、どのくらいの数から抽出したものであるか、ということでしょう。

たとえば、100人程度の小規模なメーリングリストのアンケートと、有名検索エンジンの実際のトラフィックやアクセス解析サービスの統計情報から抽出されるデータでは、精度も質も異なります。

また、国や地域によっても標本サイズや、そもそもの傾向そのものなどが大きく異なる場合かあるので、そのデータがワールドワイドのものなのか、特定の地域のものであるかを意識したほうが良いでしょう。たとえば、StatCounter によれば、2015 年 12 月の Internet Explorer 11 のシェアは、ワールドワイドでは 10.20% ですが、日本では 24.77% と 2 倍以上の違いがあります。

また、調査対象がインターネットなのか、イントラネットなのか、によっても大きな違いが出ることでしょう。

いずれにしろ参照するシェアの調査方法が、利用目的に合っているかどうかを常に意識したいところです。

ちなみに Wikipedia には Web ブラウザーのシェアの調査方法について(古い情報が混じっているものの)非常に詳しい解説がされているので一読することをお勧めします。

 

Web ブラウザーや OS のシェアが確認できる Web サービス

インターネットから特別な登録なしに Web ブラウザーや OS のシェアが確認できる Web サービスをいくつか紹介します。

StatCounter

StatCounter は、Web サイトのトラフィックやユーザーの行動を分析するためのアクセス解析を行うためのサービスを提供しており、そのサービスを利用する300万を超える Web サイトからの統計情報から Web ブラウザーや OS のシェアを抽出します。

国別、ブラウザーのバージョン、モバイル/デスクトップ/タブレットなど、他の無料サービスと比較して細かな条件設定が行えます。

image
(StatCounter GlobalStats の画面)

 

Clicky.com

Clicky.com は StatCounter と同様に、Web のアクセス解析を行うサービスを提供しており、ブラウザーや OS のシェアについての情報は、同サービス Clicky Web Analytics を利用する 50万 を超える Web サイトの約 5 億ページからのデータを利用しているとのことです。

国別のデータの表示は可能ですが、残念ながらブラウザーバージョン指定などはできないようです。

image
(Web browsers (Global marketshare)の画面 )

W3Counter

W3Counter も前出の 2 つと同じようにWeb のアクセス解析を行うサービスを提供しており、同サービスを利用する 37,120 (2015 年 12 月 時点) の Web サイトからの情報をから OS や Web ブラウザーのシェアの情報を抽出しています。

image
(W3Counter: Global Web Stats の画面)

右上の View Monthly Trends リンクをクリックするとシェアのトレンドを折れ線グラフで表示することができます。

 

NetMarketShare

NetMarketShare もWeb のアクセス解析を行うサービス MarketShare を提供しており、同サービスのデータから OS や Web ブラウザーのシェアを抽出しています。基本機能以外は有償となってしまいますが、他の同様のサービスよりも、より詳細なな条件設定ができるのが特徴であり、ニュースサイトの記事などでもたびたび引用されています

image
(Browser market share の画面)

まとめ

今回の記事で紹介したとおり、Web ブラウザーのシェアの情報を公開しているサイトは、Web サイトのアクセス解析サービスを提供している会社が、そこで得られる統計情報を利用しているものがほとんど(※)です。
(※)今回はとくに紹介しませんでしたが、Wikipedia や Wikinews などのプロジェクトを管理している Wikimedia が、提供するサービスへのトラフィックから抽出したデータを公開していたりもします。

つまり、これらが示すデータは、Web 全体をカバーしているわけではなく、あくまでも「傾向」であるということを意識する必要かあります。さらにいうのであれば、今現在、世界的なレベルでのブラウザーのシェアを測定する完全な方法はありません。

実際のところ Web サイト (アプリ) を分析するサービスを提供する wappalyzer.com で、サイトが使用している Analytics ツールのシェアを確認すると、Google Analytics が 68% でダントツで使用されている(2016/01/05 現在)のに対し、この記事で紹介しているサービスでもっとも使用率の高い StatCounter であっても 1 % にすぎません。

では、 この記事で紹介しているサービスではもっとも使用されている StatCounter の情報の精度が高いのかといえば、データの取得方法や、抽出方法によっても変わってくるのでなんとも言えないところがあります。たとえば、ユニークユーザーから情報を取得するのとページビューから情報を取得するのでは、結果に大きな違いが出てきます。(ちなみに StatCounter はページビューで、NetMarketShare はユニークユーザーで見ていると言われていますが、今回それを記載してある箇所を見つけることはそれぞれのサイトにおいてできませんでした)

この辺の内容については、以下の記事で議論されていますので興味があればご覧くださいませ。

2016/01/06 追記 : 上のブログ記事「Understanding Browser Usage Share Data」の内容を簡単に紹介してほしい、というリクエストがあったので紹介します。
同ブログ記事では、Chrome v13 で搭載されたプレレンダー(事前描画、コンテンツの先読み) 機能によってブラウザーシェアに影響が出た件を例に挙げ、StatCounter と NetMarketShare で表示されるデータの違いと、それぞれのデータの抽出(生成も?)方法について詳しく述べられています。

これから Web コンテンツを作成するにおいてブラウザーのシェアを参考にするのであれば、自社で運用している Web サーバーのログからぜひ自サイトにアクセスするブラウザーのシェアを抽出してみることをお勧めします。その際はかならず、ユニークユーザーで行うようにしてください。

なぜならば、ページビューで判断してしまうと、特定のユーザーがテストツールなどで大量のリクエストを投げたりすると、「シェア」という意味での正しいデータが取得できないためです。

Web Statistics

Clicky

HTML5 を使ったシンプルな 2 D ゲームの作り方(効果音を鳴らす)

$
0
0

このシリーズまだやってたの!?、と声が聞こえてきそうなくらい前回から間が空いてしまいましたが約半年ぶりに HTML5 を使用したシンプルな 2D ゲームの作り方の第 10  回めをお送りします。

どんなゲームを作るのかは 1 回目の記事の中に実際に動作するゲームが埋め込んであるのでぜひ遊んでみてください。なお、開発に必要な画像データは 2 回目の記事からダウンロードできますので、実際にゲーム開発を体験したい方はそちらから入手してください。

  1. HTML5 を使ったシンプルな 2 D ゲームの作り方(序)
  2. HTML5 を使ったシンプルな 2 D ゲームの作り方(準備編)
  3. HTML5 を使ったシンプルな 2 D ゲームの作り方 (画像のロード)
  4. HTML5 を使ったシンプルな 2 D ゲームの作り方 (アニメーションの実装)
  5. HTML5 を使ったシンプルな 2 D ゲームの作り方 (矢印キーとタッチによる制御の実装)
  6. HTML5 を使ったシンプルな 2 D ゲームの作り方 (当たり判定の実装)
  7. HTML5 を使ったシンプルな 2 D ゲームの作り方 (複数のSpriteの生成)
  8. HTML5 を使ったシンプルな 2 D ゲームの作り方 (ランダムな動作と FPS の制御)
  9. HTML5 を使ったシンプルな 2 D ゲームの作り方(スプライトを使った画像の切り替え)

前回までの記事で、1. 入力装置からのプレイヤーの操作2. 複数のターゲットの生成とランダムな動作3.当たり判定、4. スプライト(キャラクター)の変更といったおおよそアクションゲームに必要な機能の実装が完了しました。

今回は当たり判定時の効果の追加ということで、雪だるまと雪の結晶がヒットした際に音を出すようにしたいと思います。

 

HTML5 を使用したオーディオファイルの再生

HTML5 ファイルで MP3 などのオーディオファイルを再生する方法はいくつかありますが、単に再生するだけであれば Audio オブジェクトを使用するのが簡単です。わざわざ audio タグを記述しなくても以下のような JavaScript でオーディオファイルを再生することができます。

var audioObj = new Audio(‘your_audio_file_url.mp3’);
audioObj.play();

 

HTML5 の Audio オブジェクトのより詳しい使い方については以下のドキュメントを参照してください。

 

オーディオファイルの入手と配置

使用するオーディオファイルは以下の OneDrive のシェアから snow_game_audio.zip をダウンロードしてください。

snow_game_audio.zip を解凍すると audio という名前のフォルダが出てくるので、これを Visual Stuio のソリューションエクスプローラーにドラッグドロップして追加します。

以下のようになれば配置は完了です。

image

コードの追加

雪の結晶に雪だるまが当たった際に音を鳴らすだけなので、当たり判定処理の中に前述のコード記述すれば良いと思われるかもしれませんが、そう簡単ではありません。

例えば、雪の結晶は複数あるので、それらに同時にぶつかった際にはそれぞれに音を出す必要があります。

また、ゲームの処理はすべてアニメーションのためのフレーム(繰り返し処理)の中で動作しているため、そのまま単に音を鳴らす処理を記述しただけでは同じ処理が何度も繰り返されることになるので、それを防ぐための処理を実装する必要があります。

ここからは、前回までのコードにそういった点を考慮した実装を行っていきます。

 

Sprite クラスへの Audio プロパティの追加

ゲーム画面内で動作する Sprite (キャラクター) のクラス(※)に Audio オブジェクトのインスタンスを格納するためのプロパティと、フレーム処理の中でオーディオの繰り返し再生を避けるためのプロパティを定義します。
(※厳密にいうと JavaScript に”クラス”は無いので”関数”なのですが、理解しやすさを優先してこう呼びます。)

具体的には以下のように Sprite クラスを定義しているコードの、プロパティとして外部変数を定義している箇所に、Audio オブジェクトのインスタンスを格納するための変数 audio と 繰り返し再生を避けるために再生済みを示すフラグ audioPlayed を定義します。

//Sprite クラスの定義
   var Sprite = function (img, width, height) {
       this.image = img; //image オブジェクト
       this.height = img.height;
       this.width = img.width;
       this.x = 0;   //表示位置 x
       this.y = 0;  //表示位置 y
       this.dx = 0; //移動量 x
       this.dy = 0; //移動量 y
       this.audio = null; //Audio オブジェクト
       this.audioPlayed = false; //音が複数回鳴るのを防ぐ
       var _offset_x_pos = 0;
       var that = this;
~ 略 ~

 

Audio オブジェクトのインスタンス生成と格納

雪の結晶用の Sprite クラスのインスタンスが生成されるタイミングで Audio オブジェクトのインスタンス生成してプロパティに格納します。

個別の Sprite クラスに Audio オブジェクトを持たせるのはそれぞれに独立した再生を行わせるためです。

具体的なコードの追加箇所は loadAssets 関数内で img_snow オブジェクトの onload イベントハンドラを定義している以下の箇所です。

function loadAssets() {
    //HTML ファイル上の canvas エレメントのインスタンスを取得  
    canvas = document.getElementById(‘bg’);
    //アニメーションの開始
    canvas.addEventListener(“click”, loadCheck);
    //2D コンテキストを取得 
    ctx = canvas.getContext(‘2d’); 
    //image オブジェクトのインスタンスを生成 
    img_snow = new Image(); 
    //image オブジェクトに画像をロード 
    img_snow.src = ‘/img/sp_snow.png';

    /*画像読み込み完了のイベントハンドラーに Canvas に 
       画像を表示するメソッドを記述 */ 
    img_snow.onload = function () {
        for (var i = 0; i < SNOWS_COUNT; i++) {
            var sprite_snow = new Sprite(img_snow, SNOW_PIC_WIDTH, SNOW_PIC_HEIGHT);
            sprite_snow.dy = 1;
            sprite_snow.dx = NEIGHBOR_DISTANCE;
            sprite_snow.x = i * sprite_snow.dx;
            sprite_snow.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
            //Audio オブジェクトのインスタンスをセット
            sprite_snow.audio = new Audio(“audio/kiiiin1.mp3″);
            snow_sprites.push(sprite_snow);
            sprite_snow = null;
        }
};

 

オーディオ オブジェクトの再生

雪の結晶の Sprite オブジェクトの audio プロパティに設定されたオーディオ オブジェクトを再生します。

これは単に当たり判定の処理である isHit 関数内で play メソッドを実行し、フレーム処理による繰り返し再生を避けるためのフラグである audioPlayed プロパティを true に設定する処理と if 文を記述するだけです。

具体的には以下のような記述となります。

//当たり判定
function isHit(targetA, targetB) {
    if ((targetA.x <= targetB.x && targetA.width + targetA.x >= targetB.x)
            || (targetA.x >= targetB.x && targetB.x + targetB.width >= targetA.x)) {

        if ((targetA.y <= targetB.y && targetA.height + targetA.y >= targetB.y)
            || (targetA.y >= targetB.y && targetB.y + targetB.height >= targetA.y)) {
            ctx.font = “bold 20px ‘MS ゴシック'”;
            ctx.fillStyle = “red”;
            ctx.fillText(“ヒットしました”, getCenterPostion(canvas.clientWidth, 140), 160);
            targetA.imageIndex = SNOW_CLASH;
             //衝突音を鳴らす
          if (!targetA.audioPlayed) {
                targetA.audio.play();
                targetA.audioPlayed = true;

            }
        }
    }
}

 

再生済みフラグのリセットと再生の終了

雪の結晶が画面から消え、表示位置をリセットするタイミングで再生済みフラグである audioPlayed プロパティを fase に変更します。

また同時に、今回は再生時間の短いオーディオファイルであるためあまり必要ないのですが、再生を停止するための pause メソッドを実行します。

これらの処理はフレーム毎に呼び出される renderFrame 関数内に以下のように記述します。

function renderFrame() {
    if (timeKeeper.nextFrameJob()) {
        //canvas をクリア
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //sprite_snow_man の x 値が動作範囲内かどうか
        if ((sprite_snow_man.x < sprite_snow_man.limit_rightPosition && key_value > 0)
            || (sprite_snow_man.x >= 3 && key_value < 0)) {
            //img_snow_man の x 値を増分
            sprite_snow_man.x += key_value;
        }

        var length = snow_sprites.length;
        for (var i = 0; i < length; i++) {
            var snow_sprite = snow_sprites[i];
            //snow_sprite の y 値(縦位置) が canvas からはみ出たら先頭に戻す
            if (snow_sprite.y > canvas.clientHeight) {
                snow_sprite.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                snow_sprite.imageIndex = SNOW_BLUE;
                //オーディオ再生を停止
                snow_sprite.audio.pause();
                //オーディオ再生済フラグのリセット
                snow_sprite.audioPlayed = false;
            }else {
                if (loopCounter == SWITCH_PICTURE_COUNT 
                    && snow_sprite.imageIndex != SNOW_CLASH) {
                        snow_sprite.imageIndex = (snow_sprite.imageIndex == SNOW_BLUE)
                        ? SNOW_WHITE : SNOW_BLUE;
                } 
            };
                
            //snow_sprite の y 値を増分
            snow_sprite.y += snow_sprite.dy;
            //画像を描画
            snow_sprite.draw();

            //当たり判定
            isHit(snow_sprite, sprite_snow_man);
                snow_sprite = null;
            }
            //画像を描画
            sprite_snow_man.draw();

            //処理数のカウント
            if (loopCounter == SWITCH_PICTURE_COUNT) { loopCounter = 0; }
            loopCounter++;

            window.requestAnimationFrame(renderFrame);
        } else {
            window.requestAnimationFrame(renderFrame);
        }
    }

 

ここまでの作業で、雪の結晶が雪だるまに衝突した際に音ができるようになりました。

以下の黒いボックスをクリックして、実際の動作を確認してください。(矢印キー[←][→]で雪だるまが左右に移動します。スマートフォンの場合はタッチで操作が可能です)

 

今回作業を行った main.js 全体のコードは以下のとおりです。

(function () {
    //矢印キーのコード
    var LEFT_KEY_CODE = 37;
    var RIGHT_KEY_CODE = 39;
    var key_value = 0;

    //全体で使用する変数
    var canvas = null;
    var ctx = null;
    var img_snow = null;
    var img_snow_man = null;

    //画面の書き換え数をカウントする
    var loopCounter = 0;

    //雪の結晶画像を切り替える閾値
    const SWITCH_PICTURE_COUNT = 24;

    //1 秒間に実行されるフレーム数
    const GAME_FPS = 48;

    //表示する雪の結晶の数
    const SNOWS_COUNT = 6;

    //移動開始位置を得るための係数
    const SNOW_START_COEFFICIENT = -50;

    //隣り合う 雪の結晶画像の x 位置の差分
    const NEIGHBOR_DISTANCE = 58;

    //雪だるまの Sprite のインスタンスを格納する配列 
    var sprite_snow_man = null;

    //雪の Sprite のインスタンスを格納する配列 
    var snow_sprites = [];

    //スプライト画像のインデックス
    const SNOW_BLUE = 0;
    const SNOW_WHITE = 1;
    const SNOW_CLASH = 2;

    //雪の結晶の画像サイズ
    const SNOW_PIC_HEIGHT = 32;
    const SNOW_PIC_WIDTH = 32;

    //雪ダルマの画像サイズ
    const SNOW_MAN_PIC_HEIGHT = 80;
    const SNOW_MAN_PIC_WIDTH = 80;

    //Sprite クラスの定義
    var Sprite = function (img, width, height) {
        this.image = img; //image オブジェクト
        this.height = img.height;
        this.width = img.width;
        this.x = 0;   //表示位置 x
        this.y = 0;  //表示位置 y
        this.dx = 0; //移動量 x
        this.dy = 0; //移動量 y
        this.audio = null; //Audio オブジェクト
        this.audioPlayed = false; //音が複数回鳴るのを防ぐ
        var _offset_x_pos = 0;
        var that = this;

        //使用するインデックスを設定するための Setter/Getter
        var _imageIndex = 0;
        Object.defineProperty(this, “imageIndex”, {
            get: function () {
                return _imageIndex;
            },
            set: function (val) {
                _imageIndex = val;
                _offset_x_pos = width * _imageIndex;
            }
        });

        //Sprite を描画するメソッド
        this.draw = function () {
            ctx.drawImage(img, _offset_x_pos, 0, width, height, that.x, that.y, width, height);
        };
    }

    //FPS をコントロールするための timeKeeper クラス
    function TimeKeeper(frameCount) {
        var bofore_animation_time = 0;
        var frameInterval = (600 / frameCount);
        //window.performance オブジェクトに対応していないブラウザへの対応
        var getNow = (window.performance.now) ?
            function () { return window.performance.now(); }
            : function () { return (new Date()).getTime(); }
        //FPS として指定したフレームごとの時間が経過したら true を返す
        this.nextFrameJob = function () {
            var now_the_time = getNow();
            var renderFlag = !(((now_the_time – bofore_animation_time) < frameInterval)
                && bofore_animation_time);
            if (renderFlag) bofore_animation_time = now_the_time;
            return renderFlag;
        };
    }

    //TimeKeeper クラスのインスタンスを格納
    var timeKeeper = new TimeKeeper(GAME_FPS);

    //DOM のロードが完了したら実行
    document.addEventListener(“DOMContentLoaded”, function () {
        loadAssets();
        setHandlers();
    });

    function setHandlers() {
        //キーイベントの取得 (キーダウン)
        document.addEventListener(“keydown”, function (evnt) {
            if (evnt.which == LEFT_KEY_CODE) {
                key_value = -3;
            } else if (evnt.which == RIGHT_KEY_CODE) {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 キーが上がったら 0 に
        document.addEventListener(“keyup”, function () {
            key_value = 0;
        });

        //Canvas へのタッチイベント設定
        canvas.addEventListener(“touchstart”, function (evnt) {
            if ((canvas.clientWidth / 2) > evnt.touches[0].clientX) {
                key_value = -3;
            } else {
                key_value = 3;
            }
        });

        //雪だるまが進みっぱなしにならないように、 タッチが完了したら 0 に
        canvas.addEventListener(“touchend”, function (evnt) {
            key_value = 0;
        });
    }

    function loadAssets() {
        //HTML ファイル上の canvas エレメントのインスタンスを取得 
        canvas = document.getElementById(‘bg’);
        //アニメーションの開始
        canvas.addEventListener(“click”, loadCheck);
        //2D コンテキストを取得
        ctx = canvas.getContext(‘2d’);
        //image オブジェクトのインスタンスを生成
        img_snow = new Image();
        //image オブジェクトに画像をロード
        img_snow.src = ‘/img/sp_snow.png';

        /*画像読み込み完了のイベントハンドラーに Canvas に
           画像を表示するメソッドを記述 */
        img_snow.onload = function () {
            for (var i = 0; i < SNOWS_COUNT; i++) {
                var sprite_snow = new Sprite(img_snow, SNOW_PIC_WIDTH, SNOW_PIC_HEIGHT);
                sprite_snow.dy = 1;
                sprite_snow.dx = NEIGHBOR_DISTANCE;
                sprite_snow.x = i * sprite_snow.dx;
                sprite_snow.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                //Audio オブジェクトのインスタンスをセット
                sprite_snow.audio = new Audio(“audio/kiiiin1.mp3″);
                snow_sprites.push(sprite_snow);
                sprite_snow = null;
            }
        };
       
        //雪だるま画像のロード
        img_snow_man = new Image();
        img_snow_man.src = ‘/img/snow_man.png';
        img_snow_man.onload = function () {
            sprite_snow_man = new Sprite(img_snow_man, 
                                                       SNOW_MAN_PIC_WIDTH, SNOW_MAN_PIC_HEIGHT);
            sprite_snow_man.x = getCenterPostion(canvas.clientWidth, img_snow_man.width);
            sprite_snow_man.y = canvas.clientHeight – img_snow_man.height;
            sprite_snow_man.limit_rightPosition = getRightLimitPosition(canvas.clientWidth, 
                                                                                      img_snow_man.width);
        };
    };

    //ゲームで使用する Splite オブジェクトが準備されたかどうかを判断
    function loadCheck() {
        if (snow_sprites.length && sprite_snow_man) {
            //準備ができたらアニメーションを開始
            window.requestAnimationFrame(renderFrame);
        } else {
            //まだの場合はループして待機
            window.requestAnimationFrame(loadCheck);
        }
    }

    function renderFrame() {
        if (timeKeeper.nextFrameJob()) {
            //canvas をクリア
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            //sprite_snow_man の x 値が動作範囲内かどうか
            if ((sprite_snow_man.x < sprite_snow_man.limit_rightPosition && key_value > 0)
             || (sprite_snow_man.x >= 3 && key_value < 0)) {
                //img_snow_man の x 値を増分
                sprite_snow_man.x += key_value;
            }

            var length = snow_sprites.length;
            for (var i = 0; i < length; i++) {
                var snow_sprite = snow_sprites[i];
                //snow_sprite の y 値(縦位置) が canvas からはみ出たら先頭に戻す
                if (snow_sprite.y > canvas.clientHeight) {
                    snow_sprite.y = getRandomPosition(SNOWS_COUNT, SNOW_START_COEFFICIENT);
                    snow_sprite.imageIndex = SNOW_BLUE;
                    //オーディオ再生の終了
                    snow_sprite.audio.pause();
                    //オーディオ再生済フラグのリセット
                    snow_sprite.audioPlayed = false;
                }else {
                    if (loopCounter == SWITCH_PICTURE_COUNT
                        && snow_sprite.imageIndex != SNOW_CLASH) {
                            snow_sprite.imageIndex = (snow_sprite.imageIndex == SNOW_BLUE)
                                ? SNOW_WHITE : SNOW_BLUE;
                    }
                };
               
                //snow_sprite の y 値を増分
                snow_sprite.y += snow_sprite.dy;
                //画像を描画
                snow_sprite.draw();

                //当たり判定
                isHit(snow_sprite, sprite_snow_man);
                snow_sprite = null;
            }
            //画像を描画
            sprite_snow_man.draw();

            //処理数のカウント
            if (loopCounter == SWITCH_PICTURE_COUNT) { loopCounter = 0; }
            loopCounter++;

            window.requestAnimationFrame(renderFrame);
        } else {
            window.requestAnimationFrame(renderFrame);
        }
    }

    //中央に配置する画像の X 座標を求める関数
    function getCenterPostion(containerWidth, itemWidth) {
        return (containerWidth / 2) – (itemWidth / 2);
    };

    //Player (雪だるまを動かせる右の限界位置)
    function getRightLimitPosition(containerWidth, itemWidth) {
        return containerWidth – itemWidth;
    }

    //雪の結晶の縦位置の初期値をランダムに設定する
    function getRandomPosition(colCount, delayPos) {
        return Math.floor(Math.random() * colCount) * delayPos;
    };

    //当たり判定
    function isHit(targetA, targetB) {
        if ((targetA.x <= targetB.x && targetA.width + targetA.x >= targetB.x)
                || (targetA.x >= targetB.x && targetB.x + targetB.width >= targetA.x)) {

            if ((targetA.y <= targetB.y && targetA.height + targetA.y >= targetB.y)
                || (targetA.y >= targetB.y && targetB.y + targetB.height >= targetA.y)) {
                ctx.font = “bold 20px ‘MS ゴシック'”;
                ctx.fillStyle = “red”;
                ctx.fillText(“ヒットしました”, getCenterPostion(canvas.clientWidth, 140), 160);
                targetA.imageIndex = SNOW_CLASH;

                if (!targetA.audioPlayed) {
                    targetA.audio.play();
                    targetA.audioPlayed = true;
                }
            }
        }
    }
})();

 

まとめ

ここまでの機能実装で、アクションゲームに最低限必要なアニメーションキャラクターの操作当たり判定キャラクター画像の変更オーディオ再生といった機能が実装できました。

ゲームの終了、リセット、点数の加算や表示といった機能は、これまで応用で実装可能だと思います。

今回作成したこの単純なゲームでも画像を入れかえることによって、例えば降ってくるお金を拾うゲームや、逆に爆弾をよけ続けるゲーム、タッチ機能を使い、蟻の群れを指でつぶすといったゲームを作成可能です。

以下にこれまで作業した内容のサンプルプロジェクトをダウンロード可能としましたので、ぜひ改造していろいろなものを作成してみてください。


Web Statistics

Clicky

レガシーブラウザのサポートは本日で終了です。~さようならOld IE~

$
0
0

image

そのため、以下の表にある青字で示されている Windows のバージョンについては、OS に既定でインストールされている Internet Explorer を動作可能な最新のバージョンにアップグレードする必要があります。

Windows Internet Explorer 延長サポート終了
Windows Vista SP2 Internet Explorer 9 2017年 4 月 11 日
Windows Server 2008 SP2
Windows 7 SP1 Internet Explorer 11 2020年 1 月 14 日
Windows Server 2008 R2 SP1
Windows Server 2012 Internet Explorer 10 2023年 1 月 10 日
Windows 8.1
(Windows8はWindows8.1へのアップグレードが必要)
Internet Explorer 11
Windows Server 2012 R2 Internet Explorer 11
Windows 10 Internet Explorer 11 (最低でも10年)

同時にこれは IE7 と IE8 、また Windows Vista SP2、Windows Server 2008 SP2 以外で動作する IE9、そして IE10 の実質的なサポート終了を意味します。

そしてこれら、今回サポートが終了するバージョンの Internet Explorer は、Web 標準にもそれほど準拠せず、HTML5 も動作しない、いわゆるレガシーブラウザです。じっさいのところ、Chrome や Firefox (Opera はどうか知りませんが) は、自動更新の仕組みをもっていたので PC においてはバージョンによるフラグメンテーションはほとんど発生せず、レガシーブラウザという言葉はそのまま古いバージョンの Internet Explorer を指していました。
(※いちおう Internet Explorer も自動更新の仕組みはもっていました。)

モダンブラウザが当たり前となった昨今でも、機能も性能も劣るレガシーブラウザをサポートしなければいけないという状況が、作業者の負担かを増やし、Web の進化の足かせにもなっていました。

しかし、これらレガシーブラウザ (Old IE) のメーカーサポートが終了することにより、Web 制作の際にレガシーブラウザ対応を迫られるという状況は減っていくでしょうし、依頼された場合でもメーカーのサポート終了を後ろ盾に断っても、別料金を請求しても良いでしょう。

 

サポートが切れた Web ブラウザーを使用するユーザーについて

使用している Web ブラウザーのサポート期間が終了してもそれに気づかないか、気づいていても、気にしないて使用し続けるユーザーは少なからずいるでしょう。

サポートが終了した Web ブラウザーは、セキュリティパッチが提供されず、脆弱性がそのままになるのでマルウェアの感染や、攻撃を受けるリスクが高まるので継続して使用し続けるのは非常に危険です。

そういったユーザーのユーザーのリスクを「自己責任である」としてなにもせずに看過していると、Web サイト側もリスクを負う可能性があります。

たとえば、マルウェアのなかには Web 感染型という、Web ページにアクセスしただけで感染するものがあります。

これらは Web サイトのページを不正に書き換えて、Web ブラウザーの脆弱性をつく方法でマルウェアを感染させます。

つまり、ユーザーが、脆弱性がそのままになっているサポートの切れた Web ブラウザーを使用していると、Web サイト側も間接的にマルウェアの配布元となってしまうリスクを負うことになるのです。

とくに最近のマルウェアの頒布の方法は狡猾で、以下の記事にあるように広告ネットワークに仕込まれている場合もあります。自分の Web サイト内にあっても、自分が管理できない広告枠の中でコードを実行されることになるので、これはほぼ防ぎようがありません。

しかし、ユーザーの使用している Web ブラウザーが最新の、きちんとセキュリティパッチが適用されたものであるなら、既知の脆弱性は修正されているはずなのでこういったリスクを下げることができます。

また、まんがいちの場合に備え、ユーザーがサポートの切れた Web ブラウザーを使用するにおいてはそのリスクについて Web サイト側が責任を追わないということを明確にしておくことも重要でしょう。

なにより理想的なのは、サポートが終了した Web ブラウザーを使用しつづけることのリスクをユーザーにきちんと示し、アップグレードを促すことでしょう。

実際に以下のメジャーな Web サイトは、ユーザーに注意喚起し、サポートが終了するバージョンを使用するユーザーに対し、アップグレードを勧めています。

また、こういったページを用意しないまでも、サポート切れのブラウザーを使用するユーザーに対し、メッセージを表示する Web サイトなどもあります。

たとえば、Facebook に Windows 7 上の IE8 でアクセスすると、以下のようなメッセージバーが表示されます。Facebook では既に IE8 で使用できない機能もいくつかあるようです。

fb

 

OneDrive にアクセスした際には以下のようなページが表示され、Internet Explorer の更新を促されます。

image

じつは、このブログ記事も、サポートが終了した Internet Explorer でアクセスすると、以下のようなメッセージバーが表示されるようになっています。

このバーのソースコードについては、以下のの記事で使い方とソースを紹介していますので、興味がありましたらご覧ください。

 

マイクロソフトからの注意喚起

サポートが終了した Internet Explorer のバージョンを使用し続けるユーザーについて、マイクロソフトも手をこまねているだではありません

前出のような、Internet Explorer のサポートポリシーの変更を知らせるページを用意するだけでなく、本日(2016/01/13)配布のセキュリティ更新プログラムをインストールすると、Windows 7 において、サポートの終了したバージョンの Internet Explorer を起動時に、以下のように最新の Internet Explorer のダウンロードを促すタブが表示されるようになっています。

download_new_IE

ただしこのタブは Internet Explorer の起動のたびに毎回表示されるわけではなくて、この通知タブを閉じてから 72 時間経過してからでないと再び自動では表示されないようになっています。

この通知についての情報と、通知の停止方法については以下の技術情報をご覧ください。

 

サポート期間が終了した Internet Explorer が必要な場合

サポート期間が終了したバージョンの Internet Explorer が必要な場合もあるでしょう。たとえば、社内システムが、特定の古いバージョンの Internet Explorer でしか動作しないといった場合です。

こういったニーズに対応できるように、Internet Explorer 11 には、従来からのドキュメントモードの他にエンタープライズモードという後方互換機能を搭載しています。

ドキュメントモードが、指定されたバージョンのレンダリングルールでドキュメントの描画を行うだけなのに対し、エンタープライズモードは Internet Explorer 11 上で、Internet Explorer 8 そのものをエミュレーションします。

エミュレーションは仮想化ではないので、完全にそのものというわけではありませんが、従来よりも高い下位互換性を提供します。

これらについての詳しい情報は以下のドキュメントと記事をご参照ください。

サポート期間が終了したバージョンの Internet Explorer が必要な場合には、上記で紹介した Internet Explorer 11 の後方互換機能を使用するようにしてください。

 

まとめ

本日、1 月 13 日をもって Internet Explorer のサポートポリシーが変更され、各 バージョンの Windows にインストール可能な最新の Internet Explorer しかサポートれなくなりました。これに伴い、IE7, IE8 と Windows Vista SP2、Windows Server 2008 SP2 以外で動作する IE9、そして IE10 サポートが終了しました。

サポートが終了したバージョンの Internet Explorer をお使いの方は、ぜひサポートされているバージョンへのアップグレードをお願いします。

最新の Internet Explorer は以下から入手することができます。

これにより従来よりユーザーの安全性を確保しやすくなると同時に、ユーザーに HTML5 に代表される新しい技術を使ったリッチな体験やサービスを提供できるようになり、かつ、Web 制作者側の負担も軽減されます。

ただし一点、心にお留め願いたいのは、最新の Internet Explorer 11 は、もやはマイクロソフトの最新の Web ブラウザーではないということです。

Internet Exploere 11 は後方互換確保のためにのみ存在しており、今後は一切新しい機能は追加されません。不具合の修正プログラムとセキュリティ情報が更新されるだけの事実上メンテナンスフェーズに入った Web ブラウザーです。

これから Web のコンテンツの制作を行うには以下を参考に Internet Exporer ではなく、Edge をターゲットとしてくださいませ。

 

<おまけ>

およそ 20 年にわたる Internet Explorer の激動の歴史について、ご興味のある方は以下の記事をぜひご覧くださいませ。

 

Web Statistics

Clicky

MacでもLinuxでも使える! 無償の Visual Studio Code を使用した Cordova 開発

$
0
0

Windows はもちろん、Mac や Linux でも動作する無償のコードエディタ Visual Studio CodeApache Cordova アプリの開発を支援するための拡張 Cordova Tools Extension が公開されました。

<参照>

Visual Studio Code に Cordova Tools Extention をインストールすることにより、Visual Studio Code を使用して、Cordova アプリのプロジェクトを効率よく編集、デバッグできるようになります。

現状、提供される機能はおおまかに以下のとおりです。

  • Cordova プロジェクトのコンパイル
  • エミュレーター/シミュレーターによるデバッグ実行
  • プラグイン API 記述時の入力補完機能

ここまでの機能を見ると、あたかも Visual Studio Code だけで Cordova アプリの開発が可能になったかのように印象をうけますが、残念ながらそうではありません。

Visual Studio Code は IDE ではなく、基本的にはコードを記述するためのエディターなので、別途 Cordova の開発環境を構築しておく必要があります。

この記事では、ローカル環境に Cordova の環境を構築し、作成した Crodova アプリのプロジェクトを Visual Studio Code  + Cordova Tools Extension を使用してデバッグ実行/ビルドするまでの手順を紹介します。

 

Visual Studio Code のインストール

Visual Studio Code をインストールするには、以下の リンクからダウンロードサイトにアクセスし、ターゲットとなるプラットフォームのアイコンの下にある [Download for ~] ボタンをクリックします。

インストールの詳しい手順については [Download for ~] ボタンをクリックした際に遷移するページの内容を参照してください。

基本的にインストーラーの指示に従えはインストールは完了しますが、どうしても手順が不明で、日本語での説明が必要である場合は、以下のリンクから Visual Studio Code Preview ファースト ステップ ガイド をダウンロードし、同ドキュメントの 13 ページからの内容を参照してください。

 

Cordova Tools Extension のインストール

Visual Studio Code を起動し、キーボードの [F1] キーを押下します。

画面上部にコンボボックスが表示されるので、extension と入力すると、途中からリストボックスに入力候補が表示されるので「Extensions : Install Extension」を選択します。

image

ext install というプロンプトが表示されるので、その後ろに cordova と入力します。

入力途中からリストボックスに「Cordova Tools 1.0.1」が表示されるので、選択してインストールします。

image

Visual Studio Code を再起動し、画面左のメニューからデバッグアイコンをクリックします。

image

メニュー上部の歯車のアイコンをクリックし、

image

表示されたドロップダウンリストの中に「Cordova」が表示されていればインストールは成功です。

image

以上で Visual Studio Code で Cordova プロジェクトを編集する準備が整いました。

Visual Studio Code をインストールした環境に既に Apache Cordova の開発環境がある場合は Cordova プロジェクトの作成 に進んでください。

また、Visual Studio 2013 用の Visual Studio for Apache Cordova がインストールされている、あるいは Visual Studio 2015 のクロスプラットフォーム モバイル開発で Cordova を有効にしてある場合は 環境変数の設定に進んでください。

 

Cordova 開発環境の構築

Cordova アプリをコンパイルするためにはコンパイルに必要となるランタイムと SDK をインストールし、環境を構築する必要があります。

手順は大まかに以下のとおりです。

  1. Java SDK のインストール
  2. Android SDK のインストール
  3. Cordova コマンドラインツールのインストール
  4. 環境変数の設定
メモ

Cordova のコンパイル環境の構築には結構な手間とそれなりの時間がかかりますが、これを見て「(‘A`)マンドクセ」と思った Windows をお使いの方は Visual Studio 2015 のクロスプラットフォーム モバイル開発の機能を使用することをお勧めします。

Visual Studio 2015 のインストーラーは、Apache Cordova の開発環境の構築を一括で行うだけでなく、Visual Studio 2015 IDE によるプロジェクトの作成、コーディング支援、コンパイル、高機能な Hyper-V ベースのものを含む複数種類のシミュレーター、Mac OS 用のリモートエージェント提供など豊富な機能を提供します。なお、個人開発者やオープンソース ソフトウェアの開発者は無償の Visual Studio Community を使用することができます。

 

ここからはプラットフォームとして Windows 10 を前提として Cordova 開発環境の構築手順を説明していきますが、他のプラットフォームも大きく変わるところはないと思いますので参考にしてくたさい。

また、Mac OS をお使いで、iOS アプリを開発される方は Xcode をインストールしておいてください。

 

Java SDK のインストール

Apache Cordova を使用して Android 用アプリをコンパイルするには Android SDK が必要であり、Android SDK は Java SDK を必要とします。

よって Android SDK をインストールする前に Java SDK をインストールしておく必要があるので、以下のリンク先のページより最新の JDK をインストールしてください。

Java SDKの インストールにはそれなりに時間がかかります。ウィザードの準備にやたらと時間がかかったり、ウィザードのプログレスバーがぜんぜん進まないなぁ、と思ったらその裏側にボタンのクリックが必要なダイアログボックスが表示されていたと、はらはらすることもありますが、信じて待っていればいつか必ずインストールが完了するので完了画面かエラー画面が出るまで慌てずに待ちましょう。

 

Android SDK のインストール

Android 用アプリをコンパイルするには Android SDK が必要です。

以下のリンク先ページの SDK Tools Only  から SDK をインストールしてください。

インストール途中か、完了後に Android SDK Manager が表示されたら Android SDK 2.3 がインストールされるように構成してください。(※2016 年 2 月現在)

image

 

メモ

なおインストールの際には、Android SDK を「Install for anyone using this computer(このコンピューターのすべてのユーザーに使用させるか)/Install just for me(現在のユーザーにのみ)」の選択によりインストール位置が異なるので、どのバスにインストールされるかを覚えておいてください。

Androis SDK のインストールパスは、環境変数の設定の際に必要です。

 

Node.js のインストール

Apache Cordova のインストールには Node.js が必要です。

以下のリンクより Node.js のサイトにアクセスし、「Stable」と書かれたほうのボタンをクリックして、 最新版の Node.js をインストールします。

インストールが完了したら、以下のコマンドプロンプト(Windows)/ターミナル(Mac, Linux) を起動し、以下のコマンドを実行してバージョン番号が返るか確認してください。

node –v

つぎに、パッケージマネージャーである npm が正しくインストールされたかどうか確認するために以下のコマンドを実行してください。

mpn –v

バージョン番号が正しく返れば正常にインストールされています。

 

Cordova コマンドライン ツールのインストール

管理者権限で起動したコマンドプロンプトで以下のコマンドを実行します。(Mac、Linux の場合は su コマンドを実行しておくか以下のコマンドの前に sudo を付けて実行してください。)

npm install cordova –g

インストールが完了したら、以下のコマンドを実行しバージョン番号が返るか確認してください。

cordova –v

 

環境変数の追加

Cordova のコマンドラインツールは Android SDK のコマンドを使用するため、環境変数を設定し、いくつかのディレクトリに PATH を通しておく必要があります。

具体的な設定方法は以下のとおりです。

環境変数 ANDROID_HOME  の追加

ANDROID_HOME という環境変数を追加します。

Windows の場合は、[コントロールパネル] – [システム] – [システムの詳細設定]メニューで表示される [システムのプロパティ] ダイアログボックスの [詳細設定] タブで行います。

同タブ内の [環境変数] ボタンをクリックすると、[環境変数] ダイアログボックスが表示されるので、[(ユーザーアカウント)のユーザー環境変数]内の [新規] ボタンをクリックします。

image

[新しいユーザー変数] ダイアログボックスが表示されるので [変数名] を 「ANDROID_HOME」に[変数値]に Android SDK がインストールされているパスを指定して [OK] ボタンをクリックします。

 

PATH の設定

環境変数 ANDROID_HOME を設定したダイアログボックスの環境変数のリストで「PATH」を選択して [編集] ボタンをクリックします。

「PATH」に設定されたディレクトリパスの一覧が出てくるので、フォルダ Android\android-sdk\platform-tools の中身を確認し、ファイル類が存在すればそのディレクトリパスを、ファイルがなにも無ければ Android\android-sdk\tools のディレクトリパスを、心配な場合はその両方を [新規] ボタンをクリックして追加します。

image

なお、Windows 7 の場合は、上記の図のようなリストではなく、一行のテキストボックスに ; (セミコロン) 区切りでパスが列挙されているので、同様に ; (セミコロン) 区切りで設定を追加してください。

メモ

Android SDK のインストールのところでも書きましたが、インストールの際の選択によって Android SDK のパスは異なります。不明な場合は以下を参考にしてください。

「Install for anyone using this computer」を選択した場合
C:\Program Files (x86)\Android\android-sdk (64bit OS)
C:\Program Files\Android\android-sdk (32bit OS)

「Install just for me」を選択した場合
C:\Users\ユーザーアカウント名\AppData\Local\Android\Android-sdk

 

環境変数の設定が完了したら OS を再起動し、設定を有効にしてください。

Mac、Linux の場合

Mac、Linux の場合はターミナルが既定で使用している Bash の設定ファイルである .bash_profile に設定を追加してください。

詳しい設定方法については以下をご参照ください。

ここまでの作業で Apache Cordova を使用した開発ができる環境が整いました。

 

プロジェクトの作成

Cordova アプリの開発を行うためのプロジェクトを作成します。

コマンドプロンプト( Windows)/ターミナル(Mac, Linux) を起動して、開発を行うための任意の場所に作業用ディレクトリを切り替え、以下のコマンドを実行します。

cordova create app01 com.example.myApp01 HelloWorld -d

コマンドラインの内容は以下の通りです。

コマンドライン要素

意味

cordova create プロジェクトを作成するためのコマンド
app01 プロジェクト用に作成するフォルダ名
com.example.myApp01 Javaパッケージ命名規約に沿った
パッケージ名 (Android アプリで必要)
HelloWorld プロジェクト名
-d 途中経過を表示するスイッチ

 

なお、フォルダ名、パッケージ名、プロジェクト名は任意のものをつけてかまいません。

 

プラットフォーム用ファイルの追加

プロジェクトにアプリのターゲットとなるプラットフォーム用のファイルを追加します。

cd コマンドを使用して、作業ディレクトリをプロジェクトを用に作成したフォルダとします。

ターゲットごとに以下のコマンドを実行します。

Android 用 :
cordova platform add android

 

iOS 用 :
cordova platform add ios

 

Windows 用:
cordova platform add windows

 

Windows 環境で iOS 用のファイルを追加すると以下のように “この OS では iOS プラットフォーム用のアプリケーションはビルドできません” 的な WARNING が返りますがエラーではありません。iOS 用アプリのコンパイルには Mac OS が必要なので仕方ないのです。

image

 

Visual Studio Code へのプロジェクトのロードとコンパイルとデバッグ実行

作成した Cordova プロジェクトを Visual Studio Code でロードしてコンパイルします。

プロジェクトフォルダのロード

コマンドプロンプト( Windows)/ターミナル(Mac, Linux) の作業ディレクトリをプロジェクトフォルダとし、「code .」とコマンドを入力すると Visual Studio Code がプロジェクトのフォルダをロードして起動してきます。

コマンドプロンプトから Visual Studio Code が起動しない場合は、手動で起動してメニュー [File] – [Open Folder] でプロジェクトフォルダをオープンしてください。

 

Cordova プロジェクトのコンパイル

Visual Studio Code で Cordova プロジェクトをコンパイルします。

Visual Studio Code の画面でキーボードの [F1] キーを押下すると画面上部にコンボボックスが表示されるので、cordova と入力し、表示された入力候補からCordova: Build を選択します。

image

コンパイルが開始されます。

image

完了するとパッケージまでのリンクが表示されます。

image

Windows 環境の場合 “xcodebuild が見つからない” といった旨のエラーが表示されますが、致し方ないといったところでしょう。

image

iOS 用のアプリについては、作成したプロジェクト\platforms\ios フォルダに Xcode 用のプロジェクトが格納されているので、これを Mac OS 上の Xcode でビルドしてください。

メモ

もし、コンパイルの際に “Android 2.3 の必要…” という旨のメッセージが返りコンパイルが停止する場合は、コマンドプロンプトで android とタイプして [Enter] キーを押下してください。Android SDK Manager が起動してくるので、これを使用して 2.3 の SDK をインストールすることができます。

 

Cordova プロジェクトのデバッグ実行

Visual Studio Code から Android エミュレーターを起動して、Cordova プロジェクトをデバッグ実行することができます。

デバッグ実行してエミュレーターでアプリを表示する前に、実際に作業したものが反映されるか確認するためにプロジェクトに既定で含まれている index.html に記述を追加しましょう。

Visual Studio Code で index.html を開き、<h1>Apache Cordova</h1> と記述してある前の行に以下の記述を追加します。

<h1>こんにちは世界</h1>

既定の設定のままだと文字化けしてしまうので、以下の meta タグを追加します。

<meta charset=”UTF-8″>

プロジェクトをデバッグ実行します。

Visual Studio Code の画面でキーボードの [F1] キーを押下すると画面上部にコンボボックスが表示されるので、cordova と入力し、表示された入力候補からCordova: Run を選択します。

image

エミュレーターが起動し、以下のような画面が表示されます。

image

エミュレーターは heap 領域が足りないと処理が完遂できないので、途中で動作が止まってしまった場合は、起動している不要なアプリケーションをすべて終了してから再度行ってみてください。

なお、起動するエミュレーター/シミュレーターはデバッグ画面のドロップダウンリストで変更することができます。

image

以上で Visual Studio Code で Apache Cordova を使用したマルチプラットフォームなハイブリッドアプリを開発する環境が構築できました。

 

まとめ

今回の記事では、Visual Studio Code 用に Apache Cordova を使用した開発をするための拡張  Cordova Tools Extension  がリリースされたということで、同拡張機能のインストール方法と、Cordova の開発環境を構築する手順について紹介しました。

記事の中でも書いていますが、Windows をお使いの方で、マシンのリソースがそれなりにあるのであれば、Apache Cordova を使用した開発には Visual Studio Code ではなく  Visual Studio 2015 を使用することをお勧めします。Visual Studio 2015 は、Cordova 開発環境の構築、プロジェクトの作成やコーディングの際の豊富な入力支援機能、プラグインの管理や複数のシミュレーターの提供など、さまざまな機能が IDE 統合されており、それらをシームレスに使用することができます。

Mac や Linux をお使いの方、または Windows をお使いで、Visual Studio 2015 ほどの機能は必要なく、もっと手軽に Cordova アプリを作成したいという方は Visual studio Code をお使いになると良いでしょう。

また Visual Studio Code の開発は GitHub 上で行われており、拡張機能の開発も活発に行われているので、コミッターとして参加したり、フォークしてほしい機能を実装してみても良いかもしません。

 

Web Statistics

Clicky


JavaScriptライブラリ中毒者(ジャンキー)にならないために

$
0
0

Web コンテンツに、より高度で複雑な機能を求められる昨今、jQuery のような外部の JavaScript ライブラリを利用しない Web サイトはほとんどないでしょう。

たしかにそれらは汎用性が高く再利用が可能なので、さまざまな機能を自分で実装する必要はなく、工数を圧縮し開発生産性を高めることができます。

また、昨今の技術系のニュース記事では、新しいフレームワークが次々と登場して話題となり、それらを使用して開発することが、さも「モダン」であるかのように書かれています。

はたして本当にそうでしょうか?

DOM のセレクターを使用するためだけに大量の機能セットを含むライブラリを参照しているソースや、UI バインディングを行うためだけに大げさなフレームワークを利用しているソース、それは「モダン」で「クール」な作りなのでしょうか?

今回の記事では、外部 JavaScript のライブラリやフレームワークの使用について、その意義とリスクについてあらためと考えてみたいと思います。

 

あらためて意識しておきたい

外部の JavaScript ライブラリを
使用する際の影響

外部の JavaScript ライブラリは便利である一方、どのようなコードであろうと第三者が開発したものであるかぎり、自分の感知しえない不具合やセキュリティ、パフォーマンス問題、または予想外の振る舞いを潜在的に導入することになります。たとえば、JavaScript ライブラリを使用するにはブラウザーにロードされる必要があり、それには追加のサーバー ラウンドトリップやライブラリそのもののサイズが多少なりともパフォーマンスにネガティブな影響を与えます。また、コードの品質も必ずしも保障されているものではありません。

これはいたずら不安を煽っているわけではなく、外部の JavaScript を導入するのであれば、前述のようなマイナス面について最低限理解しておくべきあたりまえの事実です。

こういったマイナス面を担保するにはどういった方法がとれるでしょうか?

もっとも確実な方法は使用しないということです。しかしながら、前述したように Web コンテンツに複雑な高機能を要求される昨今では、外部の JavaScript ライブラリを一切しないというのは現実的ではありません。

よって現実的な 1 つの解として導きだされるのは、実装する処理に外部の JavaScript ライブラリの機能が本当に必要であるかどうか、Web 標準技術の活用だけで実装可できないのか、正しく見極めることです。

2 番目の方法は、ライブラリの更新情報をフォローし、各ライブラリの最新の安定バージョンに常にアップグレードするかどうかを判断することで、リスクを抑制することができます。

 

JS ライブラリ(jQuery)の機能を置き換える

今現在、最も一般的に使用される JavaScript ライブラリの 1 つは jQuery でしょう。この JavaScript ライブラリは、Web 開発者に HTML DOM をクエリーして簡単に操作する方法を提供します。

特徴的な jQuery セレクターの記述によってもたらされるコードの簡潔化とその機能は、初見の際には誰しもが新鮮な驚きと少なからぬ感動を覚えたことでしょう。

しかしなから、過去の我々の目に魔法のように映った jQuery のセレクターの機能も、いまや JavaScript の標準的な機能で記述することができるのです。

以下のコードは jQuery で一般的に使用される機能のいくつかです。

//Id ‘party_goods’ を持つ DOM 要素の取得
var product = $(‘#party_goods’);

//子要素であるすべてのimg要素を取得
var productImages = $(‘#party_goods’).find(‘img’);

//指定した要素のクラスを追加
$(‘#party_goods’).addClass(‘crazy’);

//指定したクラスの要素を列挙
var crazyItem = $(‘.crazy’);

 

現代の JavaScript では、標準の機能を使用して以下のように記述することができます。

 

//Id ‘party_goods’ を持つ DOM 要素の取得
var product = document.getElementById(‘party_goods’);

//子要素であるすべてのimg要素を取得
var productImages
            = document.querySelectorAll(‘#party_goods img’);

//指定した要素のクラスを追加
document.querySelector(‘#party_goods’).classList.add(‘crazy’);

//指定したクラスの要素を列挙
var crazyItem = document.querySelectorAll(‘crazy’);

さきほど “現代の” と書きましたが、これらの記述は結構以前から使用することができました。

querySelector や querySelectorAll は以下 caniuse.com のリンクが示すとおり Internet Explorer 9 の時点で Safari 以外のメジャーな PC 用の Web ブラウザーで使用することができました。

Can I use… Support tables for HTML5, CSS3, etc querySelector/querySelectorAll

JavaScript の標準的な機能を使った書き方は jQuery の記述よりも冗長かもしれません。

しかしながら要素を取得するための getElementById などは、一度どこかで以下のように宣言しておけば、

var $id = function (id) {return document.getElementById(id);}

以降は以下のように記述すれば良くなります。

//Id ‘party_goods’ を持つ DOM 要素の取得
var product = $id(‘party_goods’);

 

「そうは言っても、他の機能で jQuery を参照しているんだからべつに使ったって良んじゃネ?」という意見もあるでしょう。

たしかに CSS のフレームワークである Bootstrap などは jQuery を使用するので、望むと望まざるとにかかわらず jQuery ライブラリはブラウザにロードされることになります。「ロードされたんだから使わなければ損」という気持ちもわからなくもありません。

しかし、考えてほしいのです、想像して、推測してほしいのです。「(‘#hoge’)」と記述して、本来の getElementById メソッドに行きつくまでに、標準的な書き方をすれば処理する必要のない JavaScript コードがどれくらいあるのかを。もし、想像できなければブラウザーの開発者ツールを起動して jQuery ライブラリの中をステップ実行してみると良いでしょう。「id からエレメントを取得する」という処理のために結構な量の JavaScript コードを処理しなければならないということがわかるはずです。

つまり、jQuery のセレクターを使用する毎にこの大量のコードが実行されるのです。はたしてそれが効率の良いプログラムと言えるでしょうか?

さらには、ライブラリに依存しすぎると移植性が犠牲になります。

あたりまえですが、jQuery の使用を前提として書いたコードは jQuery のある環境でしか動作しません。もしなんらかの理由で jQuery が使用できない環境に移植する場合は修正が必要になります。しかし、前述したような JavaScript の標準機能を積極的に活用し、ライブラリへの依存度を極力下げることで修正の範囲を狭くおさえることができます。

(※じつはここから、外部フレームワークなしで実現するシンプルな JavaScript コードによるデータと UI のバインド方法について書いたのですが、長くなったので、近日別途記事にします。)

 

JavaScript ライブラリ導入後の
メンテナンス

JavaScript ライブラリはある一定期間ごとにバージョンアップが行われますが、バージョンアップで行われるのは機能追加だけではありません。

既知のものや、前バージョンリリース後に発見された不具合の修正も行われます。

これらの修正内容は、Web コンテンツの動作に関わる内容も含まれる場合もあるので、外部の JavaScript を採用したのであれば、継続して更新の内容を確認しておくことをお勧めします。

image

 

JavaScript ライブラリについて

問題を含むバージョンをチェックするツール

JavaScript のライブラリの更新情報については、提供元の Web サイトを参照するのが基本ですが、マイクロソフトでは、Web サイトで使用している JavaScript ライブラリが問題をふくむバージョンでないかどうかをチェックするツールを提供しています。

このツールにアクセスするには以下の URLにアクセスし、ページ内にある 「URL の入力」とキャプションのあるテキストボックスに対象の URL を入力し、虫眼鏡ボタンをクリックするとページのスキャンが行われます。

image

ちなみに以下は、このブログのサイトの検証結果です。

image

このブログで使用しているのは jQuery 1.5.2 であり、ソースコードの 24 行目になにがしかの問題があることを指摘し、かつ、互換性のある問題のないバージョンとして 1.6.4 を提示しています。

このツールについてはオープンソース版が GitHub で公開されており、このブログでも以前、配置の方法を記事にしています。

Web 制作での外部ライブラリの使用があたりまえとなった昨今、導入は進んだものの公開後のバージョンのメンテナンスはおろそかになっている場合があります。(じっさいのところ、毎回更新の内容を確認するのはたいへんです)

こういったツールを積極的に使用してメンテナンスを楽にしてみてはいかがでしょうか。

 

まとめ

今回の記事では、jQuery のような外部の JavaScript を使用する際のリスクについてあたらめて確認しました。

外部の JavaScript は便利な反面、依存しすぎるとパフォーマンスの低下やコードのロックインにつながります。どこまでをライブラリに任せ、どこまでを自前で書くのか意識されると良いでしょう。

Web Statistics

Clicky

[お知らせ]当ブログ過去記事がうまく表示されない問題につきまして

$
0
0

当ブログをご覧になっていただきありがとうございます。

過去のブログのページに関し、一部 iframe の抜けやレイアウト崩れが発生している場合があります。これは、少し前にブログの CMS が変更になったためです。

お使いになられているブラウザーなどの問題ではありませんのでご安心ください。

過去ページで表示に不都合があるものについて、改修可能なものにつきましては、順次修正していきますので、もうしばらくお待ちくださいませ。

以上、よろしくお願いします。

Windows 10 Anniversary Update における Microsoft Edge の新機能

$
0
0

Windows 10 が公開されてちょうど一年、Windows 10 の無償アップグレード期間が終了したのと入れ替わるように本日 (2016/8/3 日本時間) Windows 10 Anniversary Update が公開されました。

この Windows 10 Anniversary Update では、Windows 10 が発表された際の様々なビジョンのいくつかが実装され、さらにその当時は想像だにできなかった  Windows Subsystem for Linux (WSL) といったようなまったく新しい機能も搭載されています。

Windows 10 から搭載された新しい Web ブラウザーである Edge にも、当初の計画にあった新しい拡張 (エクステンション)モデルの実装や、Windows フィードバック、Developer FeedBack (旧 Edge Suggestion Box) に寄せられたフィードバックや提案をもとにした新しい機能が実装されています。

今回の記事では Windows 10 Anniversary Update の新機能、とくにユーザーが直接対話するデスクトップ UI の新機能と、新しく追加された Edge 関連のグループポリシーの設定について紹介します。

 

Microsoft Edge のデスクトップ UI 機能の強化

Windows 10 がリリースされてからこれまで、Edge にもたゆまず機能強化が行われてきましたが、その内容はパフォーマンスの向上であったり、サポートする API の数を増やすであるとか、どちらかというと開発者向けのものが多かった印象があります。

これら機能は UI を持たないため、開発者以外の多くのユーザーは Edge の機能向上の進捗を肌感として感じれなかったかもしれません。

しかし、Windows 10 Anniversary Update での Edge では、誰しもがアクセス可能なデスクトップ UI に複数の新機能を搭載しています。

この機能は、おおまかに分類すると以下の 4 つに別けられます。

  1. ナビゲーション
  2. お気に入り
  3. ダウンロード
  4. コンテキストメニュー

以降は、上記 4 つの項目について、具体的にどのどのような機能が追加されたのかを紹介していきます。


 

ナビゲーション

Web ブラウジングにおける “ナビゲーション” はページを遷移させるための操作や、その動作そのものを指します。

このナビゲーション関連では以下の機能が追加されています。

右クリックでのナビゲーション履歴表示

Edge のナビゲーションバーの左側にある 戻るボタン/進むボタン上で、マウスの右ボタンをクリックすることで、それまでの履歴と現在の位置(履歴内のどこをブラウズしているか)が表示され、クリックすることでそのページに遷移できるようになりました。

従来の 戻る/進む ボタンでは、ブラウザーを起動してからの履歴に対し、ひとつずつしか前後に遷移できませんでしたが、この機能を使用すると履歴の任意の位置に直接移動できます。

context_history

貼り付けて移動/検索

クリップボードにコピーした URL のページを Edge で表示させる場合、ナビゲーションバーに一度 URL を貼り付けてからキーボードの [ Enter] キーを押下する必要がありました。

また同様に、クリップボードにコピーしたキーワードで検索を行う場合には、 ナビゲーションバーに一度 キーワードを貼り付けてからキーボードの [ Enter] キーを押下する必要がありました。

Windows 10 Anniversary Update からの Edge では、ナビゲーションバー上でマウスの右ボタンをクリックした際に表示されるコンテキストメニューに [貼り付けて移動] もしくは [貼り付けて検索] というメニューが追加されており、このメニューを選択することで [Enter] キーを押下しなくてもクリップボードにある URL への移動、あるいはクリップボードにあるキーワードで検索を行うことができます。なお、「移動」か「検索」かは、クリップボードの内容により自動的に判断されます。

paste_and_go
(クリップボードの中身が URL の場合)


 

paste_and_find
(クリップボードの中身が URL ではない場合)

スワイプによるナビゲーション

スワイプによるナビゲーションに対応しました。

Windows Phone や タッチ対応のモニタの PC で Edge を使用する場合、画面を左/右にスワイプすることで一度遷移した URL について遷移することができます。

左にスワイプするとひとつ前に戻り、右にスワイプするとひとつ進みます。

 

お気に入り

Edge において「お気に入り」 (favorite) はユーザーが任意の URL を Web ブラウザーに登録しておく機能です。

お気に入り関連では以下の機能が追加されています。

ピン留め

ピン留めは Internet Explorer 8 からサポートされた機能で、当時はピン留め対応した Web サイトのショートカット アイコンとナビゲーションメニューを Windows のタスクバーに登録することができました。

Windows 10 Anniversary Update で提供される Edge には、ショートカットアイコンの登録場所や提供される機能は異なりますが、ピン留め機能が復活しています。

また、Web サイト側での特別な設定は不要となっています。

Edge のピン留め機能を使用するには、任意のページを表示したページのタブの上で右クリックし、表示されたコンテキストメニューから [ピン留めする] メニューを選択します。

Pinned tab

これによりタブの左端にページがピン留めされ、Edge が起動されると同時にページがロードされるようになります。

image

[お気に入り] メニューのツリー表示と並べ替え機能

これまで Edge の [お気に入り] メニューでは、同一階層にあるリンクのみが一覧で表示されていましたが、Windows 10 Anniversary Update で提供される Edge ではツリー表示されるようになりました。

favorit_tree

また、名前で並べ替えも出来るようになっています。

name_sort

[お気に入り] のインポート元の表示

Edge では他の Web ブラウザーから [お気に入り] をインポートできますが、インポート元の Web ブラウザーの名前がついたフォルダが作成され、どの Web ブラウザーからインポートされたのかわかるようになりました。

Inport

お気に入りバーのメニュー追加

お気に入りバー上にショートカットの表示で、アイコンだけを表示できる設定が追加されました。

favorite_setting


また、これまでお気に入りバーにはコンテキストメニューは設定されていませんでしたが、今回のアップデートで [新しいフォルダの作成] と [アイコンのみ表示する] メニューが追加されました。

FavoritesBar

 

ダウンロード

Edge のダウンロード機能については、保存場所や保存のさいのアクションについて、以下のような機能が追加されています。

保存先フォルダの指定

これまでの Edge では、既定のダウンロード先のフォルダは %user%\ダウンロード となっており、これを変更することは出来ませんでしたが、今回のアップデートでは [詳細設定] メニューからこれを変更できるようになりました。

image

ダウンロード先の指定

これまで、Edge ではファイルをダウンロードする際に保存先の指定を任意で行うことはできませんでしたが、今回のアップデートでは、ダウンロード時に表示されるダイアログボックスに [名前を付けて保存] ボタンが追加され、保存先の指定や、保存する際のファイル名の指定ができるようになりました。

dl_dialog

ダウンロード中に Edge 終了の際の警告

ファイルをダウンロード中に Edge をクローズ場合、警告メッセージが表示されるようになりました。

 

コンテキストメニューへの機能追加と変更

Web ページを表示する部分で、右クリックした際に表示されるコンテキストメニューにも機能が追加されています。

Cortana との連携

Edge に Cortana との連携機能が実装されました。

文字列、もしくは画像を選択し、マウスの右クリックメニューから [Cortana に質問] を選択すると、選択された内容に関連する情報を判断して検索を行い結果を列挙します。

Cortana


 

たとえば、以下のように画像を問い合わせた場合、Cortana は関連する情報と類似する画像を調査して列挙します。

image

 

開発者用メニューの表示タイミング

これまでの Edge では、表示されている Web ページ上での右クリックメニューに [要素の検査] と [ソースの表示] という開発者向けのメニューが、初期状態から表示されるようになっていました。

今回のアップデートでは、初期状態ではこれら開発者向けのメニューは表示されず、F12 開発者ツールが起動されてからはじめて表示されるようになっています。

 

ここまで Windows 10 Anniversary Update で追加される Edge の新機能について紹介してきました。

Edge の新機能については、かねてからのロードマップと、ユーザーから寄せられたフィードバックにもとづき実装しています。

しかしながら、期待していた機能が実装されていなかった、ということもあるでしょう。そういった場合には Edge に拡張インストールし、昨日を追加することでご要望を満たすことができるかもしれません。

 

拡張 (エクステンション) による Edge の機能強化

Windows 10 Anniversary Update の Edge では、拡張がサポートされました。

拡張とは、外部で作られたプログラムで、Edge にプラグインすることで Edge の機能を文字どおり拡張します。

Edge の拡張は Windows ストアから入手することができ、すでに Ad ブロックやマウスジェスチャー、翻訳等、さまざまな機能を提供する拡張が用意されています。

拡張の入手と Edge へのインストール

拡張の具体的な入手とインストール方法は以下のとおりです。

  1. Edge のツールバー上の  […] アイコンをクリックして [拡張機能] メニューをクリックします。
    image


     

  2. [拡張]パネルが表示されるので [ストアから拡張機能を取得する] リンクをクリックします。
    image


     

  3. Windows ストアの 「Microsoft Edge の拡張機能」 画面が開くので任意の拡張のアイコンをクリックします。
    ExtensionList


     

  4. 選択した拡張の説明画面に遷移するので [無料] 、もしくは金額の書かれた(※有料の拡張の場合) ボタンをクリックします。
    image

以上の手順で拡張のダウンロードとインストールが行われます。

拡張の設定とアンインストール

Edge にインストールした拡張のアンインストールやオプション設定は、Edge の [拡張機能] メニューで行います。

具体的な手順は以下のとおりです。

  1. Edge のツールバー上の  […] アイコンをクリックして [拡張機能] メニューをクリックします。
  2. [拡張]パネルが表示され、インストール済の拡張のリストが表示されるので、任意の拡張をクリックします。
  3. 拡張の詳細設定画面が表示されるので以下から目的の操作を行います。
    • 拡張を有効、もしくは無効に –  トグルボタンを操作
    • 拡張のオプション設定を行う – [オプション] ボタンをクリック
    • 拡張をアンインストールする – [アンインストール] ボタンをクリック
    image


 

Edge への拡張のインストール/アンインストール方法は以上です。

Edge 用の拡張を自分で作成する方法についてはこのブログの前回の記事で紹介していますので、興味のある方はぜひご覧ください。

 

Windows 10 Anniversary Update で追加される Edge のグループポリシー設定

Windows 10 Anniversary Update では Edge のグループポリシーで設定できる内容も追加が行われています。

グループポリシーとは、IT 管理者が管理対象の使用者に対してさまざまな設定を一括で行うための機能です。

従来から Edge では、以下の内容について IT 管理者がグループポリシーを用いて Windows ドメイン ユーザーの使用する Edge を管理することができます。

設定 説明
オートフィルを無効にする Edge の使用中にフォームのフィールドにオートフィルで自動入力できるかどうか
開発者ツールを無効にする F12開発者ツールの使用を許可するかどうか
トラッキング拒否ヘッダーの送信を従業員に許可する トラッキング情報が要求される Web サイトに従業員がトラッキング拒否ヘッダーを送信を許可するかどうか
InPrivate ブラウズを無効にする InPrivate ブラウズの使用の有無
パスワードマネージャーを無効にする パスワードマネージャーを使用してパスワードのローカル保存を許可するかどうか
ポップアップブロックを無効にする ポップアップブロック機能を使用可とするかどうか
アドレスバーの検索候補を無効にする アドレスバーに検索候補を表示するかどうか
SmartScreen フィルターを無効にする SmartScreen フィルターを有効にするかどうか
Open a new tab with an empty tab ([新しいタブ]ページでのWebコンテンツの許可) 新しいタブを開いたときに表示するページの種類を構成
Cookie を構成する Cookie の扱いを構成
エンタープライズモードサイト一覧を構成する エンタープライズ モードとエンタープライズ モード サイト一覧を使用するかどうかを構成
お気に入りを構成する ユーザーに表示される既定のお気に入りを構成できます
WebRTC による LocalHost IP アドレスの共有をしない WebRTC プロトコルを使用した通話中にユーザーの LocalHost IP アドレスが表示されるかどうかを指定
企業のホームページを構成する ドメインに参加しているデバイス用に企業のホーム ページを構成
SmartScreen フィルター機能の警告の上書きを許可しない 有害である可能性のある Web サイトに関する SmartScreen フィルター機能の警告を従業員が上書きできるかどうかを指定
確認されていないファイルに関するSmartScreen フィルター機能の警告の上書きを許可しない 確認されていないファイルのダウンロードに関する SmartScreen フィルター機能の警告をユーザーが上書きできるかどうかを指定
すべてのイントラネットサイトを Internet Explorer 11 に送る イントラネット サイトを Internet Explorer 11 で表示するかどうかを指定

 

今回のアップデートでは、新たに以下の内容が制御可能となりました。

設定 説明
Microsoft Edge で about:flags ページへのアクセスを禁止する ユーザーが about:flags ページにアクセスできるかどうかを指定
拡張機能の許可 ユーザーが拡張機能を読み込めるかどうかを許可
Interner Explorer でサイトを開くときのメッセージ表示 Internet Explorer 11 でサイトが開かれたことを示す追加ページを Microsoft Edge で従業員に表示するのかどうかを指定

これらグループポリシーの新しい設定を使用することで、IT 管理者は今回のアップデートで追加された Edge の新機能の使用の有無を管理することかできます。

 

Microsoft Edge の更新履歴について

Windows 10 のビルド単位での、より詳しい更新履歴については、以下のページで確認することができます。

 

Microsoft Edge がサポートする API については以下をご参照ください。

 

なお、F12 開発者ツールの新機能 (そんなにない)、 Internet Explorer 11 の後方互換性関連の新機能 (これも、そんなにない) については後日紹介したいと思います。

 

まとめ

これまでの Edge では、Web コンテンツの閲覧中 Internet Explorer 11 と比較して機能が少ないと感じる場面が多々あったかもしれません。しかし、そういった不満は Windows 10 Anniversary Update によってずいぶんと解決されていると思います。

また、それでも足らないと感じる機能については、拡張を追加することである程度解消できることでしょう。

Edge を使ってみて他の Web ブラウザーを使うようになってしまった人も、Edge をまだ使用したことがない人もぜひこの機会に Edge をお試しくださいませ。

 

Real Time Analytics

Clicky

2016 11/1, 2 Microsoft TechSummit 開催

$
0
0

マイクロソフトの IT Pro 向けのイベント Microsoft Ignite の日本版 Microsoft TechSummit が 11 月の 1 日、2 日にヒルトンお台場で開催されます。

 

Tech_w708-h255_2

 

ただ今、早期割引実施中です。

お申込みはこちらから。

ちなみに私は IT Pro 向けのイベントにもかかわらず Edge 拡張の開発とデバッグ方法について、デモとサンプル山盛りのセッションをする予定です。

ご興味のある方はぜひともご参加くださいませ。

 

Real Time Analytics

Clicky

Microsoft Edge 拡張の作り方:browserAction 編

$
0
0

前回の記事で Microsoft Edge の拡張の作り方を紹介してからずいぶん間があいてしまいましたが今回から数回に別けて続きをお送りします。

前回の記事では、サンプルとして Web コンテンツ上でマウスの右ボタンをクリックした際に表示されるコンテキストメニューに独自のメニューを追加する機能の作成方法について紹介しました。

今回からは、残りのその他のアクションで動作する拡張について、特徴と具体的な作り方を紹介していきます。

取り上げるアクションは以下のとおりです。

(※Edge 拡張の概要と、コンテキストメニューの実装サンプルについてはこちらの記事をご覧ください。)

なお、今回から紹介するサンプルコードはすべて Google Chrome(2016年10月時点の最新のもの) でも動作します。

 

Edge 拡張を構成するファイル

その前に、前回の記事で紹介したつもりになっていて実際にはぜんぜん書いていなかった Edge 拡張を構成するファイルについて紹介します。

Microsoft Edge の拡張を構成するファイルは manifest (json)、background page (html)、Content scripts (js)、UI pages (html) の 4 種類のファイルです。

ファイル 説明

Manifest (json)

定義ファイル(※必須)
拡張の名前や説明、アクセス権や拡張が使用するファイルなどを指定

Background page (html)

拡張の機能をバックグラウンドで動作させるためのページ

Content scripts (js)

拡張の機能を実装するための JS ファイル

UI pages (html)

ポップアップや設定画面などのUI ページ


 

これらのファイルで必須なのは manifest.json だけで、そのほかのファイルは用途に合わせて取捨選択して使用します。

ただし、manifest.json ファイルは単なる定義ファイルなので、これだけでは拡張として何らかの機能を提供することはできません。

よって、Microsoft Edge の拡張は、必ずその他の 1 つ以上のファイルと組み合わせて作られています。

 

ブラウザー拡張のアクション

ブラウザー拡張の API はさまざまな機能を提供しますが、ユーザーにそれらの機能を呼び出させるための実装(アクション)は以下の 4 つになります。

今回はブラウザーアクションの拡張について紹介します。

 

ブラウザーアクション

ブラウザーアクションの拡張は、Web ブラウザーのツールバーに表示されるアイコン、もしくは [詳細] メニュー (Edge のみ) に表示されるアイコンから拡張の機能を実行します。

image

 

image


 

ブラウザーアクションには HTML で記述したポップアップを関連付けることができるので、メニューを介して複数の機能を提供したり、テキストボックスのような入力 UI を配置して SNS への共有機能などを実装することもできます。

たとえば、以下のサンプルは Edge のツールバーをクリックするとポップアップ画面に Microsoft Edge 関連の Web サイト のリンクを表示するものです。

image


 

以降、ソースを使用して説明を行いますが、お手元で実際に動作させるには e-19.png という名前の 19 x 19 ピクセルのアイコン用の画像ファイルが必要です。

作成するのが面倒な方は以下の画像を保存して使用してください。

image

ブラウザーアクションの manifest.json

ブラウザーアクションの manifest.json は以下のようになります。

manifest.json のキー “browser_action” の内容に注目してください。

default_icon” キーで、ツールバーに表示されるサイズのアイコンを、”default_title” でアイコン上に表示されるタイトルを指定しています。

default_popup” キーでは、アイコンをクリックした際にポップアップとして表示される html ファイルを指定しています。

 

ブラウザーアクションのポップアップ用の html

ブラウザーアクションの拡張で使用する基本的なポップアップ用の html ファイルは以下のとおりです。

ご覧のとおりなんの変哲もない通常の html ファイルです。

 

ブラウザーアクションのサンプルの実行

前述のサンプルコードを実際に Microsoft Edge で動作させるには、以下の手順を実行します。

  1. 拡張用の各ファイルを配置するための空の作業フォルダを作成します。
     
  2. フォルダ内に icon という名前でフォルダを作成し、e-19.png という名前で 19 x 19 ピクセルの画像を保存します。
     
  3. テキストエディタに ブラウザアクションの manifest.json のサンプルコードの内容を貼り付け、manifest.json という名前で作業フォルダに保存します。
     
  4. テキストエディタで新しいテキストを作成し、ブラウザーアクションのポップアップ用の html のサンプルコードの内容を貼り付け popup.html という名前で作業フォルダに保存します。
     
  5. 前回の記事の Edge 拡張のテストインストール の内容を参考に Edge に拡張をインストールします。
     
  6. Edge のメニュー[…] ([詳細]) をクリックすると指定した拡張用のアイコンが表示されているので、マウスの右ボタンをクリックして [アドレスバーの横に表示]をクリックします。

     image
     
  7. アイコンがツールバー上に表示され、クリックするとポップアップ画面が表示されるのを確認してください。

なお、ポップアップ画面内には Microsoft Edge 関連 Web サイトへのリンクがありますが、現状、クリックしてもなにも動作しません。

これは拡張の仕様でも HTML の記述が間違っているとかいうのでもなく、たんに Microsoft EdgeHTML 14.14393 の不具合です。(次回のアップデートで修正されるそうです)

今回作成した拡張を Google Chrome にインストールして使用するとポップアップ内のリンクが正常に動作するのが確認できます。

 

アイコンへの情報の表示

ブラウザーアクションの拡張では browserAction.setBadgeText メソッドを使用してアイコンの上に簡単な情報を表示できます。

browserAction.setBadgeText メソッドの書式は以下のとおりです。


 

browserAction.setBadgeText({text: ‘表示したい情報’ });


 

このメソッドを使用して、リンクをクリックした数をカウントして表示するように、ここで作成した拡張を改造してみましょう。

手順は以下のとおりです。

  1. popup.html のソースでコメントアウトされていた以下のタグを有効にします。

      <script src=”clickCounter.js”></script>
     
  2. テキストエディタで新しいテキストを作成し、以下のコードを貼り付けて clickCounter.js という名前で作業フォルダに保存します。

 

以上で拡張の改造は完了です。

現在インストールされている拡張を再読み込みして実行します。

Edge 拡張の再読み込みの手順に再読み込みを行ったあと、拡張のポップアップ画面内のリンクをクリックしてください。

アイコンの上に数字が表示され、ポップアップ画面内のリンクをクリックするたびにカウントアップされていくのが確認できます。

 

image

まとめ

今回はブラウザーアクションの拡張の作成方法について紹介しました。

ポップアップで Web サイトへのリンクを表示するくらいであれば、JavaScript の記述も必要ないということがご理解いただけたかと思います。

次回はページアクション拡張について紹介します。

 

 

<付録>Edge 拡張の再読み込み

Microsoft Edge でテストインストールされている拡張の関連ファイルを再読み込みさせるには以下の手順を実行します。

  1. メニューバーから […] (詳細) メニューをクリックし、[拡張機能] をクリックします。
     
  2. インストールされている拡張の一覧が表示されるので、目的の拡張をクリックします。
     
  3. 選択した拡張の設定画面が表示されるので、 [拡張機能の再読み込み] をクリックします。


 

以上の手順でインストールされている拡張のファイルは新しいものに置き換えられます。

Real Time Analytics

Clicky

Viewing all 51 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>