Canvasはゲームの実践を共有します(一)


最近何冊かの外国人の本を読んで、いくつかの大神たちのブログを勉強して、火の大変なcanvasに触れてゲームをして、自分の学習過程を分かち合いました.
1.ゲームの基本
1.1アニメーションとは
アニメーションは、一連の画面を連続的に再生することで、視覚を連続的に変化させる絵です.その基本原理は映画、テレビと同じように、視覚原理です.医学はすでに証明して、人類は視覚の暫定的な特性を持って、つまり人の目は1枚の絵あるいは1つの物体を見た後に、1/24秒以内に消えません.この原理を利用して、1枚の絵が消える前に次の絵を再生すると、スムーズな視覚変化効果が得られます.そのため、映画は毎秒24コマの速度で撮影放送され、テレビは毎秒25コマ(PAL制、中央テレビのアニメはPAL制)または30コマ(NSTC制)の速度で撮影放送される.毎秒24枚未満の速度で撮影再生すると、ストップ現象が発生します.
再生効果では、シーケンスアニメーション(連続動作)とインタラクティブアニメーション(繰り返し動作)に分けられます.フレーム単位アニメーションは一般的なアニメーション形式(Frame By Frame)であり、その原理は「連続キー」でアニメーション動作を分解することであり、つまり時間軸のフレームごとに異なる内容をフレームごとに描き、連続的に再生させてアニメーションにすることである.
1.2 HTML 5を使った動画作成
HTML 5で作成されるアニメーションは、主にフレームごとのアニメーションです.現在は主にDOM,SVG,Canvasの3つの方式で実現されている.ここでは主にCanvas方式でアニメーションを作成することについて議論します.Canvasのサポート
これまで、基本的なすべてのブラウザの最新バージョンはcanvasの全面的なサポートを提供してきました.「漸近的に強化され、優雅にダウングレードされた」モバイルインターネットアプリケーション体験に基づいて、ユーザーが使用するブラウザのバージョンが低い場合は、canvasラベルに情報を書き込み、ブラウザのアップグレードを促すことができます.次のようになります.
<canvas>           ,        </canvas>

プログラミングを使用してcanvasのサポートの程度を検出する場合は、次のコードを使用します.
if(document.createElement(“canvas”).getContext(“2d”)){
         console.log(“       canvas”);
}

もちろん、サードパーティのオープンソースJavaScriptライブラリ(http://code.google.com/p/explorercanvas/)、canvasをサポートしていないブラウザでcanvasの様々なAPIをシミュレートします.各デバイスとブラウザのバージョンの実装方法が異なるため、ユーザーが一致した体験を得ることを保証するために、できるだけ多くのデバイスとブラウザで私たちのゲームをテストし、最適化する必要があります.HTML 5基本ドキュメントテンプレート私たちのゲームは、HTMLドキュメントのcanvasラベルでレンダリングする必要があります.ここでは、最も基本的なHTMLドキュメントテンプレートを作成します.次のように
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>base canvas</title>
<link rel="stylesheet"  type=”text/css”   href="style.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type=”text/javascript”>
window.onload = function () {

};
</script>
</body>
</html>

簡単に見ると、最初はHTML 5のドキュメントタイプを定義し、その後はヘッダーラベルを定義し、外部のCSSファイルを参照しました.次にbodyにcanvasラベルを定義して、私たちのゲームレンダリングコンテナにします.bodyタグが終わる前にscriptタグを作成し、JavaScriptを使用してゲームを実現します(headerでlinkタグを使用して外部cssファイルをロードしたり、bodyがラベルを終了する前にscriptタグを定義したり、外部JavaScriptファイルを導入したりするのは、ページの逐次表示速度を保証し、閲覧器がHTMLページをより効率的にレンダリングし、スクリプトダウンロードの並列度を高めるためです.Steve Souders大神の『高性能ウェブサイト建設ガイドライン』).スクリプトでは、Windowsオブジェクトのonloadイベントにコールバック関数を指定します.つまり、すべてのドキュメント要素のロードが完了した後、コールバック関数のプログラムを実行します.これにより、canvasラベルが使用される前に作成されたことが保証されます.もちろん、現在のHTMLドキュメントに大量のリソース(画像、音楽など)がロードされる必要がある場合は、window.onloadイベントは実行に長い時間待たなければなりません.この場合、スクリプトを使用して対応するリソースを動的にロードすることが望ましいので、後で関連する知識を説明します.その他
 
開発ゲームの複雑さが増すにつれて、私たちのコード量とプログラムの複雑さが増加します.これは、ゲームをモデリングし、コードを一定のルールで外部スクリプトファイルに配置して導入する必要があります.
また、ゲーム開発における良いエディタとデバッグツールも、半分の効果を得ることができます.ここではsublime text 2をエディタとして使用し、chromeの開発者ツールをデバッグツールとして使用します.
 
1.3フレーム単位のアニメーション
 
canvasアニメーションはフレーム単位のアニメーションなので、アニメーション内の各フレームのレンダリングを制御するループが必要です.各フレームのアニメーションのレンダリングは、次のようになります.
a.現在のフレーム動作を計算するすべてのコードを実行し、その結果canvas APIを呼び出してメモリに入れる
b.メモリの現在のフレームをcanvasコンテナにレンダリングする
c.次のフレームの処理フローに進む(通常はこの時点でキャンバスを消去する)
JavaScriptでは、settimeoutとsetIntervalが通常、関連するタイミング呼び出しに使用される2つの関数があります.settimeoutはコールバック関数を1回のみ実行し、setIntervalはXミリ秒ごとに関数を実行します.しかし、この2つの関数はいずれもゲームの開発のために生まれたものではなく、いくつかの問題がある.
JavaScriptエンジンのタイミングポリシーと本質的な単一スレッドの実行方法に基づいているため、他のコードの実行がこのスレッドをブロックする可能性があります.したがって、settimeoutで指定された時刻に関数が呼び出されることは保証できません.コールバック関数の実行がブロックされると、setIntervalはより多くの破壊命令を発行します.非常に小さなタイミング間隔では、コールバック関数が蓄積されます.したがって、通常、setIntervalを使用するのではなく、settimeoutを使用することを推奨し、最も簡単な処理コールバック関数がブロックされている場合は、コールバック関数でsettimeoutを呼び出すことである.(具体的にはJavaScript Garden http://bonsaiden.github.com/JavaScript-Garden/zh/参照).
しかし、アニメーションのスムーズさの要求が高まるにつれて、同時に実行されるタイマが大量にある場合、これらのタイマ間のスケジューリングはパフォーマンスにわずかな影響を及ぼします.1つの解決策は、フレーム管理を採用したアニメーションフレームを実現し、1つのタイマによってアニメーションフレームをトリガし、異なるアニメーションによってこれらのフレームを登録し、各フレームで複数のアニメーションの属性変化を処理することである.このような利点は、タイマスケジューリングのオーバーヘッドを低減することであるが、アニメーションフレームワークの開発者にとって、フレーム管理を統一し、フレームを傍受するAPIを提供するなど、開発とメンテナンスが必要である.ブラウザベンダーは現在、ブラウザレベルでフレームアニメーションを最適化するrequestAnimationFrame()というアニメーション専用の方法を提供しています.以下のコード例を参照してください(http://paulirish.com/2011/requestanimationframe-for-smart-animating/)。参照).
window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    || 
              window.oRequestAnimationFrame      || 
              window.msRequestAnimationFrame     || 
              function( callback ){
                window.setTimeout(callback, 1000 / 60);
              };
    })();
(function animloop(){
      requestAnimFrame(animloop);
      render();
})();
 
 
 
1.4 JavaScriptオブジェクトの知識
JavaScriptはオブジェクトベースの言語で、変数、関数、または他のオブジェクトであってもよい属性を含む特殊なデータ構造です.同時にJavaScriptオブジェクトはいつでも動的に変更できます.次のようになります.
 
var  objectA={};
objectA.name=”objectA”;

同じタイプのオブジェクトを同時に作成する必要がある場合は、コンストラクション関数の形式を使用します.JavaScriptのコンストラクション関数は、独自に設定した属性に基づいてオブジェクトを生成する特殊な関数です.コンストラクション関数を作成すると、newキーワードを使用してオブジェクトを生成できます.次のようになります.
function Animal(name){
       this.name=name || “animal”;
       this.say=function(){   console.log(this.name);
}

var dog=new Animal(“dog”);   dog.say();
var cat=new Animal(“cat”);    cat.say();

JavaScriptはプロトタイプベースの言語です.新しいオブジェクトインスタンスを作成すると、コンストラクション関数のプロトタイプチェーンを継承するオブジェクトが作成されます(詳細は、JavaScriptオブジェクト向けプログラミングおよびhttp://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.htmlまたはhttp://7685941014.blog.163.com/blog/static/124615480201061782347164/を参照).
function Person(name){  
       this.name=name;  
       console.log(this.name); 
}

 function Student(name,school){  
       Person.call(this,name); 
       this.school=school; 
}

Student.prototype=new Person();
Student.prototype.constructer=Student;

JavaScriptの関数もオブジェクトなので、関数に属性やメソッドを設定できます.例えば、多くの場合、私たちが使用するコールバック方法などです.次のようになります.
var person=[“Jim”,”James”,”Kimmy”]; 

person.forEach(function(o,i){   console.log(i+”,”+o);  }

forループを直接構築するか、forEachメソッドを使用してArrayのすべての要素を巡回するか、Arrayオブジェクトの要素数が多い場合、forEachメソッドを使用すると効率的に問題が発生します.これと同様に、for...inループを使用してオブジェクトのすべてのプロパティを巡回する場合、オブジェクトのプロトタイプチェーンのネスト階層が深い場合、効率に問題が発生します.(for...inは、Arrayのlength属性などのenumerableがfalseである属性を遍歴することはできません).
 
1.5ユーザー・インタラクション
ゲームの核心はユーザーインタラクティブ性にあり、ユーザーインタラクティブはイベントに基づいている.イベントには、リスナーおよびイベント処理が含まれます.canvas上に描画されたグラフィック自体はDOMイベント検出をサポートせず、canvasラベル自体だけがDOM全体のリスニングをサポートします.そのためcanvasコンテナのイベントを処理し,相対イベントの傍受と処理を実現する必要がある.
W 3 C仕様http://www.w3.org/TR/DOM-Level-3-Eventsを選択すると、次のようにオブジェクトにイベントを登録できます.
element.addEventListener(type, handler [, useCapture]);

典型的なマウスのクリックを傍受するイベントは次のとおりです.
canvas.addEventListener('mousedown', function (event) {
      console.log("Mouse pressed on element!");
}, false);

すなわち、各オブジェクトは指定されたイベントトリガイベントを購読し、そのイベントがトリガーされると、その情報を購読したすべてのオブジェクトにこの情報がブロードキャストされ、このオブジェクトは対応するイベントトリガコールバック関数を呼び出して処理される.イベントをログアウトしたい場合は、
element.removeEventListener(type, handler [, useCapture]);
 
マウスイベント
 
マウスイベントには、mousedown、mouseup、mouseoverなどがあります.マウスの位置を取得する必要がある場合は、mousemoveイベント応答を傍受した後、次の処理を行います.
var utils={};
utils.cpatureMousePosition=function(element){
     var mouse={x:0,y:0};
     element.addEventListener("mousemove",function(event){
           var x,y;
           if(event.pageX||event.pageY){
                  x=event.pageX;
                  y=event.pageY;
           }else{
                  x=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;
                  y=event.clientY+document.body.scrollTop+document.documentElement.scrollTop;
           }
           x-=element.offsetLeft;
           y-=element.offsetTop;
           mouse.x=x;
           mouse.y=y;
       },false);
       return mouse;
};

具体的には、各ブラウザのマウス位置に対する処理の実装方法が提供されるインタフェースと異なるためです.http://www.seobye.com/div-css/87/およびhttp://javascript.about.com/library/blmousepos.htmを選択します.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Get Mouse Position</title>
<link rel="stylesheet"  type=”text/css”   href="style.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type=”text/javascript”>
window.onload = function () {
              var canvas=document.getElementById(“canvas”);
              var mouse=utils.captureMousePosition(canvas);
              (function drawFrame(){
                            window.requestAnimFrame(drawFrame,canvas);
                            console.log(mouse.x+”,”+mouse.y);
              })();
};
</script>
</body>
</html>

キーボードイベントには、keydownとkeyupの2つのキーボードイベントがあります.イベントを通過できます.keyCode (https://github.com/lamberta/html5-animation/blob/master/xtras/keycode.js)を使用して、現在のキーボード値のASCII値を取得します.次にswitchを用いて具体的なキーを区別して処理する.次のようになります.
element.addEventListener(“keyup”,function(event){
              switch(event.keyCode){
                   case:   break;
             }
},false);