Buiding JavaScript Games for Phons Tables and Desktop(5)-プレイヤーが何をしているかを知っています.

8435 ワード

プレイヤーは何をしていますか?
この章では、Painterというゲームを作ります.このゲームには、移動する精霊をスクリーンに表示する必要があります.いくつかのロードと表示精霊の例を知っています.そして、経過した時間の値で精霊の位置を変える方法が分かりました.これらの基礎の上でこのコンピュータゲームを作ります.また、ユーザーゲームの入力をどう処理するかを学ぶことができます.これまでのFlyingSpriteの例から、風船の位置に変えてマウスに従って移動します.次の章では、キーボードやタッチパネルなど他のタイプの入力を検出します.
マウスに従って移動する精霊
画面に精霊を表示する方法を知っています.今はユーザーの入力を使って精霊の位置を制御します.これらを行うためには、現在のマウスの位置を知る必要があります.このセクションでは、マウスの位置をどのように取得し、マウスに従って移動する精霊を描くかを教えます.
マウスの位置を取得
例を見てください.このプログラムは前のFlyingSpriteのプログラムとあまり違いません.FlyingSpriteでは、システム時間で風船の位置を計算します.
var d = new Date();
Game.balloonPosition.x = d.getTime() * 0.3 % Game.canvas.width;
位置はballo Position変数に格納されます.現在のプログラムは時間によって位置を計算するのではなく、マウスの位置によって計算します.イベントを使って現在のマウスの値を取得するのはとても簡単です.
javascriptには多くの種類のイベントがあります.よくある事件の例は以下の通りです.
  • マウスの移動
  • マウスをクリックして
  • をクリックします.
  • キー
  • HTMLページのロード
  • ネットワーク接続からの情報
  • 精霊完了ローディング
  • 上記のイベントが発生したら、実行命令を選択することができます.例えば、マウスを動かす時、マウスの位置の値をいくつかのコマンドで取得し、位置情報を保存してから、精霊を描くことができます.例えばHTMLページを読み込むと、documentはウェブページの要素を取得することができます.しかし、より重要なのは、これらの変数はマウスを介してユーザーを移動させたり、キーボードをクリックしたり、タッチスクリーンをクリックして情報を得ることができます.
    これらの変数は既に使用されています.例えば、以下のdocumentを通じてHTMLページからcanvas要素を取得します.
    Game.canvas = document.getElementById("myCanvas");
    
    getElement ById以外にも、documentには他のメンバー変数と方法があります.例えば、オモスクというメンバー変数があります.この変数は数値や文字列ではなく、方法です.マウスを動かすと、ブラウザがこの方法を呼び出します.この方法であなたが書きたいコードを書くことができます.このようなタイプの方法こそ、事件処理と呼ばれます.イベントハンドリングは、ユーザ入力を処理するのに非常に効果的な方法である.
    もう一つの処理ユーザ入力は、ループ毎にユーザの入力を検出する方式である.それでもいいですが、それは利用イベントよりもはるかに遅くなりました.毎回のサイクルで検査しなければならないので、イベント処理はユーザーが何かをしたら自動的に分かります.
    イベントハンドラには特定の書き方があります.このパラメータはオブジェクトであり、イベントに関する情報を提供するパラメータがあります.たとえば、以下に空のイベントハンドリング関数があります.
    function handleMouseMove(evt) {
    // do something here
    }
    
    この関数には単一のパラメータevtがあり、イベントを処理する必要がある情報が含まれています.今はこの関数をOmousemove変数に割り当てることができます.
    document.onmousemove = handleMouseMove;
    
    これからは、マウスを動かすたびに、ハンドルMouse関数が呼び出されます.この関数でevtオブジェクトを通してマウスの位置を得ることができます.例えば、次の例:
    function handleMouseMove(evt) {
    Game.balloonPosition = { x : evt.pageX, y : evt.pageY };
    }
    
    evtオブジェクトの2つのメンバー変数PageXとPageYはマウスの位置を格納しています.位置は左上隅(0,0)から計算します.図5-1では、位置に関する情報がいくつか見られます.
    (図5-1を省略する)
    drawの方法は簡単にマウスの位置で風船を描くだけなので、風船はマウスに付いています.図5−2は、この効果を示している.風船はマウスの針の下にあります.マウスを動かすと風船がマウスに付いてきます.
    (図5-2は省略)
    図5-2からバルーンはマウスの先端の中心位置が現れていないことが分かります.これが原因です.今度は詳しく説明します.この精霊を矩形にします.左上の角がマウスの先端です.風船が先端にそろっていないように見えるのは、風船が丸く、長方形を完全に覆い隠していないからです.
    pageXとpageYの他に、clientXとclientYを使ってもいいし、マウスの位置を表してもいいです.しかし、clientXとclientYはマウスのスクロール値を計算しません.このようにマウスの位置を計算すると、次のようになります.
    Game.balloonPosition = { x : evt.clientX, y : evt.clientY };
    
    図5-3はエラーの所在を教えています.マウスがスクロールするので、clientYは480より小さいです.マウスはもう画像の下に来ました.そのため、バルーンは表が出る位置には現れません.ですから、ずっとPageXとpageYを使うことを提案します.もちろん、場合によっては、スクロール値を位置に入れないことが有益である.
    (図5-3は省略)
    精霊の原点を変える
    Ballowo 1を実行すると、バルーンの左上が現在のマウスの位置になります.精霊を特定の位置に描くと、この精霊の左上がこの位置になります.例えば、以下のこのコマンド:
    Game.drawImage(someSprite, somePosition);
    
    someSpriteの左上の角はsomePositionの位置にあります.左上角が精霊の原点とも言える.原点を変えたいならどうすればいいですか?例えば、精霊の中心を原点にしたい場合は、Image類のwidthとheight変数でこの原点値を計算できます.ここではオリジンという変数を宣言して精霊センターの位置値を保存します.
    var origin = { x : someSprite.width / 2, y : someSprite.height / 2 };
    
    今は精霊someSpriteを違う原点に描きたいなら、こうしてもいいです.
    var pos = { x : somePosition.x - origin.x,
     y : somePosition.y - origin.y };
    Game.drawImage(someSprite, pos);
    
    原点値を減算することで、精霊の原点位置が現在は精霊の中心になります.自分で原点値を計算する以外に、canvas Contectからの方法drawImageで原点偏差値を指定できます.以下のとおりです
    Game.canvasContext.save();
    Game.canvasContext.translate(position.x, position.y);
    Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height,
     -origin.x, -origin.y, sprite.width, sprite.height);
    Game.canvasContext.restore();
    
    上記のような異なる偏差値を設定することにより、精霊の2つの異なる表示方式が得られ、一つの原点は精霊の左上隅であり、一つは精霊の中心であり、図5-4に示すようになる.
    (図5-4は省略)
    JavaScriptの中で他の位置との引き算はちょっと面倒です.
    var pos = { x : somePosition.x - origin.x,
     y : somePosition.y - origin.y };
    
    下にこのように書いてもいいですか?
    var pos = somePosition - origin;
    
    残念なことに、JavaScriptではこれは不可能です.他のいくつかの言語(たとえばJavaとC攂)は、演算子の再負荷をサポートしています.プログラマが自分たちの演算操作を定義することができます.2つのオブジェクトは「+」で加算できます.しかし、全く可能ではないので、対象同士の演算は上記のようにする方法を定義できます.第8章では、これを丁寧に説明します.
    精霊の描き方の違いの原点を知っています.同じように、マウスを風船の底の中心に従って移動させることもできます.例ballo 2はこの考えを実現しました.ここでは原点を格納するための追加変数を定義します.
    var Game = {
     canvas : undefined,
     canvasContext : undefined,
     backgroundSprite : undefined,
     balloonSprite : undefined,
     mousePosition : { x : 0, y : 0 },
     balloonOrigin : { x : 0, y : 0 }
    };
    
    精霊のロード時にのみ原点の計算を行うことができます.したがって、draw方式では、以下のコードから原点を算出します.
    Game.balloonOrigin = { x : Game.balloonSprite.width / 2,
     y : Game.balloonSprite.height };
    
    原点位置は精霊幅の半分ですが、高さは精霊の全高さです.つまり、精霊の底の中心に原点があります.drawメソッドの中で原点を計算するのは一番良くないです.原点を計算するだけのところに現れます.その後、より良い処理方法を発見します.
    今はDRawImage法を拡張するだけで、新しいパラメータを加えて原点値を伝えることができます.以下は実装コードです.
    Game.drawImage = function (sprite, position, origin) {
     Game.canvasContext.save();
     Game.canvasContext.translate(position.x, position.y);
     Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height,
     -origin.x, -origin.y, sprite.width, sprite.height);
     Game.canvasContext.restore();
    };
    
    draw方式では、原点の位置を計算してDRawImageに渡す方法があります.
    Game.draw = function () {
     Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 }, { x : 0, y : 0 });
     Game.balloonOrigin = { x : Game.balloonSprite.width / 2,
     y : Game.balloonSprite.height };
     Game.drawImage(Game.balloonSprite, Game.mousePosition, Game.balloonOrigin);
    };
    
    マウスを使って砲身を回転させます.
    painterゲームの特徴の一つはマウスで砲身を回転させることです.プレイヤーは大砲で風船の色を変えることができます.painter 1の例では、砲身がマウスを介して回転することができます.
    いくつかのメンバー変数を宣言する必要があります.まず背景図と砲身図を格納する変数です.現在のマウスの位置があります.そして砲身の位置の変数などを保存することができます.ゲームオブジェクトはこう見える:
    var Game = {
     canvas : undefined,
     canvasContext : undefined,
     backgroundSprite : undefined,
     cannonBarrelSprite : undefined,
     mousePosition : { x : 0, y : 0 },
     cannonPosition : { x : 72, y : 405 },
     cannonOrigin : { x : 34, y : 34 },
     cannonRotation : 0
    };
    
    砲身の位置と砲身の原点の位置はすでに定義されています.砲身の位置の選択は大砲のベースにぴったりです.砲身の一部は丸い.大砲を円心に従って回したいです.円心が原点という意味です.円形のこの部分は写真の左半分で半径が砲身高さの半分(砲身高さ68ピクセル)なので、原点は(34,34)です.これは上のコードと同じです.
    砲身を角度に見せるためには、スクリーンに砲身を描く時に砲身を回転させる必要があります.canvascontextにrotateの方法があります.
    今はDRawImage法に回転角度に関するパラメータを追加します.以下は新しいdrawImageの方法です.
    Game.drawImage = function (sprite, position, rotation, origin) {
    Game.canvasContext.save();
    Game.canvasContext.translate(position.x, position.y);
    Game.canvasContext.rotate(rotation);
    Game.canvasContext.drawImage(sprite, 0, 0, sprite.width, sprite.height,
    -origin.x, -origin.y, sprite.width, sprite.height);
    Game.canvasContext.restore();
    };
    
    startの方法には、二つの精霊が追加されます.
    Game.backgroundSprite = new Image();
    Game.backgroundSprite.src = "spr_background.jpg";
    Game.cannonBarrelSprite = new Image();
    Game.cannonBarrelSprite.src = "spr_cannon_barrel.png";
    
    次のステップはゲームのサイクルを実現します.今のところ、udateにはまだ何もありません.今から中に物を書きます.砲身の角度を計算する必要があります.この角度はどう計算しますか?図5-5を見てください.
    (図5-5は省略)
    角度は数学の三角関数で計算できます.ここでは、タンジェント関数を使用します.
    tan(angle)=tan(opposite/adjacent)
    スタイルを変えるということは、
    angle=arctan(opposite/adjacent)
    現在のマウス位置と砲身位置の違いを計算することで、隣と反対側の長さを計算できます.以下のとおりです
    var opposite = Game.mousePosition.y - Game.cannonPosition.y;
    var adjacent = Game.mousePosition.x - Game.cannonPosition.x;
    
    上の値から角度を算出することができます.どのように計算しますか?javascriptはMathオブジェクトを提供しています.中には三角関数を含む非常に有用な数学関数が含まれています.二つの関数があります.角度の値を計算できます.最初の関数は単一の関数だけが必要ですが、マウスが砲身の真上にあるときは、除数は0です.
    このような状況を考えると、ここには別の方法があります.apan 2は、隣と反対側の二つのパラメータを用いて角度計算を行う.以下のとおりです
    Game.cnon Rotation=Math.apan 2(opposite、adjacent)
    今udateは次のように見えます.
    Game.update = function () {
    var opposite = Game.mousePosition.y - Game.cannonPosition.y;
    var adjacent = Game.mousePosition.x - Game.cannonPosition.x;
    Game.cannonRotation = Math.atan2(opposite, adjacent);
    };
    
    最後に残ったのはdraw法を使ってこれらの精霊を示すことです.
    Game.draw = function () {
    Game.clearCanvas();
    Game.drawImage(Game.backgroundSprite, { x : 0, y : 0 }, 0,
    { x : 0, y : 0 });
    Game.drawImage(Game.cannonBarrelSprite, Game.cannonPosition,
    Game.cannonRotation, Game.cannonOrigin);
    };
    
    何を習いましたか
    この章で勉強しました.
  • はどのようにイベント処理を通じて現在のマウスの位置を取得しますか?
  • どのように特定の角度で精霊を描くか?
  • どのようにマウスの位置に基づいて角度を変えますか?