enchant.js Developers Blog

The Latest News on the HTML5 + JavaScript Game Engine enchant.js

Archive for the ‘Tutorial’ Category

やあみんな。shi3zだよ。

三日間の短期集中連載だからガンガンポストしていくよ。

さて、前回の最後のプログラムは実行してみたかな?
マウスカーソルに不思議な動きで宇宙船がついてくるね。

この動きの秘密は、もちろんプログラムにある。

ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

ひとつずつ解説しよう。

(続きは以下から)

まず、this.xのあとに続く記号、+=は、this.xに右の式の値を足し込むという意味になる。
this.x+=1だと、this.x=this.x+1と同じ意味になるわけ。これはゲームでは異常によく使う記号だから覚えておこう。

次に、mouseXという謎の変数が突然出てくる。
これはお察しの通り、僕の作った最速ゲーム学習用システムが用意している変数だ。

この変数には常にマウスカーソルのX座標が格納されている。
ではmouseYには・・・そう。マウスカーソルのY座標だ。

この式は、mouseXからthis.xを引いた値を10で割ったものをthis.x自身に足し込んでる。

これは一体どういうことなのか?

まず、プログラムとしてはマウスカーソルに宇宙船を近づけたい。
それにはいくつか別のもっとわかりやすい方法もある。

例えば次のようなプログラムだ。

ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
if(this.x > mouseX) this.x-=10;
if(this.x < mouseX) this.x +=10;                if(this.y > mouseY) this.y-=10;
if(this.y < mouseY) this.y +=10;
};

こんどは動きはどう変わっただろうか?前回のコードではヌルっという動きでマウスカーソルをまっすぐ追いかけた。

今回のコードでは斜めにしばらく進んだ後、横または縦方向にまっすぐカーソルを追いかけてくるようになるはずだ。

この動きの差はどうしてうまれるのか?すべての秘密はソースコードにある。

前回示したコードより、後者のif文を沢山使ったコードのほうが理解しやすいはずだ。

もし、自分の位置(this.xとthis.y)がマウスの位置と違ったら、それぞれ10ドットずつ移動しろ、という命令を書いているわけだね。

けれども、カーソルがたとえば45度以外の斜め方向に居るとき、x、yの増加量はともに10ずつとなって、結局斜め45度の動きになってしまう。

この動きは非常にぎこちなく、なんだか変な感じだ。

それにくらべると、最初の例に用いた式は、シンプルだが効果的だ。

この数式がどういう動きを生み出すのか。下の図を見てほしい。

マウスカーソルの座標から宇宙船の現在座標を引くと、これは宇宙船からマウスカーソルへ伸びるベクトルになる。

これを足すと、宇宙船がいきなりマウスカーソルの位置にワープすることになる。

これはもっとシンプルなプログラムで試すことができる。

       ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
this.x += mouseX-this.x;
this.y += mouseY-this.y;
};

10で割るのをやめてみると、いきなり宇宙船がマウスカーソルに張り付いたような動きになるはずだ。

これを10で割ることで、マウスカーソルに近づけば近づくほど細かい動きになっていき、あの独特のヌルっとした動きになるのだ。

このヌルっとした動きがなんとなく「気持ちよく」感じられるのはなぜだろうか?

ひとつはこの動きにリアリティ(現実感)があるからだ。

実は、こうした動きは実際のモノの動きに良く似ている。

クルマは急に止まれない、という言葉があるけれど、本当に急に止まれない。
止まるには少しずつ減速していかないとならない。

全速力で走っていて、急に止まろうとしたら勢いで二三歩余計に歩いてしまう、そんな経験が誰にもあるだろう。

そういう感覚がこうした動きにはあるのだ。

さて、宇宙船しかいなかったらつまらないから、宇宙船以外のものも表示してみよう。

宇宙だから岩がいい。それにはforループを使うのが簡単だ。

function onLoad() {     var ship= new Image('img/starship.png');
ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

for(i=0;i<10;i++){
rock = new Image('img/rock.png');
rock.x = Math.random()*320;
rock.y = Math.random()*480;
}
gameStart();
}

実行すると次のような画面になる。

白い宇宙空間に岩がゴロゴロ。
小惑星、というわけだ。

ところがこの宇宙船、小惑星にぶつかってもびくともしない。
それではつまらないから、小惑星にぶつかったらゲームオーバーになることにしよう。

function onLoad() {
var ship= new Image('img/starship.png');
ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
this.x += (mouseX-this.x)/10;
this.y += (mouseY-this.y)/10;
};

ship.onHit = function(){ //衝突した!
alert("CRASHED!");
}

for(i=0;i<10;i++){
rock = new Image('img/rock.png');
rock.x = Math.random()*320;
rock.y = Math.random()*480;
}
gameStart();
}

ただし、これは極めていい加減なプログラムなので、衝突すると「CRASHED」という警告ウィンドウが出続ける。

やめるにはマウスカーソルを正しい位置に逃がして、リロードする必要がある。

alertは、JavaScriptが元々もっている命令(関数)のひとつで、警告ウィンドウを表示する機能を持っている。
ship.onHit関数もまた、システムが呼び出す特別な関数で、なにか他のImageと衝突したときに呼び出される。

この場合、宇宙船(ship)がなにか別の物体とぶつかったとき、警告ウィンドウを表示する、というゲームになったわけだ。

これをもとにして、以下の課題に挑戦してみよう。また次回。次回はすぐだよ

1)rockをforループと乱数を使わずに並べて、電流イライラ棒ゲームを作ってみよう
2)rock.tickを定義して、隕石のほうも動かしてみよう
3)動く隕石と動かない隕石を作ってみよう

  • コメントは受け付けていません。
  • Filed under: Tutorial
  • やぁみんな!元気かな? shi3zだよ。

    さてさて、先日の環太平洋ミニゲーム開発オリンピック、個人的には参加する方としても見ている方としても大いに楽しめたんだけど、まあ正直、自分が優勝しちゃったのはどうかと思うんだよね。まあ立場もあるし、気を使ってくれたのかもしれないけど、とにかく、僕は次回からは参加しないことにしたんだ。

    でもこれって結構面白くて、ミニゲームそのものもそうだけど、この大会というひとつの大きな枠組みのゲームとして、ハマってきた。

    だからもう一回やりたい。

    と言ったら鎌田君が「いいですね。でも僕はもう体力の限界です」というのでリタイヤ。TAZZY委員長は仕事が忙しすぎてやってられないということで、近藤君と伏見君の二人だけになっちゃう、というのもつまらない。

    そこで、プログラム完全未経験のHidemyに僕がゲームプログラミングを三日でコーチし、大会で闘えるところまで育てることができるか!?という挑戦をしてみることになったよ。そんなこと本当にできるのかね?

    続きは以下


    実は昨日、alan先生からもらった連載原稿を先に全部出しちゃったのは、まずHidemyにプログラミングを学んでほしかったからなんだ。

    正直、教育学部卒で英文学専攻という彼女がどのくらいのスピードでこれをマスターできるかは多いに疑問だったんだよね。

    とりあえず昨日の夜、みんなでご飯を食べたあと、「Hidemyはalan先生の原稿を読んでから、自分なりのプログラムを作って提出して」と課題を与えてみた。

    それが八時くらい。

    そして12時。つまり四時間後だけど、早速Hidemyから課題が届いた。

    //おはな
    function flower(){
    for(i=0;i<180;i++){
    if( i<10 ){
    move(2);
    turn(1);
    }if( i>170 ){
    move(2);
    turn(1);
    }else{
    move(1);
    turn(1);
    }
    }
    }

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<9;j++){
    flower();
    turn(90);
    }
    penUp();
    }


    これ以外にもふたつのプログラムをつくってきてくれた。

    彼女の飲み込みの速さに結構驚いたね。

    これならいけるかもしれない

    と思ったよ。

    そこでalan先生の連載とは別に、僕がゲームプログラミングを教える短期集中連載を始めることにするよ。

    alan先生の連載は丁寧でわかりやすいけど、ちょっと時間がかかるので、ここでは一足飛びに僕がゲームを学ぶために必要な教材をまとめてzipにしてみた。

    まずはこれをダウンロードしてほしい

    ゲームのもと(game.zip)をダウンロード

    とはいっても、alan先生の連載とファイル構成は似ている。

    違うのは、game.jsというファイルとimgフォルダがあることくらい。

    まずはmain.jsをテキストエディタで開いてほしい。

    例によって面倒だという人のために、ブラウザ上で試す環境も用意してある。

    http://junk.wise9.jp/game/

    さて、最初のプログラムはゲームのキャラクターを表示するものだ。

    function onLoad() {
    banana = new Image('img/banana.png'); // ここでキャラクターを出現
    }

    このプログラムのポイントは 「new Image」という部分にしかない。

    この命令は、新しいImageを作成してbananaという変数に入れろ、という意味になる。

    このImageというのは、実はゲームプログラミングを最速で教えるために僕が定義した新しいプログラムだ。
    実は、JavaScriptではプログラムの中から別のプログラムの塊を呼び出すことができる。

    こういうプログラムの塊を「クラス」とか「ライブラリ」とか言ったりするんだ。
    クラスとライブラリは本質的に別のものだけど、今回はそんなことを理解する必要はない。興味が湧いたら自分で調べてみてほしい(きっとそのうちalan先生の連載で扱うだろう)。

    とにかく、ゲーム開発に必要なことで、面倒なだけのことはあまりにも多い。
    そこで今回はオリジナルのゲームを作るために本当に最低限しかプログラムを書かなくてもいいように教材の方を工夫した。料理で言えばレトルト食品みたいなものだ。
    味は最高に良いとは言えないが、誰でも調理できてそこそこ美味しい。そういう連載なのだと思ってほしい。

    こうしたクラスにはクラスを設計したプログラマの経験が総て詰まっている。
    そのひとつが、このImageクラスというわけだ。

    秘伝のタレ、みたいなものだね。

    さて、このプログラムを実行するとどうなるか、まずは試してみてほしい。

    ここで注意事項。
    ゲームプログラムは、過激なプログラムだ。
    だから、「ゲームを実行する」というボタンを押したら、止めたりソースコードを書き直したりしたくなったら一度リロードする必要がある。

    リロードしても君の書いたコードが消えることはないのでご安心を。

    さて、new Imageのあとにつづく謎の文字の説明をしなくてはならない

    new Image(‘img/banana.png’);

    これは言わずと知れた「ファイル名」である。「img」はフォルダ名を指し、banana.pngはファイル名となる。フォルダとファイル名の間は「/」で繋ぐことになっている。まあこのへんはわりとお馴染みかな。

    banana.pngにはバナナの画像が入っている。
    バナナには見えないかもしれないが、これは断じてバナナである。
    実は今回のzipファイルには、ゲーム作りに最低限必要と思われる画像ファイルをこちらで用意したものを添付してある。

    バナナ以外にも、いろいろあるからフォルダを覗いてみてほしい。
    さて、次はキャラクターを動かしてみよう。
    バナナがひとりでに動く、というのも気持ち悪いので、宇宙船の絵に変えてみる。
    以下のようなプログラムを動かしてみてほしい。

    function onLoad() {
    ship = new Image('img/starship.png');  //A
    ship.tick = function(){ //B
    this.x = this.x + 1;//C ここで宇宙船の動きを定義する
    };
    gameStart(); //D
    }

    いくつか新しい命令が出て来た。

    Aの行でImageをshipに代入しているのはいいとして、Bの行はなんだろう?

    実はJavaScriptの変数は総てオブジェクト変数といって、数字だけでなくプログラムも入れることができるようになっている。

    ship変数のなかにtickという関数を定義しているわけだね。
    このtickは一定時間ごとに呼び出される特殊な関数だ。

    tickの中身を見てみよう(C)これも単純だね。

    this.x = this.x +1 ;

    this.xに1を足したものをふたたびthis.xに代入している。
    このthisが示すのはこの関数が定義されているオブジェクト自身、この場合はたとえばship自身を指しているんだ。this.xがあるということは当然、this.yもある。しかしこの式はなにをしてるんだ?

    実はこれは学校で真面目に数学をやっていると、けっこう混乱してしまう部分のひとつだ。

    「こんなthis.xはあり得ない」

    と思ってしまうのだ。しかしこの式はあくまでも代入式であって方程式ではない。解くための式ではないのだ。

    どうしても意味が分からないのなら、次のようなイメージで理解すると良い。

    this.x ← this.x +1 ;

    右のthis.xは過去のthis.xであり、左のthis.xは未来のthis.xである。矢印の向きで覚えると良いのだ。

    たとえばこの式の実行時点でthis.xの内容が0なら、この式が実行されたあとのthis.xの中身は1になる。

    実際、プログラミングで最初につまづくポイントがこの代入式と方程式の違いがわからないというところだったりする。

    解ればあまりにも簡単だが、いきなりそれまで習って来たことの前提が覆ってしまうと人はビックリしてしまうものだ。

    さて、これを実行すると、宇宙船が画面の中央に現れて、ゆっくり右へ移動していくのが見えると思う。

    一定時間ごとにthis.xに値を足していくと、this.xの座標が変わるワケだ。

    さて、一回目なのでそろそろやめにしたいが、最後にキャラクターを自分の思うがままに動かすプログラムを示して終わろうと思う。詳しい解説は次回行う。

    是非試してみてほしい。

    function onLoad() {
    ship = new Image('img/starship.png');
    ship.tick = function(){ //宇宙船がマウスカーソルを追いかける
    this.x += (mouseX-this.x)/10;
    this.y += (mouseY-this.y)/10;
    };
    gameStart();
    }
  • コメントは受け付けていません。
  • Filed under: Tutorial
  • 前回、ゲームを作ってみます、と言ったのですが、「shi3z式ゲームプログラミング」が始まってしまったのでこの連載では引き続き粛々とプログラミングの楽しさを紹介していきたいと思います。

    さて、今回のテーマは「再帰(さいき)」です。

    再帰・・・再び帰ってくる。まるで宇宙探査機はやぶさのようです。

    今回のテーマを学ぶとこんな図形を描けるようになりますよ

    さあやってみましょう

    (続きは以下のリンクから)

    前々回、関数というものを学びました。

    ところで関数の中からさらに関数を呼んでみるとどうなるでしょう?

    ・・・というのは説明するまでもないかもしれませんね。

    なにしろいままでonLoadという主たる処理を書いていた関数から、さらに自分で定義したcircleやrandという関数を呼び出して使っていた訳です。

    そう。もちろん、関数の中から関数を呼び出すことも簡単にできるんです。

    では・・・関数から関数自身を呼び出したらどうなるでしょうか・・・

    実は・・・大変なことになります。
    下のコードはサンプルですが、決して実行しないで下さい。ブラウザが壊れることがあります。

    function onLoad(){
    onLoad(); // こうしたらどうなる?
    }


    Safariなどの賢いブラウザは、こんなふうに警告を発してくれます。
    この警告はどういう意味でしょう?

    maximum call stack size exceeded(最大コールスタックサイズを超えました)」

    実は、ここに関数呼び出しの秘密があります。
    関数は自由に呼び出せるが、無限に呼び出せる訳ではないのです。

    つまり「最大」の呼び出し数が決まっているということで、それが「コールスタックサイズ」なのです。

    onLoad関数のなかで無条件にonLoad関数を呼ぶと、それは無限に新しいonLoad関数を呼び出してしまいます。

    すると、最大コールスタックサイズがどれだけ大きく設定されていたとしても、確実に最大コールスタックサイズを超えてしまうのです。

    通常は十分なだけのコールスタックサイズが設定されているのですが、どれだけ大きなコールスタックサイズを確保したとしても、無限にあるわけではないので必ずエラーになります。

    こんな危険な機能・・・つまり自分自身を呼び出す関数という機能はなぜ実装されているのでしょうか?

    実は関数が自分自身を呼び出す機能、というのは、上手く使えば非常に有効な道具になってくれるのです。それが「再帰」というテクニックです。

    以下のコードを見て下さい。

    function onLoad(){
    var proc = function(t){
    if(t<1) // tが1未満になったら再帰をやめる
    return;
    for(var i=0;i<360;i++){ //円を描く
    move(t);
    turn(1);
    }
    proc(t*0.8); //tに0.8を掛けて再び円を描く
    };
    penDown();
    proc(3);
    logo.penUp();
    }

    実行すると下のようになります。

    今度はブラウザもおかしくならずにうまく動作しました。

    これはなにが起きているのでしょう?
    ご覧のようにprocが何回も呼び出されていますね。
    このプログラムの動きを知るには、alertを使うと簡単です。

    以下のように書き換えて下さい

    function onLoad(){
    var proc = function(t){
    alert("t="+t);
    if(t<1) // tが1未満になったら再帰をやめる
    return;
    for(var i=0;i<360;i++){ //円を描く
    move(t);
    turn(1);
    }
    proc(t*0.8); //tに0.8を掛けて再び円を描く
    };
    penDown();
    proc(3);  //最初のtの値に3を代入する
    logo.penUp();
    }

    すると、procが呼び出される度にalertでtの値が表示されます。
    最初はtの値は3です。

    次は「t=2.4000000000000004」となりますが、ほぼ2.4、そして1.92、1.536、1.2288、0.98304となってtが1未満になったので再帰は終わります。

    また、右側の画像にも注目してください。
    再帰が繰り返されるほどより半径の小さい円が描かれていきます。

    このように、自分自身を呼び出しながらも、呼び出し回数にわざと制限を設けて呼び出すのが再帰です。

    使いこなすのが難しいと思いましたか?
    実際、再帰は慣れるまで非常に理解するのが大変な考え方のひとつです。
    逆に再帰を使いこなせるようになれば、プログラマとして一人前になった、と言えるかもしれません。

    最後に、再帰を使って美しい木のグラフィックを出す方法をご紹介して今回は終わりにしたいと思います。

    function onLoad(){
    a=20;
    b=0.8;
    var proc = function(t){
    if(t<10){ // tの値が10未満まで小さくなったら再帰をやめる
    move(t*b);  //進んで
    move(-t*b); //戻る
    return;
    }
    turn(-a*b);
    move(t*b);
    proc(t*b);      //ここで自分自身を呼び出す(再帰呼び出し)
    move(-t*b);
    turn(a*b);
    turn(a);
    move(t*b);
    proc(t*b);    //ここで自分自身を呼び出す(再帰呼び出し)
    move(-t*b);
    turn(-a);
    };
    penUp();
    turn(180);
    move(-100);
    penDown();
    proc(80);
    logo.penUp();
    }

    なにが起きているかわかりましたか?
    こういうプログラムを理解するコツは、適当に数字を変えてみたり、moveやturnの順番を変えてみたりすることです。

    なあに、よほどのことが起きなければ驚くほどのことはありません。
    ただし相手にしているのは再帰です。

    無限の再帰に気をつけて。
    ではまた次回お会いしましょう

    文・alan

  • コメントは受け付けていません。
  • Filed under: Tutorial
  • alanです。
    さて、前回は関数の作り方を勉強しました。

    これまで、この連載では変数、命令、そしてループについて学び、それから前回、関数を作ることで自分だけの命令を定義できることを学びました。

    さて、これでプログラムを作るための部品はけっこう揃って来たのですが、もうひとつ、大切なものがあります。
    それは条件判断です。

    ○○から起きたら、××する、というような命令の仕方です。
    あまりにもよく使う命令ですが、プログラミングの経験がないと、すぐには必要な場面が思いつかないかもしれません。

    たとえば、ゲームでキャラクターを動かしたりするときによく使います。

    「右キーが押されていた」ら、「キャラクターを右に動かす」というような感じです。

    「右キーが押されている」という条件を判断し、「キャラクターを右に動かす」という動作を行うわけです。

    つまりif文はいわばコンピュータの頭脳そのもの。
    プログラムのなかでif文をどう上手く使うかが、すなわちプログラミング能力そのものと言ってもいいかもしれません。

    (続きは以下のリンクから)

    前回の練習問題で円を描くプログラムの話をしました。
    どんな感じになるかというと

    function circle(){
    for(i=0;i<360;i++){
    move(1);
    turn(1);
    }
    }

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<4;j++){
    circle();
    turn(90);
    }
    penUp();
    }

    とこうなるはずです。

    この場合、円は90度ずつ回転しながら四つ描かれるのでこんな感じになるわけです。

    この図形をif文を使ってさらに変化させてみましょう。

    circle関数の中身を以下のように書き換えます。

    function circle(){
    for(i=0;i<360;i++){

    if( i<30 ){
    move(5);
    }
    move(1);
    turn(1);
    }
    }

    ifという文が真ん中に現れました。
    forループと似ていますね。

    ifの場合、ifに続く括弧の中身は「条件式」と呼ばれるものになります。
    この条件式が成立すると、括弧の中身が実行されるわけです。
    この場合だと、iが30未満の間は、move(5)が毎回実行されるわけです。

    これを実行してみましょう。

    とっても奇妙なカタチがあらわれました。
    これは4つつなげたものなので、ひとつだけ表示するようにプログラムを書き換えましょう。

    円の一部が間延びしたような、変なカタチになっていますね。
    これは、iが30未満の間だけ、moveが多く実行されている証拠です。

    さらに変えてみましょう。

    function circle(){
    for(i=0;i<360;i++){

    if( i == 180 ){
    turn(90);
    }else{
    move(1);
    turn(1);
    }
    }
    }

    [/pre]

    こんどはiが180のときだけ90度回転するという大胆なプログラムにしてみます。
    ifの{}の後ろにelseという見慣れない命令文も出て来ています。

    このelseはifとセットになっていて、if文で示された条件式が成立していない場合に実行される文です。

    この場合だと、iが180ピッタリのときは90度回転し、そうでないときは通常の円を描くのと同じように動くことになります。

    これ、どんな図形になるか想像できますか?

    以下のような感じです。

    ループで四つつづけて書くと、美しい花のような模様が現れました。

    このように、if文を使うといろいろな遊びが出来るようになります。

    さて、ここまでで一通りのプログラミングに必要な部品は揃いました。

    次回はいよいよ、いきなりゲームを作ってみたいと思います。
    ご期待ください。

  • コメントは受け付けていません。
  • Filed under: Tutorial
  • こんにちはalanです。

    Wise9編集部のみんなは、サンフランシスコで楽しくゲームを作ってるみたいだけど、僕はいま北海道に居ます。

    今回も面白いプログラミングの世界を学んでいきましょう!

    ところでみなさんは「函館(はこだて)」という場所を知っていますか?

    北海道の南に位置する、とても美しい街です。

    この函館、不思議な名前だと思いませんか?

    函館の由来には諸説あって、Wikipediaによるとこんな感じのようです。

    地名の由来 [編集]

    古来、この地はウスケシ宇須岸)と呼ばれていた。1454年享徳3年)、南部氏との戦いに破れた津軽の豪族・安東政季を擁し、武田信広らと共に蝦夷地に渡った河野政通が、函館山の麓(現在の弥生町付近)に築いた館(「宇須岸館」とも「河野館」とも呼ばれる)が箱に似ていたため箱館と呼ばれるようになり、明治時代になって函館と改められたとされるが、諸説ある。

    フリー百科事典 Wikipediaより引用 http://ja.wikipedia.org/wiki/函館市

    っまり「函館」の「函(はこ)」=「箱」ということですね。

    さてさて、今回のかんたんプログラミングでは、この「箱」というか「函」について学んでみましょう。

    みなさんは函数(かんすう)という言葉をしっていますか?

    「関数なら知ってるけど函数なんてへんてこな数、知らないよ」と思うかもしれません。

    確かに学校で習うのは「関数」です。

    実は関数というのは現代になって作られた当て字で、本当は函数と書いていたのです。

    「関数」と書かれると、「なにか関係する数」のように見えますが、「函数」と書かれると、「数に関係する函(はこ)」というイメージが湧いてきます。

    これ、けっこうイメージ違いますよね?

    関数というと、数に見えるのですが、函数というとどちらかというと函に見えるはずです。

    ひっくりかえして数函(かずばこ)にすると、数が飛び出してくる箱、というイメージになりません?

    そう。実は関数とは、ブラックボックス。つまりボタンを押すと数が飛び出してくる箱のことなのです。

    ちなみにさらに面白いことに、関数は英語でfunction(ファンクション)と書きます。

    そしてfunctionを英語の辞書でひくと、関数という意味以外にも意外な意味がでてきます。

    function

    音節func・tion 発音記号/fˈʌŋ(k)ʃən/音声を聞く音声を聞く

    【名詞】【可算名詞】

    1

    機能働き作用目的of〕.

    【数学】 関数.

    というような意味があります。

    日本語の漢字に複数の意味があるように、英語の単語にも複数の意味がある場合が多いのです。

    function=函数(関数)と翻訳したのはまだ数学の概念が発達していなかった頃の日本人です。

    だから安易に「関係する数」としても問題はなかったのでしょう。

    しかしいま、コンピュータプログラミングの世界では、関数とは必ずしも数を意味しません。

    コンピュータの関数が意味するのは「機能」や「働き」「作用」といったことです。

    さて、前回の最後の問題はうまくできたでしょうか?

    ループで渦巻き模様をつくるプログラムをさらにループさせる、というものでした。

    どんな図形になりましたか?

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<4;j++){
    for(i=0;i<360;i++){
    move(10);
    turn(i);
    }
    turn(90);
    }
    penUp();
    }

    shi3z編集チョが作ってくれたブラウザ上で実行するインタプリタ環境でも試すことができます。

    http://junk.wise9.jp/js/
    というか答えはもう出てますね。
    さて、ループを二重の入れ子構造にすると、プログラムが少し複雑になってきました。

    「渦巻きを描く」とか「円を描く」とかいう命令を出すときにいちいちループを書くのはちょっと面倒な気がしませんか?

    そういうときに関数を作るのです。
    関数を作る、というのはfunctionを作る。つまり機能を作る、ということで、このあたりが数学で用いられる関数とは根本的に違うところです。

    では、さっそく渦巻きを描く関数を作って、さっきのループをシンプルにしてみましょう。

    function uzumaki(){ //これが関数の定義
    for(i=0;i<360;i++){
    move(10);
    turn(i);
    }
    }

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<8;j++){
    uzumaki(); //←ここで関数を呼び出している
    turn(45);
    }
    penUp();
    }

    プログラムの世界で関数を作るのは難しいことではありません。

    関数とはプログラムそのものを別の枠組みでくくる、ということです。

    上のコードを実際に実行してみて下さい。

    前回とはちょっと違った図形になるはずです。

    上の「function」という定義部分で「uzumaki(うずまき)」という新しい関数を作っています。

    それをループの中で呼び出しています。

    関数の呼び出しには、関数の名前と、その後ろに括弧をつけることになっています。
    コードの下半分と上半分を見比べてみて下さい。

    これ、なにか気づきましたか?

    そう。実は今まで書いていたプログラムは、そもそも「onLoad」という関数をしていたのです。

    つまり関数を学ぶまでもなく既に書いていた、ということになります。

    実はこの連載ではもうお馴染みのturnやmoveといった関数もまた、関数として別のファイルで定義されているのです。つまり関数をつくるというのは、命令を作るということであり、プログラミングとは自分で作った命令を自分で呼び出す、ということの連続になるのです。これがプログラミングが最高に面白いポイントでもあります。

    いろんな関数を定義していくことで、自分だけの言葉、自分だけの命令によって世界を動かすことができます。プログラミングとは、自分だけの小宇宙をつくること、でもあるのです。

    関数の面白さがちょっと解りましたか?

    とはいえ、これだけではちょっとつまらないので、すこし関数を使っていたずらをしてみましょう。

    function uzumaki(){
    for(i=0;i<360;i++){
    move(Math.random()*10);
    turn(i);
    }
    }

    関数は最初から様々なものが用意されています。
    Math.randomという関数もそのひとつです。

    これはMath(数学)というジャンルのrandomという関数ですよ、という意味です。

    この連載であつかっているJavaScriptには無数の関数があり、総て覚えるのは大変ですし、実は私自身も覚えていません。

    ですから本当に必要な部分だけを少しずつ切り出して紹介しています。また、いまどきは全部の関数を覚える必要は全くありません。たぶん総て暗記している人はあまりいないんじゃないかな。必要になったときにネットで「JavaScript 関数」とでも検索すれば、いつでも情報が手に入るんですから、覚える必要なんてあまりないんです。

    さて、そのなかでもこのMath.randomは非常に面白い関数で、これは0から1までのランダムな小数(乱数といいます)を返す関数です。これに10を掛けると、ちょうど0から10までの好きな値になります。まるで酔っぱらいのようにふらふらとへんてこな線が出てきます。

    ちなみに乱数を使うと、プログラムの実行結果は毎回変わります。だから、上のような写真にならなくても間違いではありません。

    ゲームなどでときおり出てくる乱数の要素は、実はこのような関数を使って実現されているのですね。

    Math.randomは数学ジャンルの関数だけあって、非常に数学の「関数」っぽいのですが、数学の授業に出てくる関数って、だいたいどうでもいい感じのものばっかりでしょ? f(x) = ax+bとか。それがなんの役に立つの?というものばかりです。

    それに比べると、プログラムででてくる関数は最高にイカしてます。
    だって、それは実際に役に立つ(機能する)からです。まさにfunctionという感じでね。

    Math.randomを使ってuzumaki関数を書き直すと、関数というのがいかに便利で面白いものか、わかると思いますよ。ぜひ試してみて下さい。

    Math.randomは、「0から1までの値を返す」 関数と説明しましたが、自分でつくる関数でも値を返すことができます。

    また逆に数学の関数や、move、turnといった関数のようにパラメータを渡すこともできます。

    試しにプログラムを以下のように書き換えてみましょう。

    function random(x){
    return Math.random()*x;
    }

    function uzumaki(){
    for(i=0;i<360;i++){
    move(random(i));
    turn(i);
    }
    }

    function onLoad(){
    logo.init();
    penDown();
    for(j=0;j<8;j++){
    uzumaki();
    turn(45);
    }
    penUp();
    }

    Math.randomは便利な関数なのですが、いかんせん名前が長過ぎるのと、あとから10を掛けたりするのは面倒です。そこでオリジナルの乱数を返す関数random(x)をつくってみました。

    関数を定義するときに、パラメータ部分に変数を設定しておくと、それを関数のなかで使えるようになります。

    そして値を返したい場合は、returnという命令のあとに、返す値を渡します。

    この場合、Math.randomにxを掛けた値を返しているというわけですね。

    uzumaki関数でrandomを呼び出すときにもちょっと細工がしてあります。

    さきほどは「10」で固定だった部分をループ変数のiにしています。

    こうするとどうなるか。

    iは0から360まで増えていきますから、得られる乱数も0から360までの範囲で次第に増えていくことになります。つまり後半になればなるほど、大股で歩く酔っぱらい、のような動きになるのです。

    ぜひ試してみて下さい。

    また、以下のことも試してみることをお勧めします。

    練習問題

    1. moveにも乱数を渡してみよう
    2. 円や正方形を描く関数を自分で作ってみよう

  • コメントは受け付けていません。
  • Filed under: Tutorial
  • こんにちはalanです。

    前回の最後の図形、描けましたか?

    そう、以下のような画面になるはずです。

    これってどういうことなのかわかりますか?

    おさらいしてみましょう。

    100進んで90度曲がって、さらに100進んで90度曲がる、というのを四回繰り返した訳でした。

    前回のコード
    
    function onLoad() {
        logo.init();

        penDown();
        move(100);
        turn(90);
        move(100);
        turn(90);
        move(100);
        turn(90);
        move(100);
        penUp();
    }

    同じ処理を四回繰り返すのに、コピペを多用するのはややこしいですね。
    プログラムで繰り返しをしたいとき、一番簡単なのは、forという命令文を使うことです。
    では、正方形を描くプログラムをfor文で書き直してみましょう。

    function onLoad() {
    logo.init();
    penDown();
    for(i=0;i<4;i++){
    move(100);
    turn(90);
    }
    penUp();
    }

    このように書き換えてみても、前回と全く同じように正方形が描かれることが確認できると思います。

    for文は、上図のように、あとに続く「{」と「}」で囲まれた部分を指定した回数だけ繰り返せ、という命令です。
    この場合、「4」という数字が見えますね。それが繰り返しの回数になります。

    こういう命令の使い方をループ処理またはループと呼びます。
    しかしこれだけだと、コピーした方が早いと感じてしまうかもしれませんね。
    でも、例えば次のようにコードを書き換えてみて下さい

    function onLoad() {
    logo.init();
    penDown();
    for(i=0;i<360;i++){
    move(1);
    turn(1);
    }
    penUp();}

    4だった部分を360に、moveとturnをそれぞれ1ドット、1度ずつにしてみました。
    何が起きそうか、予感はしますか?

    そう。結果は下図のようになります。

    奇麗な円が書けました。

    さすがに1度ずつ360回コピーするよりは、for文を使った方が断然ラクですよね?

    さて、さっきは軽くスルーしましたが、このfor文にはiという記号が沢山でてきます。

    このiとはなにかというと、「変数」です。

    「変数」とは・・・要するに、変わる数ですね。

    中身がどんどん変わっていきます。

    for文をもう一度見てみましょう。

    for(i=0;i<360;i++){

    for文に続く()の中身を見てみると、なにやら複雑なことになっています。
    しかし前回、「;」は文末を意味すると説明しました。
    「;」はそのほかに、こうした場合に、「区切り」としても使われるのです。
    とすると、このfor文の()の中身は、「i=0」と「i<360」と「i++」に分けられるということが解ります。
    最初の「i=0」は、変数iに、0を代入しなさい、という命令です。だからこのときiは0になります。
    いちど、{}の中身、つまり moveとturnを実行したあと、今度はさらにループを続けるか、ということをfor文は判断します。
    そのときに、「i<360」という式を使います。
    これは文字通り「iが360より小さければ」またループを繰り返せ、ということになります。
    では最後のi++はなんでしょうか?
    これは、iの中身を1増やせ、という意味です。

    試しにiの中身を2ずつ増やしてみましょう。「i++」の部分を「i+=2」に変えてセーブしてからリロードしてみてください。

    どうなりましたか?

    なんと円が半分だけになってしまいました。

    これは、本来1ずつ足していれば360度全部描けたのに、2ずつ足したことによって、ループ回数が半分の180回しかなかったため、正しい円ではなく半円になってしまった、ということなのです。

    これを利用すると面白いことができます。

    たとえば、以下のようにすると八角形を描くことができます。

    penDown();
    for(i=0;i<360;i+=360/8){
    move(360/8);
    turn(360/8);
    }
    penUp();

    360を8で割って、そのぶんだけ回転しながら描画しているわけです。

    ちょうど8回で終わるように割り算しているので、ちょうど8角形が描けるわけです。

    これ、もちろん三角形でも六角形でも20角形でも好きなカタチを描画することができるんですね。

    でも、実はみんな意外と知らないのが、7角形のカタチなんです。

    360を7で割ると、割り切れないんですね。

    7角形は分度器では描くのは非常に難しいので、コンピュータに描かせるのが一番もっともらしいものになります。

    実際に描かせるとこんな感じになります。

    実に不思議なカタチをしていますね。

    余談ですけど、小学校などで五角形とか八角形の描き方を習った頃に、僕はプログラムを書けば七角形が描けるよ、と言ったらひどくモテたことを思い出しました。プログラミングも意外なところで役に立つものです。

    さて、ところでここで使われているiですけど、ループに使う変数を特別にループ変数とかイテレータとか呼んだりすることもあります。

    ループの面白さが解っていただけたでしょうか?

    さらにもうひとつ、変わったことをしてみましょう。

    このループ変数i、実はループの中でも使うことができるんです。

    試しにこんなことをやってみましょう。

    for(i=0;i<360;i++){
    move(10);
    turn(i);
    }

    これ、どうなるかすぐにわかりますか?

    10進んで、i度だけ曲がるわけです。でもiは1度から360度までどんどん上がっていくから、どんどん曲がり方が急になっていくわけですね。

    何だコリャ!!

    こんなゼンマイというか渦巻きというか、そんな図形もループを使うと簡単に描けてしまうのですね。
    ちなみにですよ。

    ループをさらにループさせるということもできるんです。

    for(j=0;j<4;j++){
    for(i=0;i<360;i++){
    move(10);
    turn(i);
    }
    turn(90);
    }

    iのループの外側に、jという別のループ変数を使ったループを作ってみました。
    さっきの渦巻きループを4回繰り返していますよ。
    さあ、どうなるか、想像できますか?

    結果は、ぜひ試してみて下さい。
    ではまた次回!

    文・alan

  • コメントは受け付けていません。
  • Filed under: Tutorial
  • こんにちは。alanです。

    最近、プログラムを始めたいんだけど、どこから手を付けていいのか解らない!という声を聞くので、いっちょ僕も初心に帰って、プログラミングの初歩の初歩を解説したいと思います。

    プログラミング言語にはいろいろありますが、今回はお金がかからなくてしかも最近は主流となりつつある、JavaScript(ジャバスクリプト)という言語を題材として、プログラミングの面白さを手軽に理解できるように心がけたいと思います。

    用意するもの

    ・Webブラウザ(InternetExplorerではなく、ChromeやSafariが望ましい)

    今回はお金の掛からないプログラミング入門ということで、最新のWebブラウザを用意しましょう。無料です。AppleのSafari(サファリ)はWindowsからでもダウンロードすることができます。GoogleのChrome(クローム)でもかまぃません。総て無料でダウンロードできます。

    Windowsに標準でついてくるInternetExplorer(インターネットエクスプローラ)は動作が特殊なため、今回は対応しないことにします。

    ・テキストエディタ
    使い慣れたエディタがあればなんでも構いません。ただし、Microsoft Word(マイクロソフト ワード)やWindowsに標準でついてくる「メモ帳」や「ワードパッド」はダメです。WindowsならApsaly(http://www.vector.co.jp/soft/win95/writing/se423509.html)というブラウザが無料で使えるようです。
    Macの場合、mi(http://www.mimikaki.net/)というテキストエディタが無料だし使いやすいと思います。

    用意するものは以上ふたつだけです。

    プログラミングを入門するにはいくつかの方法がありますが、今回は最も伝統的なやり方でやりましょう。

    手順はこうです。

    1. お手本となるプログラムを入力する
    2. お手本を実行する
    3. お手本を改造する
    4. 改造したプログラムを実行して動作を確かめる
    5. さらに難しい課題に挑戦する

    お手本を改造しながら学ぶことで、理解が早まります。

    これがコンピュータ言語学習の王道です。他のどんな言語にも応用できます。
    しかし、今回、お手本としてどんなプログラムを示すか、けっこう迷いました。

    ありきたりのものでは面白くないし、かといって、あまりに突飛なものでもみんな腰が引けてしまいそうです。
    プログラミングに入門しようとなんども挑戦した人は沢山いると思いますが、その都度、味気ない数字の羅列を見て、挫折してしまったりしたのではないでしょうか。
    足し算とかかけ算の結果とか、どうでもいいじゃないですか。

    そういうわけで、僕は今回、入門の段階からいきなりコンピュータグラフィックを描いてみようと思います。
    プログラミングを始めるとき、まず覚えなければならないのは、ソースコードという言葉です。

    ソースコードは、略してコードとも呼ばれます(ただしコードは別の意味も持っているので注意)。
    プログラミング言語で書かれたプログラムのことを言います。

    プログラミング言語とは、コンピュータに命令するための特別な言葉です。独自の命令と独自の文法を持っています。
    しかし、人間が作った言葉なので、英語や中国語を覚えるよりは単語の数も少なく、ずっと簡単です。

    それでは、さっそくあなたのプログラミングを始めましょう。
    まずは以下のコードをテキストエディタに順番にコピペし、それぞれ正しいファイル名でセーブしてください。

    ファイル名:start.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="wiselogo.js"></script>
    <script type="text/javascript" src="main.js"></script>
    </head>
    <body onload="onLoad()">
    <canvas id="canvas0" width="500" height="500"
    style="border:1px black solid">
    </canvas>
    </body>
    </html>

    ファイル名:wiselogo.js

    var Vector = function(x,y){
    this.x = x;
    this.y =y;
    this.plus = function(v){
    this.x += v.x;
    this.y += v.y;
    },
    this.times = function(t){
    return new Vector(this.x*t,this.y*t);
    }
    };

    var logo = {
    canvas:null,
    context:null,
    cursor:new Vector(250,250),
    direction:new Vector(0,1),
    rotate :0,
    pen : false,
    penDown:function(){this.pen = true;},
    penUp:function(){this.pen = false;},
    init:function(){
    this.canvas =document.getElementById("canvas0");
    this.context=this.canvas.getContext("2d");
    },
    turn:function(r){
    this.rotate += r;
    this.direction.x = Math.sin(this.rotate*3.14159/180);
    this.direction.y = Math.cos(this.rotate*3.14159/180);
    },
    move :function(t){
    if(this.pen){
    this.context.beginPath();
    this.context.moveTo(this.cursor.x,this.cursor.y);
    }
    this.cursor.plus(this.direction.times(t));
    if(this.pen){
    this.context.lineTo(this.cursor.x,this.cursor.y);
    this.context.stroke();
    }
    },
    printpos :function(){
    alert('hoge: '+this.cursor.x+","+this.cursor.y);
    }
    };

    var move = function(t){logo.move(t)};
    var turn= function(r){logo.turn(r)};
    var penDown= function(){logo.penDown()};
    var penUp = function(){logo.penUp()};

    ファイル名:main.js

    function onLoad() { //このあたりはあとで説明します
    logo.init(); //ここもあとで

    penDown(); //ペンを下ろす
    move(50); //50進む
    penUp(); //ペンをあげる

    }

    上記のソースコードをすべて正しいファイル名でセーブしたら、start.htmlをSafariかChromeで開いてみましょう。

    Macの方はstart.htmlをダブルクリックすれば起動しますが、WindowsでChromeが標準ブラウザに設定されていない場合、Chromeのウィンドウを開いてstart.htmlをドラッグ&ドロップすれば大丈夫です。

    上手く開けましたか?

    こんな画面が表示されたら成功です。

    もしうまくいかなかったら、以下のことを調べてみましょう。

    • start.html、wiselogo.js、main.jsの総てが同じフォルダ内にあるか
    • ChromeまたはSafariで開いているか?(InternetExplorerでは動作しません)

    さて、この最初のプログラムはなにをしているのでしょうか?
    たいていのプログラムには必ずメインとなる部分があります。このお手本プログラムの場合、それはもちろんmain.jsです。

    このmain.jsではなにをしているのでしょうか?
    functionとかinitとかいうあたりは読み飛ばしていただいて(あとで説明します)、注目してほしいのはpenDown()のあたりです。

    実は、これは絵を描くプログラムになっています。
    絵を描くときにはペンを使いますよね?

    ここでは画面を紙として描く、仮想のペンを想像してください。そのペンを紙に下ろす。これがpenDown()という命令がやっていることです。

    次にmove(50)は、50進むこと。ペンを下ろしたまま50ドット進みます。

    最後にpenUp()で下ろしたペンを上げます。

    それで画面の真ん中に、短い直線が表示されているというわけです。
    この短いプログラムの中にも、いくつか法則というか、プログラミング言語の決まり事が見て取れます。

    詳しく説明しましょう。

    JavaScriptでは、//(スラッシュが二回)の後ろはコメントという扱いになって、ここには好きなことを書くことができます。たいていの場合は、プログラムが解りやすくなるようにメモなどを書くのが普通です。

    さらに、青で示したのは命令です。ただし、命令のことをJavaScriptでは関数とも呼びます(厳密には異なりますがここはこういうものだと思って下さい)。

    penDownは、ペンを下げろ、という命令なわけですね。

    命令のうしろに続くふたつの括弧は、この命令に渡すパラメータを指定するための場所です。penDownにはパラメータがありませんが、moveには50というパラメータが渡されていますね。

    最後の「;」はセミコロンと言って、文の終わりであることを示す記号です。日本語で言えば「。」にあたります。

    コンピュータはセミコロンがないと文がどこで終わったのかわからなくて混乱してしまいます。
    ですから、セミコロンは忘れずにつけるようにしましょう。

    さて、これだけでは全く面白くありません。

    このmain.jsを改造して、プログラムを覚えてみましょう。

    テキストエディタを使って、main.jsを以下のように変えてみて下さい。

    function onLoad() { //このあたりはあとで説明します
    logo.init(); //ここもあとで

    penDown(); //ペンを下ろす
    move(50); //50進む
    penUp(); //ペンをあげる
    move(50);
    penDown();
    move(50);
    penUp();

    }

    どうなりましたか?
    以下のような画面になったでしょうか?

    このプログラムがどういうふうに動作しているか、なんとなくわかりましたか?

    一度ペンを下げて、50移動して、ペンを上げて、さらに50移動して、またペンを下げて、50移動して、最後にまたペンを上げました。

    それで、点線のような模様が画面に描かれたわけです。

    penDown、move、penUpの三つの命令だけだと、直線しか描けないので、ここで新しい命令、turnを登場させることにしましょう。

    turnはその名の通り、方向を変えます。

    再びmain.jsを以下のように改造してみて下さい。

    function onLoad() { //このあたりはあとで説明します
    logo.init(); //ここもあとで

    penDown();
    move(100);
    turn(90);
    move(100);
    turn(90);
    move(100);
    turn(90);
    move(100);
    penUp();
    }

    turnは、moveと同じく、パラメータをとります。

    moveのパラメータは移動距離でした。
    turnのパラメータは角度になります。
    100進んで、90度ターンして、100進んで、90度ターンして、と四回繰り返す訳です。

    すると・・・結果はぜひ試してみて下さい。

    次回はもっと複雑な図形に挑戦しますよ!

  • 6 Comments
  • Filed under: Tutorial
  • about “enchant.js”

    enchant.js is an HTML5 + JavaScript based game engine. It is a standalone library that enables cross-platform application development for PC, Mac, iPhone, iPad, and Android from just 30 KB of source code.

    enchant.js was developed at Ubiquitous Entertainment Inc.'s Akihabara Research Center, and released April of 2011. Nearly 200 games have been created in its first two months of release, making it the world's most-used HTML5 game engine.

    enchant.js Official Website

    facebook Like