Skip to content

お絵描きアプリで学ぶHTML5のCanvas超速入門 #1

みんな元気かな? shi3zだよ。
日本に帰ってきました。

さて、日本に帰って来て一発目の原稿はみんなの大好きなJavaScriptによるHTML5のプログラミングを解説するよ!

今回のサンプルは前回と同じ、http://junk.wise9.jp/game/で試すことができるよ!

続きは以下から

さて、さっそくプログラムを提示しよう。

こういうのは実体験で覚えるのが一番だからね。


Blush=false; //A ブラシの状態を保存している。falsh(偽)に

function onLoad() {
    var canvasDiv = document.getElementById("canvas0"); //B キャンバスDIVを取得
    var myCanvas =document.createElement("canvas"); //C キャンバス要素を追加
    myCanvas.width=320; //D キャンバス要素の幅を設定
    myCanvas.height=480; //E キャンバス要素の高さを設計
    canvasDiv.appendChild(myCanvas); //F キャンバス要素を追加

    var ctx = myCanvas.getContext('2d'); //G キャンバスからコンテキストを取得
    document.addEventListener("mousemove", function(event){ //H マウス移動イベント
        mouseX = event.pageX;
        mouseY = event.pageY;
        if(Blush){ //I ブラシフラグがtrue(真)なら実行
            ctx.beginPath(); //J コンテキストでパス開始
            ctx.moveTo(x, y); //K (x,y)から
            ctx.lineTo(mouseX, mouseY); //L (mouseX,mouseY)まで
            ctx.stroke(); //M 直線を引く
        }
        x =mouseX;
        y =mouseY;

    });
    document.addEventListener("mousedown", function(){ //N マウスボタン押下イベント
        Blush=true; //O ブラシフラグを真(true)に。
    });
    document.addEventListener("mouseup", function(){ //P マウスボタン離されたイベント
        Blush=false; //Q ブラシフラグを偽(false)に
    });
}

例によってコピペすると動くのでぜひ試してみてほしい。
マウスボタンを押している間は線を引く。それだけだ。

ほぼ総ての行にコメントがついているという病的なまでの展開に我ながらびっくりだ。

まず、Aで「Blush」という変数を定義し、falseという値を入れている。
このfalseという値は、数字ではないが、数字と同じ扱いになる特殊な記号で、日本語では「偽(ぎ)」と呼ばれる。

falseの反対はtrueで、日本語では「真(しん)」。
ふたつあわせて「真偽(しんぎ)」となる。

この真偽は特別な値で、とくにifでの判定で用いる。
if(Blush)としたときに、Blushがtrueの時はifは成立し、Blushがfalseの時はifは成立しない。

こういう真偽しかでてこない変数をブーリアン(boolean)変数やフラグ変数と呼ぶ。

よく、ネット用語「フラグ立った」という言葉があるけど、そのフラグだ。
フラグが立つ、というのはフラグ変数が真(true)になることを言う。

このフラグ変数は、ゲームなどではある条件が成立したときに真(true)になる。
ある条件とは、「プレイヤーの魅力値が100を超えたのでヒロインがプレイヤーに対してツンモードからデレモードに移行する」ような条件で、このとき「デレフラグ」が立つ(tureになる)わけだ。

死亡フラグ」とかも同様で、そのフラグが立つと死亡する、というスラングだ。覚えておこう。

さて、お絵描きをするためにはいろいろと準備が必要だ。
shi3z式ゲームプログラミング入門」では画像ファイルをキャラクターとして表示したり、ラベルで文字やHTMLを表示したりといったことをやった。

しかし、自由に絵を描くには「キャンバス(canvas)」というHTML要素を作る必要がある。

これはHTML5で最初に作られた新しい要素で、これによってHTML5は非常に多彩な表現力を獲得した。

ぜひとも使いこなしたい機能のひとつだ。
この連載ではCanvasの使い方について順に学んでいこうと思う。

Bの行では、もともとのHTMLに置かれている「canvas0」という名前のdiv要素を獲得している(ややこしいが)。

div要素とは、HTMLのある領域を意味する要素で、ここにcanvas要素を追加しているのがCからFの行だ。

Cの行では「myCanvas=document.createElement(“canvas”)」として、キャンバス要素オブジェクトを作成し、myCanvas変数に格納している。

document.createElement関数を使うと、任意のHTML要素を作成することができる。
作成したい要素のタグをパラメータとして指定するだけだ。

D、Eの行では作成したキャンバス要素の幅(width)と高さ(height)を決めている。

Fの行で、作成したキャンバス要素オブジェクトmyCanvasを、div要素に追加(appendChild)している。

これでお絵描きの準備は完了だ。

キャンバス要素をつくると、ふつうのHTMLではできない、斜めの直線や円などをグラフィックを使わずに描くことができる。

そのためにはコンテキストオブジェクトというものを作る必要がある。
そのコンテキストオブジェクトを作っているのがGの行だ。

myCanvasに対するコンテキストオブジェクトを創り、ctxという変数に格納している。

さて、コンテキストオブジェクトとはなんだろうか?
常に一足飛び、拙速主義で解説することが身上のこの連載でも、コンテキストオブジェクトとかいうわけのわからないものが突然でてきたらさすがに戸惑うと思う。

キャンバス要素オブジェクトは、文字通りそれだけではただの真っ白なキャンバスだ。
それだけではなにも描けない。

コンテキストオブジェクトは、いわばペンケースのようなものだと思えばいい。

それがctx変数に格納されているわけだ。

さて、次だ。
マウスによる操作をどう扱うか。

shi3z式ゲームプログラミング入門」では、マウスの状態はmouseXとmouseYによって取得していた。これは僕が用意した「ゲームのもと」のなかで自動的にマウスの座標をmouseXとmouseYに保存するようにしていたからだ。

今回はゲームではなくお絵描きソフトを作るので、マウスを直接扱ってみよう。

HTML5、そしてJavaScriptではマウスの動きやタッチパネルへのタッチなどは、「イベント」という考え方で制御される。

マウスが動くと「マウスが動いた」というイベントが発生し、「マウスが動いた」イベントに対応するコールバック関数が呼び出される。

たとえば「shi3z式ゲームプログラミング」でmouseXとmouseYにマウス座標を保存していたコールバック関数の中身はこんな感じだ。


function onTouchmove(event){
    mouseX = event.pageX;
    mouseY = event.pageY;
}

onTouchmoveコールバック関数はマウスが移動するイベントが発生する度に呼び出されるコールバック関数だ。それぞれevent.pageXをmouseXに、event.pageYをmouseYに保存しているだけだ。

コールバック関数のeventパラメータにはイベントに関係する情報が渡される。
event.pageX、event.pageYがそれぞれマウスのX,Y座標に対応した変数だ。

これと同じ感じでHからのコールバック関数が記述されている。
もう一度Hの行を見てみよう。


    document.addEventListener("mousemove", function(event){ //H マウス移動イベント

document.addEventListener関数は、イベントが発生したときのコールバック関数(リスナー関数)を設定する。

ここではコールバック関数として無名関数を渡している。
JavaScriptではコールバック関数をこんなふうに名前をつけずに定義することができる。

この機能は非常に便利だ。

マウス移動イベントを処理するコールバック関数の中身は非常に単純だ。

I、J、K、L、Mの各行で、直線を引いている。
Iの行は、ブラシフラグが立っていたら、直線を引くという判定をしている。
つまりこの行によってペンがキャンバスに押し付けられているかどうかを表現しているわだ。

Jのctx.beginPathでパス(線)を書き始めることをコンテキストに指示し、Kのctx.move関数で直線の開始座標を(x,y)にセット、それからLのctx.linetTo関数で直線を座標(mouseX,mouseY)まで描画することを指示、最後にctx.stroke()で実際に直線を引く、というわけだ。

このあたりの書き方ははっきりいって、泥臭いし面倒くさい。

なぜctx.line(x,y,mouseX,mouseY)ではだめなのか。
このほうがよほどわかりやすいではないか。

このあたりは、キャンバス要素クラスを設計したどこかの偉い人の好みによるものなので、あまり文句を言っても仕方が無いんだけど、それでもなんか腑に落ちないものは感じる。

このあたりは本当に儀式的なところなので、必要に迫られるまでは呪文のようなものだ、と覚えておけばOKだ。

さて、NとPの行ではまた別のイベントリスナー(イベントで呼び出されるコールバック関数)を定義している。

Nの行ではマウスのボタンが押された、というmousedownイベントを。Pの行ではマウスのボタンが離された、というmouseupイベントを定義している。

いずれもコールバックの中身は、Blushフラグを立てたり(trueにする)下ろしたり(falseにする)だけだ。

このコールバックによってマウスボタンが押されている間はBlushがtrueになり、マウスボタンが離されている間はBlushがfalseになる、という処理を実現している。

なんと、たったこれだけのプログラムで、お絵描きができてしまう。
次回はもう少し突っ込んでいろんなことをしてみよう。
ではまた次回

練習問題

・マウスボタンを離している間は描いて、押している間は描かないようにしてみよう
・moveToの(x,y)座標を入れ替えて(y,x)に変えてみたらどうなるだろう?

このエントリーをはてなブックマークに追加
はてなブックマーク - お絵描きアプリで学ぶHTML5のCanvas超速入門 #1
Post to Google Buzz
Share on GREE

Related posts:

  1. shi3z式ゲームプログラミング入門 #2 あと48時間でゲームプログラマになる方法
  2. shi3z式ゲームプログラミング入門 #3 “ゲームらしく”する
  3. Kinectでキミもアイアンマンになれる!?(実装編)/バイナリとソース付き
  4. shi3z式ゲームプログラミング入門 #1 72時間でゲームプログラマになる方法
  5. かんたんプログラミング #1:亀の子グラフィック

Facebook comments:

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*