# チュートリアル[ゲーム作りの基礎をやってみよう] ### 目次 > #### Step0 まずは準備 > #### Step1 ゲームの基本を作ろう > #### Step2 ゲームのキャラに動きを付けよう > #### Step3 ゲームの部品を追加しよう > #### Step4 ゲームの部品を追加しよう(発展) > #### Step5 クラスを活用しよう(その1) > #### Step6 クラスを活用しよう(その2) > #### Step7 キャラに動作を付けよう > #### Step8 当たり判定を設定しよう > #### Step9 ゲームを完成させよう > #### Step10 画面にスコアを表示させよう > #### Step11 画面にタイマーを表示させよう > #### Step12 フルーツを作るクラスを複数作ろう > #### Step13 画面外から出てくる爆弾を作ろう > #### Step14 爆弾が画面端四方向から出てくるようにしよう ### Step0 まずは準備 ## 実際に使ってみよう 第2回では、コーディングを行いゲームを開発します。コーディングとは、実際にタイピングでコードを記述することです。今回はこちら用意した学習支援システムで学習を行います。 以下の部分をクリックしてみてください。 [学習システム](http://150.19.10.187/summer2019_enchant/login.php) するとログイン画面が出ます。 ![](https://i.imgur.com/uQ9xF8k.png) 皆さんの机の上にあるメモを見てユーザIDとパスワードを入力してください。 下のような画面に行ったら成功です。 ![](https://i.imgur.com/TkWbl3W.png) 第2回では、昨日作成したクマさんのフルーツ狩りをより進歩させたゲームを作成します。 本日作るゲームは以下のようになっています。 ![](https://i.imgur.com/ocis2PL.gif) 最初に、復習もかねて、前回作成したゲームをコーディングで作成してみます。Step1から作っていきます。 ### Step1 クマを表示させてみよう!(復習) まずは、[クマさんのフルーツ狩り]STEP1を開始します。開始ボタンを押してください。 ここでは、クマを表示させるプログラムを作ることを目標に、コードを書いていきます。 完成図はANSWERの部分を確認してください。 </br> まずは、下のサンプルコードをタイピングで丸写ししてみましょう。 <details><summary>サンプルコードを表示するときはここをクリック</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif'); var bear; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 0; game.rootScene.addChild(bear); }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> 写し終わったらRUNボタンを押してみてください。ANSWERと同様の画面が出てきていれば成功です。<font color="red">何も表示されなかったり、別の画面が表示されたときは、サンプルコードが正しく写せていないので、もう一度見比べてみてください。</font> ではサンプルコードの説明をします。 #### 1行目 初めにコードの頭(1行目)に ``` enchant(); ``` という記述があります。これは「enchant.js」使うためのおまじないのようなものです。 enchant.jsで、ゲームを作るときは、必ず先頭にこの一行を書きます。 <!-- さらにその下にこのコードが書いてあります。 ``` window.onload = function() { game = new Game(320, 320); game.onload = function() { }; game.debug(); }; ``` enchant.jsでは、上のコードの1行目に書いてある ``` window.onload = function() { ``` と、6行目に書いてある ``` }; ``` の間に、ブラウザを読み込んだ時に起こるプログラム処理を書きます。ブラウザとはウェブページのことです。今使っている学習教材、「テキスト型学習支援システム」では、RUNボタンを押した瞬間に行う命令をこの1行目と6行目の間にかきます。つまり、今回のサンプルコードではRUNボタンを押した瞬間に、 --> #### 3行目,22行目 次は3行目と22行目を見てください。 3行目には、 ``` window.onload = function() { ``` 22行目には、 ``` }; ``` と書かれています。enchant.jsでは、 ``` window.onload = function() { ・ ・ ・ }; ``` という記述をし、「・・・」の部分にブラウザを読み込んだ時に起こるプログラム処理(命令の集まり)を書きます。ブラウザを読み込むとはウェブページ(google chromeやedge、firefoxなどで開いたページ)を開いたタイミングのことです。今使っている学習教材、「テキスト型学習支援システム」では、RUNボタンを押した瞬間に行う命令を「・・・」の部分にかきます。つまり、<font color="red">今回のサンプルコードではRUNボタンを押した瞬間に、5行目から22行目までの命令を行っている</font>ということになります。 <details><summary> function()やwindow.onloadなどに関してさらに詳しく知りたい方は、ここをクリックしてください。 </summary> </br> "function"とは関数のことで、関数とは何かのプログラム動作をまとめたものです。また、window.onloadはすでに用意されている関数で、ブラウザを読み込んだ時に起こるプログラム処理を{}の中に書くことで書くことで実行することができます。fuctionは自分で自由に作ることもできます。半角英数字のみ、頭文字に数字を使えないといった制約はありますが、3日目の講義で作ってみましょう。 </details> </br> 次は5行目から22行目、つまりRUNボタンを押した瞬間に行う命令について詳しく見ていきます。 #### 5行目 5行目の ``` new Game(320,320); ``` ですが、これはゲーム画面を作成する命令です。(320,320)は画面のサイズを決めるためのもので、(横幅、縦幅)を決めています。今回は<font color="red">「横320px,縦320pxのゲーム画面でゲームを作成してください」</font>という命令を書いたことになります。 <details><summary> new Game()について詳しく知りたい人はここをクリック </summary> </br> new Game(320,320)のようにnew 名前(値)はenchant.jsのゲームを作る素を新しく呼ぶ命令です。この命令を好きな名前の変数というもの(今回の場合はgame)に入れることでGameに用意されている命令を簡単に使うことができます。入れるときの命令は以下のようになります。 ``` 好きな変数名 = new 名前(必要な値); ``` 値は一つの時や複数の時があります。Gameの場合は2つになります。 </details> #### 6行目 次の6行目の ``` game.preload('images/chara1.gif'); ``` ですが、 ``` game.preload('使いたい画像'); ``` とすることで画像の情報を取得してゲーム内で利用できるようになります。 'images/chara1.gif'は画像ファイルで、画像の内容は以下のようになっています。 ![](https://i.imgur.com/vqY9pYT.gif) 今回の場合はくまを使いたいので、下の画像'images/chara1.gif'を'自分の使いたい画像'の部分に入力します。 まとめると6行目では、<font color="red">「'images/chara1.gif'の画像をゲーム内で使えるようにしてください」</font>と命令していることになります。 #### 8行目 8行目の ``` var bear; ``` はbearという変数を作成する命令になります。 変数とは値などを保存するためのものです。箱のようなものだと考えてください。 変数を使うには先に変数を宣言しなければなりません。「これからこのゲームではこの名前の変数を使いますよ」と宣言しなければならないわけです。enchant.jsでは変数を宣言する際に頭にvarを付けます。つまり、 ``` var "変数名"; ``` とすることで、「"変数名"という名前の変数をこれから使えるように作ってください」と宣言することになります。まとめると、8行目では、<font color="red">「bearという名前の変数をこれから使えるように作ってください」</font>と命令していることになります。 #### 10行目,16行目 10行目、16行目では3行目と22行目ににた構文が書かれています。 10行目には、 ``` game.onload = function() { ``` 16行目には、 ``` }; ``` と書かれています。enchant.jsでは、 ``` game.onload = function() { ・ ・ ・ }; ``` という記述をし、「・・・」の部分にゲームを読み込んだ時、つまりゲームを開始した時に行うプログラム処理(命令の集まり)を書きます。ゲームを始めるとはSTARTボタンをおしたタイミングのことです。つまり、<font color="red">今回のサンプルコードでは、ゲームを開始した瞬間に、11行目から15行目までの命令を行っている</font>ということになります。 #### 11行目 11行目はコメントアウトという機能をもちいてコードにコメントを記述しています。コメントアウトについて詳しく知りたい方は以下を参照ください。 <details><summary> コメントアウトについて詳しく知りたい人はここをクリック </summary> </br> </details> #### 12行目 12行目は ``` bear = new Sprite(32, 32); ``` です。左辺に注目してください。左辺のbearは8行目で宣言した変数でしたね。 ``` "変数" = new Sprite(a, b); ``` と書くことで、"変数"という名前の変数をスプライト変数とし、横aピクセル、縦bピクセルとする。という意味になります。難しいですが、簡単に言うと、ゲームの中に登場するキャラクターを"変数"という名前で作成し、横aピクセル、縦bピクセルで作成する。という意味になります。つまり、<font color="red">今後スプライト変数という言葉が出てきたら、「このゲームに存在するキャラクターにつけられた名前」と理解してください</font>。(正確には違いますが今回はこの程度で大丈夫です。)スプライト変数は、様々な固有の変数を持っており、また追加で持たせることも可能です。これに関しては、13、14行目で説明します。 まとめると、12行目では、<font color="red">「bearという名前のキャラクターを横32ピクセル、縦32ピクセルで作成してください」</font>ということになります。 #### 13,14行目 ``` bear.image = game.assets['images/chara1.gif']; bear.frame = 0; ``` スプライト変数は、作成した瞬間それぞれ固有の変数を所持します。固有の変数は、 ``` "スプライト変数名"."固有な変数の変数名" ``` と記述します。今回はbear.image、bear,frameとなっているため、bearというスプライト変数が所持するimageという変数、frameという変数について命令を行っていることになります。それでは命令の内容について詳しく見ます。 ``` bear.image = game.assets['images/chara1.gif']; ``` ですが、 ``` スプライト変数.image = game.assets[ゲーム内に登録してある画像データ名]; ``` とすることで、画像データをスプライト変数に設定することができます。ここで設定できる画像データは、game.preload()という命令で登録した画像データのみ使用することができます。(サンプルコードでは6行目で設定しています。)また、この時画像データはスプライト変数を作成した時の画像サイズで分割します。この分割に関しての詳細は、Step2で説明します。以上をまとめ簡単に言うと、「 スプライト変数 というキャラクターの画像を画像データに設定してください」と命令しています。つまり、13行目では、<font color="red">「bearという名前のキャラクターの画像データに、クマの画像を設定してください」</font>と命令していることになります。 また、 ``` bear.frame = 0; ``` ですが、これに関しては、Step2で説明します。 #### 15行目 ``` game.rootScene.addChild(bear); ``` この命令を記述することで、作成したスプライト変数で制御されたキャラクターを、ゲーム上に表示させることができるようになります。スプライト変数は、作成しただけではゲーム上に登場することはありません。 ``` game.rootScene.addChild("スプライト変数名"); ``` とすることで、()内の変数の情報を画面に表示させます。 まとめると、15行目では<font color="red">「bearというキャラクターをゲーム上に表示してください」</font>と命令していることになります。 <!-- "new Game(320,320);"はゲーム画面を作成するコードです。(320,320)は画面のサイズを決めるためのもので、(横幅、縦幅)を決めています。今回は横320,縦320になります。横と縦の幅でここでゲーム画面のサイズを決めていきます。 game.onloadはゲーム開始時に行われる設定を書く場所で、window.onloadの中に入っているのでブラウザが開かれると同時にゲーム開始時のプログラムが読み込まれます。 そして最後に"game.debug();"でゲームがデバッグモードで起動されます。 大変長くなりましたが、これでゲーム作成のための準備は完成です。 この状態で実行すると画面は下のようになります。 ![](https://i.imgur.com/1qZQ6e1.png) それではゲームの主人公となるくまを画面に表示させましょう。 enchant.jsで画像を表示させるためには以下のように"game.onload"の前の"window.onload"の中で書く必要があります。 ``` game.preload('自分の使いたい画像'); ``` これを行うことで画像の情報を取得してゲーム内で利用できるようになります。 今回の場合はくまを使いたいので、下の画像'images/chara1.gif'を'自分の使いたい画像'の部分に入力します。 ![](https://i.imgur.com/vqY9pYT.gif) くまの情報を保存する場所として変数を使用します。 変数とは値等を保存するためのものです、箱のようなものだと考えてください。 変数を使うには先に変数に名前を付けておく必要があります。 enchant.jsでは変数を宣言する際に頭にvarを付けます。 ``` var bear; ``` これで変数bearを定義することができました。 くまを表示させるコードは"game.onload"の中に書きます。 まず変数bearに画像表示機能を持たせるためにSpriteを使用します。 ``` bear = new Sprite(32,32); ``` ()内の数値は画像の幅と高さを意味しています。次に先ほどpreloadした画像を熊に設定しましょう。 ``` bear.image = game.assets['images/chara1.gif']; ``` 最後にくまを画面表示させますaddChildを使用して()内の変数の情報を 画面に表示させます。 ```  game.rootScene.addChild(bear); ``` ではコードを実行してみましょう、画面にくまが表れるはずです。 ![](https://i.imgur.com/oCYLiIW.png) デバッグで起動するとスプライトは赤枠で表示され分かりやすくなります。もし通常起動したければgame.debug();を下のように変えてください。 ```  game.start(); ``` <details><summary>コードは以下のようになります。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif'); var bear; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 0; game.rootScene.addChild(bear); }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> --> ### Step2 ゲームのキャラに動きを付けよう(復習) Step2では、ゲームのキャラクターを変更すること、ゲームのキャラクターを動かすことを目標にゲームを作成します。 完成図はANSWERの部分を確認してください。ゲームをスタートした後、画面上の任意の点をクリックしてみてください。クマがクリックした点に動きます。 それではまずは、クマの画像を変更することを目的にプログラムを変更してみます。11行目から15行目までをこのように書き換えてみてください。 ``` /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); ``` <details><summary>ここまでのサンプルコードを知りたい方はここをクリック。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif'); var bear; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> 14行目を確認してください。0が10に書き換わっていると思います。 「chara1.gif」の画像ファイルのサイズは160 x 96 pxとなっており、Sprite(32, 32)は、32 x 32 pxのサイズで画像を用意するという意味でちょうど、画像ファイルの一キャラクターのサイズとなっています。 ![](https://i.imgur.com/3U7Uleg.png) そのため画像を次に移動させることでくまを別のくまに変えることができます。それを変更する方法がStep1で説明を省略したframe変数です。frame変数は、 ``` スプライト変数.frame = 数値; ``` という形で命令を記述します。frame変数は画像の左上を起点に0から始まり、右に向かう度、順番に番号が1ずつ増加します。また、最も右に到達したら次の行の左から順番に、というように設定されます。そのためにくまを女の子にしたい場合は下のようになります。 つまり上の画像を参考にすると、女の子とのくまを表示するためには、bear.frame = 10にすればよいことがわかります。逆に言うと、今まではbear.frame = 0であったため、0番目の画像、つまり男の子のクマが表示されていたというわけですね。 これで番号10にある女の子のくまが表示されます。 つまり、今回の14行目の変更により、<font color="red">「bearの画像に使用する画像を10番目の画像、つまり女の子のくまにしてください」</font>と命令することになります。それでは実行してみましょう。以下のプレイ画面になったら成功です。 ![](https://i.imgur.com/deqCwyt.png) それでは次はクマを動かすことを目標にしてみましょう。マウスクリックでくまを動かしてみましょう。 まずは以下のコードを現在のサンプルコードの16行目の下に追加します。 ``` game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; } ``` <details><summary>ここまでのサンプルコードを知りたい方はここをクリック。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif'); var bear; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> マウスクリックを活用する際にenchant.jsではontouchendを使用します。 使用方法としては、 ``` game."シーン名".ontouchend = function(event) { ・ ・ ・ }; ``` と記述し、「・・・」の部分にシーン上でクリックした時に行うプログラム処理(命令の集まり)を書きます。シーンについては、Step9で説明します。また、eventはイベント変数であり、固有の変数を所持しています。今回は、マウスがクリックされたというイベントに対する変数になります。 それでは20行目、22行目を見てみましょう。 20行目 ``` bear.x = event.x; ``` 22行目 ``` bear.y = event.y; ``` スプライト変数.xおよびスプライト変数.yは、スプライト変数が所持する固有な変数の1つで、そのスプライト変数の位置座標を司ります。また、event.xおよびevent.yはイベント変数が所持する固有な変数の1つで、そのイベントが発生した際に取得される位置座標を司ります。enchant.jsでは、ゲーム画面の位置を座標系で制御します。座標系は、一般の数学と違い、左上が(0,0)になり、x座標は右に正をとり、y座標は下に正をとります。詳しくは下の画像を参考にしてください。 ![](https://i.imgur.com/4ILFyyV.png) つまり、bear.x、bear.yはくまのx座標、y座標に対応しています。また、今回のイベント変数は、マウスがクリックされたというイベントに対するイベント変数です。よって、event.x、event.yはマウスがクリックされたときのx座標、y座標が対応しています。 つまり、20行目は、<font color="red">「くまのx座標をクリックしたときのx座標にしてください」</font>という命令で、22行目は、<font color="red">「くまのy座標をクリックしたときのy座標にしてください」</font>という命令となります。 <!-- このプログラムは下の場所に書いてください。 ![](https://i.imgur.com/lPOQEIk.png) --> これでくまはクリックした場所に移動するようになりました。 ### Step3 ゲームの部品を追加しよう Step3では、くまの他にフルーツを画面のランダムな位置に表示させることを目標にプログラムを作っていきます。 ![](https://i.imgur.com/f9Nx7yJ.png) それにあたり、まずはフルーツをゲームに登場させましょう。フルーツは、クマを登場させた方法と同様の方法で登場させることができます。以下のプログラムは、フルーツをゲームに登場させるためのプログラムです。映しながら、何を行っているかを考えてみてください。 <details><summary>サンプルコードはここをクリックします</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif')//ここに注目 var bear; var fruits; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); fruits = new Sprite(16,16); fruits.image = game.assets['images/icon0.gif']; fruits.frame = 15; game.rootScene.addChild(fruits); }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> 追加や変更を行った行数は、6行目、9行目、18行目から21行目です。 <!-- <details><summary>コードは以下のようになります。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif')//ここに注目 var bear; var fruits; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); fruits = new Sprite(16,16); fruits.image = game.assets['images/icon0.gif']; fruits.frame = 15; /* 0から320未満の任意の整数を設定 */ fruits.x = Math.floor(Math.random() * 320); //ここに注目 /* 0から320未満の任意の整数を設定 */ fruits.y = Math.floor(Math.random() * 320);//ここに注目 game.rootScene.addChild(fruits); }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> まずはクマの時と同じように変数fruitsの定義を行いましょう。 ``` var fruits; ``` フルーツもくまと同じやり方で表示できます。ただし画像のサイズがくまと違うのでSpriteのサイズも(16,16)に変更します。 ```javascript= fruits = new Sprite(16,16); fruits.image = game.assets['images/icon0.gif']; fruits.frame = 15; game.rootScene.addChild(fruits); ``` game.preloadも忘れないようにしましょう ```javascript= game.preload('images/chara1.gif', 'images/icon0.gif'); ``` --> フルーツが表示されるようになりました ![](https://i.imgur.com/sQ7HZy0.png) それではフルーツがランダムな位置で始まることを目標にプログラムを作成します。 ランダムな整数を取るためにMath.floor(Math.random())を使います。 Math.random()では0以上1未満の数値が取れるのでこれに好きな数値をかけることで0以上好きな数字未満の数値を取ることができます。 今回の場合ゲームの画面は 320 x 320 なのでフルーツの座標を以下のように設定します。これをfruits.frame = 15の下に、つまりfruitsの設定部分に記入して見てください。 ``` /* 0から320未満の任意の整数を設定 */ fruits.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits.y = Math.floor(Math.random() * 320); ``` <details><summary>ここまでのサンプルコードを知りたい方はここをクリック。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif')//ここに注目 var bear; var fruits; game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); fruits = new Sprite(16,16); fruits.image = game.assets['images/icon0.gif']; fruits.frame = 15; /* 0から320未満の任意の整数を設定 */ fruits.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits.y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits); }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> これでフルーツはランダム位置に表示されるようになりました。 ### Step4 ゲームの部品を追加しよう(復習) フルーツがひとつではつまらないのでたくさん表示させましょう。 ただ一つ一つ上の処理を何度も書いていくのは大変です。こういったときのために、for文と配列を使って繰り返し処理を行います。 ![](https://i.imgur.com/KA5qY1y.png) 下のコードを見て、フルーツの作り方を変えてみましょう。 <details><summary>サンプルコードはここをクリック。</summary> ```javascript= enchant(); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif'); var bear; var fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Sprite(32, 32); bear.image = game.assets['images/chara1.gif']; bear.frame = 10; game.rootScene.addChild(bear); //fruitsを10個作成 var i = 0; for (i = 0; i < 10; i++) { fruits[i] = new Sprite(16,16); fruits[i].image = game.assets['images/icon0.gif']; fruits[i].frame = 15;//ここに注目 /* 0から320未満の任意の整数を設定 */ fruits[i].x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits[i].y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits[i]); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> 変更点や追加点は9行目、19行目から30行目です。 変更点を見比べてみましょう。まず9行目ですが、 変更前 ``` var fruits; ``` 変更後 ``` var fruits = Array(); ``` となっています。このArray()を配列と言います。つまり、変更前は「fruitsという変数を作ってください」という命令であったものが、変更後は「fruitsという配列の変数を作ってください」という命令に変わったということです。配列とは簡単に言うと、同様の名前の変数に番号を振ることによって複数の変数を作ったことと同様にするという仕組みの機能です。例えばfruitsという変数を作った場合、fruitsは一つなので当然変数は一つです。しかしfruitsという配列の変数を作ると、fruits[0]、fruits[1]、・・・fruits[n]といった形で同様の名前で番号付けがされた独立した変数が複数作られると考えてください。こうすることにより、1行で複数の変数を作ることができる仕組みだと考えてくれればよいです。 次に、20行目から30行目です。 変更前 ``` fruits = new Sprite(16,16); fruits.image = game.assets['images/icon0.gif']; fruits.frame = 15; fruits.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits.y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits); ``` 変更後 ``` var i = 0; for (i = 0; i < 10; i++) { fruits[i] = new Sprite(16,16); fruits[i].image = game.assets['images/icon0.gif']; fruits[i].frame = 15;//ここに注目 /* 0から320未満の任意の整数を設定 */ fruits[i].x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits[i].y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits[i]); } ``` 先頭に変数iが0で定義されたことと、 ``` for(i = 0; i < 10; i++) { } ``` が追加されたこと、またすべてのfruitsがfruits[i]になったことが変更点です。 これは、for文と配列を利用し、同様の動作を行う独立した変数を複数操作しています。詳細は両略しますが、気になる方は下のこちらをクリックしてくださいという部分をクリックしてみてください。ちなみに、5個作りたい場合は、 ``` for(i = 0; i < 10; i++) { } ``` を ``` for(i = 0; i < 5; i++) { } ``` に書き換えてください。 まとめると、<font color="red">同様の動作を行う独立した変数xをn個操作したい場合は、 ①変数xの定義を ``` var x = Array(); ``` とする。 ②操作する部分で ``` var 変数名(x以外の変数、ここでは仮にiとする); for(i = 0; i < n; i++) { ここでそうさする際のxをx[i] に置き換える } ``` </font> となります。 <details><summary>for文と配列の詳細な説明は時間がかかるため、本日は省略します。気になる方はこちらをクリックしてください。</summary> for文は同じ処理を何度も繰り返すときに使うための処理です。3つの要素の設定をしてあげることで使うことができます。 for文は以下のように書くことができます。 ``` for(最初の変数の決定; ループが続く条件; 1回の処理の最後に行われる処理){ //繰り返す処理内容 } ``` 10回繰り返す場合は以下のようになります。 ``` for(i=0; i<10; i++){ //繰り返す処理内容 } ``` 配列では同じ型のデータを一つの変数に与えることができます。これを使って複数のデータを一つの変数に入れることができるになります。変数の要素は図のように入れられています ![](https://i.imgur.com/BfaSRns.png) enchant.jsで変数で配列を使えるようにするには変数の定義をしていた箇所を下のようにしてください。 ``` var fruites = Array(); ``` これを実際にやってみるとこうなります ``` for (i = 0; i < 10; i++) { fruits[i] = new Sprite(16,16); fruits[i].image = game.assets['icon0.png']; fruits[i].frame = 15; /* 0から320未満の任意の整数を設定 */ fruits[i].x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits[i].y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits[i]); } ``` </details> </br> これでfruits[0]からfruits[9]の10個の変数に画像と座標が設定されて 画面に表示されるようになりました。 ### Step5 クラスを活用しよう(その1) <font color="red">ここから今日の新しいテーマになります。</font> このステップでの目標は、コードを部品ごとにまとめて、見栄えを向上させることです。そのためにクラスというものを勉強します。 これからくまとフルーツに色々な要素を追加していきたいのですが、このまま書き続けてもコードがごちゃごちゃになってしまいますそこでクラスを活用します。まずは下のサンプルコードを確認し、コードを変更してみましょう。大幅に変更されているので、丁寧に見比べながらどこをどう変更したのか確認しながら変更してください。 <details><summary>サンプルコードはここをクリック。</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { //初期化する Sprite.call(this, 32, 32); //Spriteオブジェクトを初期化 this.image = game.assets['images/chara1.gif']; //クマのx座標を決める this.x = x; //クマのy座標を決める this.y = y; this.frame = 10; game.rootScene.addChild(this); }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif'); var bear; var fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); for (i = 0; i < 10; i++) { fruits[i] = new Sprite(16,16); fruits[i].image = game.assets['images/icon0.gif']; fruits[i].frame = 15; /* 0から320未満の任意の整数を設定 */ fruits[i].x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ fruits[i].y = Math.floor(Math.random() * 320); game.rootScene.addChild(fruits[i]); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> クラスとは,プログラミングを楽にするために考案されたコードの部品化の方法です。これを利用することでプログラムを要素を分けながら書くことができます。 ここでは、クマのキャラクターを一つの部品としました。つまり、クラス化したということです。 コードの4行目から16行目を確認してください。くまのクラスBearが作られています。 ``` Bear = Class.create(Sprite, { initialize: function(x, y) { //初期化する Sprite.call(this, 32, 32); //Spriteオブジェクトを初期化 this.image = game.assets['chara1.png']; this.x = x; this.y = y; this.frame = 10; game.rootScene.addChild(this); }, }); ``` クラスは"window.onload"の外側に書いてください。 initializeは初期状態を書く場所でここに書いておくとクラスを呼び出したときにすぐに呼ばれます。クラスの中ではクラス自身を対象とするとき変数名は全てthisを使います。例えば、「bear.image」は「this.image」になります。 また、クラスには引数というものを入れることができます。今回の場合は(x,y)の2要素になります。この引数はクラス内で使うことができます。 ``` initialize: function(x, y) { ``` このクラスBearを利用するには以下のようになります。 ``` bear = new Bear(32, 32); ``` ここに記述している(32,32)はクラスの引数x,yに継承されるものであり、くまの座標位置は(32,32)になります。 とても難しい内容なのでわかりづらい方はクマのスタンプを思い浮かべてみてください。今、目の前にあるノートの1ページ目にそのスタンプを押すと、クマの絵が描かれます。そのまま次のページをめくってスタンプを押してみましょう。また同様の絵が描かれますよね?クラスとはそのスタンプの役割を果たしていると考えてみてください。 コードの4行目から16行目を確認してください。例で例えるとこの部分でBearという名前のスタンプを作っています。そのスタンプの使い方は6行目に書かれています。そのスタンプを使うためには、xとyという2つの変数が必要です。まだここではその2つの変数が意味するものは分かりません。そのまま次の行を見てみましょう。 7行目をみると、そのスタンプをスプライトにしてくださいと書かれています。thisという変数は、スタンプ自身を表していると考えてください。8行目では、this.image、つまりそのスタンプ自身の画像を設定しています。10行目、12行目ですが、ここでx,yという新しい変数が出てきました。this.x = x ということはつまり自分自身のx座標をスタンプを使う際に必要であったxという変数にしてください、と 同様にthis.y = y、つまり自分自身のy座標をスタンプを使う際に必要であったyにしてください と書かれています。つまりスタンプを使うために必要であったxとyという変数はスタンプを押すときにどこに押すのかをきめるための変数になっています。以下16行目までスタンプを作っていると考えてください。 せっかく作ったスタンプも押さなければ意味がありません。そのスタンプを押すという行動が28行目です。 ``` bear = new Bear(32, 32); ``` 今回作ったスタンプの名前はBearです。()の中身は最初に設定したスタンプを利用するために必要な2つの変数、xとyに対応しています。つまりこれは(32,32)の部分にスタンプを押してください。つまり(32,32)の部分にスプライトを置いてくださいね という意味になります。 このようにくまの表示をさせていた部分がシンプルになり分かりやすくなったはずです。 ## Step6 クラスを活用しよう(その2) ではフルーツも同様にクラス化していきましょう。以下の記述を、クマのクラスの下に記述します。 ``` /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); } }); ``` 今回は引数をframeという要素1つだけにします。 また、フルーツを作成したい部分を以下に書き換えます。クラスFruitsの呼び出し方はクラスBearと同じです。配列に入れるのを忘れないようにしてください。 ``` for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } ``` <details> <summary>ここまでのサンプルコードはこちら</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; this.frame = 10; game.rootScene.addChild(this); }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); } }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif'); var bear; var fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.x = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.y = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> </br> 画像が表示される部分がすべてクラスに移行しすっきりしました。 ## Step7 キャラに動作を付けよう(復習) このStepでの目標はクマの動きを滑らかにすることです。完成図のANSWERの部分を確認してください。クマが滑らかに動いていることがわかります。 ![](https://i.imgur.com/klE2Iei.gif) <details> <summary>コードは以下のようになります。</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { //遅くするための変数 slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif'); var bear; var fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> 今回はクマの動きを変更するのでBearクラスの中身を書き換えました。 まずはべつのx,yと同様なものtx,tyをBearに定義してクリックした座標をそこに入れます。 game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; tx,tyにだんだん近づくようにenterframeを利用します。 enterframeはフレームごとに行われる動作でゲームプレイヤーが操作を行わなくても動作を続けます。フレームは初期は1/60秒に1進みます。Bearのクラスに以下の関数を加えてみましょう。これでクラスBearを読んでから1フレームごとに行われる処理を書くことができます。 ``` onenterframe: function() { //内容 } ``` ここにくまがだんだんクリックした地点に近づくような処理を書いていきます ``` slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; ``` これでだんだんくまがクリックした地点に近づいていくようになります。 ## Step8 当たり判定を設定しよう(復習) ここまで来たらくまがフルーツに触れたらフルーツが消えるようにしましょう。 そこでこのStepでは、スプライト同士の接触判定とif文について学ぶことを目標にします。 ![](https://i.imgur.com/jxixLl7.gif) それではサンプルコードを参考にコードを書き換えてみてください。 <details><summary>サンプルコードはこちら</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { //bearに触れたとき if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif'); fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); }; ``` </details> 当たり判定はif文を用いてクラスFruitsに「もしフルーツがくまに触れたら」というものを作ります。 if文はプログラムにおいて条件分けの時に使います ``` if (条件) { //条件を満たした時行う処理 } ``` ()の中に条件を書いてその条件を満たしたとき{}の中の処理を行います。if文の例を書いておいたので興味がある方は以下を参考にしてみてください <details><summary>if文の例が気になる方はこちらをクリック</summary> 例を挙げます。 ``` a = 6; if (a < 10) { 〇〇 } ``` この場合、〇〇の処理を行うことはできるでしょうか。答えはできます。 命令としては、まずa = 6なのでaは6です。 if(a < 10)というのは、「もし、aが10より小さいならば」 と書かれています。今、aは6としているため、「もし、aが10より小さいならば」というのは正しいことになります。 これが正しい場合、〇〇の部分を行うことができます。というのがif文です。反対に ``` a = 15; if (a < 10) { 〇〇 } ``` これはどうでしょうか。こればもちろん〇〇の処理をおこなうことはできません。なぜならば、aが15であるからです。if(a < 10)というのは、「もし、aが10より小さいならば」 と書かれています。今回の例では、aは15としているため、「もし、aが10より小さいならば」というのは間違っていることになります。こういった場合、〇〇を行うことはできません。 今は数値で例を挙げましたが、条件部分(例ではa < 10にあたる部分)は数値である必要はありません。 例えば、今回のプログラムでは、 ``` if (this.within(bear)) { ``` </details> onenterframeはフレームごとに行う処理の記述方法でした ``` onenterframe: function() {  ・  ・  ・ } ``` と書くことで、「フレームが更新されるたびに・・・の処理を行う」という意味になることを思い出してください。 つまりonenterframeの中に、命令を書いておくと、1フレームごとに条件を満たしているかどうかの判定を行うことができます。fruitsのonenterframeの中にif文を追加してみましょう。enchant.jsでは触れた処理をするときにはwithin(触れるもの)をif文の()に入れます。 つまり、 ``` if (this.within(bear)) {  ・  ・  ・ } ``` というのは、<font color="red">「もし、this(つまりFruits)がbearと接触したならば、・・・をしてください」</font>という意味になります。この判断をフレームごとに行っているわけです。 次にif文の中にフルーツが消えるように記述していきます。 enchan.jsで画面から画像を消すにはaddChildのようにremoceChildを 使用してください。 45行目 ``` game.rootScene.removeChild(this); ``` <font color="red">「this(つまりFruits)をゲーム画面から除外する」</font>ということです。 これでフルーツにクマが触れるとフルーツが消えるようになります。 ### Step9 ゲームを完成させよう(復習) ここまで来たらあとは仕上げです。フルーツをすべて取ったらゲームクリアが表示され、ダイヤログが表示されるようにしましょう。 ![](https://i.imgur.com/kJDjT0Y.png) それではサンプルコードを参考にコードを変更します。 <details><summary>サンプルコードはこちら</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); /* スコアを0に設定 */ score = 0; fruits = Array(); game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ //game.start(); game.debug(); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; }; ``` </details> 得点を入れるための変数はscoreとします。まず、ゲームが開始されたタイミングでは当然scoreは0ですよね?ゲームが始まったタイミング、つまりwindow.onloadの中でscoreを0にしておきましょう。 つまり、56行目~ ``` /* スコアを0に設定 */ score = 0; fruits = Array(); game.onload = function() { ``` となります。 つぎはscoreが増えるタイミングです。フルーツが消えるたびにscoreを+1すればよさそうです。 つまり、フルーツが消えるタイミングである45行目 ``` score++; ``` となります。score\+\+は難しい表現ですね。同じ表記方法として ``` score = score + 1; ``` があります。(score\+\+とscore = score + 1は同じ意味です。)つまり、<font color="red">「score\+\+とはscoreを1増やしてください」という意味</font>です。 ではgame.onenterframeにコードを追加して、scoreが10になったときにクリア画像(clear.png)が表示されるようにしましょう。 ゲームないで画像を使う場合は、game.preloadの部分にすべて表記しておく必要がありました。 54~55行目のgame.preloadに'images/clear.png'を追加しましょう。 ``` game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); ``` 今回はさらにクリア画面が出た後に点数が表示されるようにしています。 81行目を確認してください。 ``` game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; ``` game.onenterframeはStep7で学んだenterframeを利用しています。つまり、 ``` game.onenterframe = function(){  ・  ・  ・ } ``` とすることで、<font color="red">ゲームのフレームが更新されるたびに「・・・」の命令をおこなうこと</font>になります。 else ifとはif文からさらに条件を分岐するためのものです。if(条件)を満たしていないとき、かつelse ifの()内の条件を満たしたときのみ処理を行います。つまり ``` if(条件){ 〇〇 } else { △△ } ``` という構文があった場合、<font color="red">条件を満たしていれば〇〇を、そうでないときは△△を行うこと</font>になります。 今回はゲーム画面にメッセージを表示したいのでalertを使います。alertの書き方は以下のようになっています。 ``` alert("表示したい文字"); ``` 変数の値を出したいときは以下のようになっています。 ``` alert(変数名+"表示したい文字")//「変数名表示したい文字」が画面にでる alert("表示したい文字"+変数名)//「表示したい文字変数名」が画面にでる alert("表示したい文字"+変数名+"表示したい文字")//「表示したい文字変数名表示したい文字」が画面にでる ``` これでゲームの完成です。 ここまでが1日目までで出来上がった部分になります。 それではコードに新しい要素を追加していきましょう。 追加していく要素はこの4つになります。 * ゲーム画面にscoreを表示する * ゲーム画面にタイマーをつけて、制限時間をつける * フルーツのクラスを2つ作って、それぞれとったときに違うスコアになるようにする * 爆弾を画面外四方向から一直線に移動してくるようにして、クマが触れたらゲームオーバーになるようにする。 #### 追加要素を始める前に game.onenterframeの処理をgame.onloadの中に入れるようにしておきます。このような書き方にするとgame.onloadの中で宣言した変数がそのまま使えるようになります。皆さんの問題ではすでにこの作業をしているので安心してください。 <details> <summary>ここまでのコードはこちらをクリック</summary> ```javascript= enchant(); //グローバル変数の設定 /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> ### Step10 画面にスコアを表示させよう 今の状態のゲームではゲームをやっている人が、スコアが何点であるか判断することが難しくなっています。 そこでゲーム画面にテキストラベルをだしてスコアを表示させましょう。 ![](https://i.imgur.com/p7jOaq9.png) #### 画面にスコアラベルを出す。 それではコードの68行目と69行目の間に以下のコードを入力してください。 ``` // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); ``` <details> <summary>ここまでのコードはこちらをクリック</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> スコアラベルとは、完成図のゲーム画面左上に表示されている得点の画面のことです。 スコアラベルの定義は以下のようになっています。 ``` 変数名 = new ScoreLabel(ゲーム上のx座標,ゲーム上のy座標); ``` 今回の場合は(10,10)の位置にスコアラベルを配置しています。 画像の通りスコアラベルというものを使うとデコレーションされた文字の画像を使って"SCORE:"を表示させる機能を持っています。 また、"SCORE:"という文字の右側に表示する数字は、以下のように設定できます。 ``` scoreLabel.score = 数値; ``` "SCORE:"の右側に表示したい数字はもちろん得点です。そのため、変数scoreを代入します。スコアラベルのような文字列も画面に表示するにはgame.rootScene.addChild();を使います。 #### スコアラベルの更新 スコアラベルは今のままではフルーツを取っても値が更新されません。これはゲームを開始するときにしか、scoreLabel.scoreを変更していないからです。 なので、フルーツを取ったときにスコアラベルの値を更新するようにしましょう。 フルーツをとったタイミングは、42行目から47行目の間でしたね。そこに、先ほど勉強した命令、 ``` scoreLabel.score = score;//スコアを更新する ``` を追加しましょう。追加した結果以下のようになります。 ``` if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } ``` <details> <summary>ここまでのコードはここをクリック</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> これでフルーツを取ったときにスコアの値を更新することができるようになりました。 ### Step11 画面にタイマーを表示させよう 次にゲーム画面にタイマーを表示させて、時間制限をつけましょう。 ![](https://i.imgur.com/0erVjcs.png) #### タイマーラベルの表示 スコアラベルと似たように、タイマーラベルというものもあります。 下のコードを71行目の下(スコアラベルを作ったところの下)に打ってみましょう。 ``` // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); ``` <details> <summary>ここまでのコードはここをクリックしてください</summary> enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; </details> タイムラベルの使い方は、スコアラベルとは違い()の中に3つの要素が必要です。 使い方は以下のようになっています。 ``` タイムラベル = new TimeLabel(変数名 = new ScoreLabel(横軸の位置,縦軸の位置, "タイマーの種類"); ``` 今回使用した"countdown"はタイマーにカウントダウンをつけるための命令です。これを書くと、ゲームが始まったときに、自動でタイマーの秒数が減ります。また、 ``` 変数名.time = "秒数" ``` とすることでタイマーの秒数を設定することができます。今回は30と入力したのでタイマーは30秒になります。 #### タイムオーバーの追加 しかし今のままでは0秒を切ってもタイマーは止まりません。タイマーラベルは時間を表示や計測、保存する機能しかないためです、そこでgame.onenterframeの中にタイマーが0を下回ったときの処理を加えましょう。 下のコードを89行目のした(else ifの処理の下)に書きましょう ``` if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruitsの定義 */ Fruits = Class.create(Sprite, // Spriteクラスを継承 { initialize: function(frame) { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = frame; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> 今回はif文を使って条件を書きました。今回の条件はtimeLable.timeの値が0よりも小さいときです。このようにif文では等しいときだけでなく、左右の大小比較の条件式も多く使います。下に例を挙げます。 ``` if(a<b) //もしaがbよりも小さいならば if(a>b) //もしaがbよりも大きいならば if(a<=b) //もしaがb以下ならば if(a>=b) //もしaがb以上ならば ``` つまり、90行目から94行目をまとめると、 ``` if(timeLabel.time<0){          |もし、タイマーの時間が0より小さいならば、 game.end();              |ゲームを終了してください game.onenterframe = null;  |フレームの更新をやめてください alert(score + "点獲得しました!");  |〇点獲得しました!と表示してください } ``` となります。92行目は難しいので、このような表記をしないといけないんだな。と思っていただければよいです。 これでゲームにタイムオーバーを導入できました。 ![](https://i.imgur.com/il6SZgp.png) 画像の追加をせずにgame.end()を行うと「gameover」の画像が出ることを覚えておきましょう。 ### Step12 フルーツを作るクラスを複数作ろう では次にフルーツを作るクラスを2個にしてそれぞれ、リンゴとバナナを出すようにしてみましょう。 ![](https://i.imgur.com/OAdI9pA.png) #### クラスの作成 それでは今までフルーツを表示していたクラスFruitsをなくして代わりにFruits1,Fruits2を作成しましょう。 ```javascript= /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); var fruits = Array(); /* スコアを0に設定 */ score = 0; game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { fruits[i] = new Fruits(15); } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> 内容はFruitsのものと基本同様です、ただし引数frameをなくして、何も要素を入れなくても呼び出せるようにしました。またFruits2のクラスで消えたときに増えるscoreを2にしてみました。 今のままだとプログラムは動かないので注意してください。 #### 10個の2種類のフルーツがランダムに出るようにする それではこの2つのクラスを入れる変数を用意しましょう。80行目(var fruits=Array()を宣言していたところ)を下のように書き換えましょう。 ```javascript= //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; ``` i1とi2は今まで配列の[]の中にいれていたiの代わりです変数は頭文字でなければ数字を使うことができます。 では配列とif文とランダム変数Math.ramdomを使って下のようなコードを作りましょう。書く場所は93行目です。 ```javascript= /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { //作るフルーツをランダムにする //0から1まででのランダムな値を作成する random = Math.floor(Math.random()*2); if(random == 0){ fruits1[i1] = new Fruits1(); i1 = i1+1; } if(random == 1){ fruits2[i2] = new Fruits2(); i2 = i2+1; } } ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; /* スコアを0に設定 */ score = 0; var random = 0;//ランダムな値を保存する変数 game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { //作るフルーツをランダムにする //0から1まででのランダムな値を作成する random = Math.floor(Math.random()*2); if(random == 0){ fruits1[i1] = new Fruits1(); i1 = i1+1; } if(random == 1){ fruits2[i2] = new Fruits2(); i2 = i2+1; } } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> 条件が成り立ったときのみi1とi2の値を+1することで配列を0から順番に使うことができるようになります。 これでランダムにフルーツを選ぶことができました。 ### Step13 画面外から出てくる爆弾を作ろう それでは画面左側から右に向けて一直線に飛んでくる爆弾を作成しましょう。 ![](https://i.imgur.com/TiwF0EL.gif) #### クラスBombの作成 それではまずは爆弾を作るクラスを作成しましょう。 クラスの要件は以下のようになっています。 * 1.横は0,縦ランダムで画面に表示される * 2.左から右に一直線に移動する * 3.クマが触れたときゲームオーバーになる それはクラスを作っていきましょう。 下のコードを76行目(クラスFruits2の下)に追加してください ```javascript= /*独自クラスBombの定義*/ Bomb = Class.create(Sprite, { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 24; /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); this.x = 0; this.y = this.random; game.rootScene.addChild(this); }, onenterframe: function() { //左から右へと1直線に移動するようにする this.x = this.x + 1; this.y = this.random; if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } } }); ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); /*独自クラスBombの定義*/ Bomb = Class.create(Sprite, { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 24; /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); this.x = 0; this.y = this.random; game.rootScene.addChild(this); }, onenterframe: function() { //左から右へと1直線に移動するようにする this.x = this.x + 1; this.y = this.random; if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } } }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //爆弾用の配列を用意する var bomb = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; //爆弾配列に入っている爆弾の個数確認用変数 var i3 = 0; /* スコアを0に設定 */ score = 0; var random = 0;//ランダムな値を保存する変数 game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { //作るフルーツをランダムにする //0から1まででのランダムな値を作成する random = Math.floor(Math.random()*2); if(random == 0){ fruits1[i1] = new Fruits1(); i1 = i1+1; } if(random == 0){ fruits2[i2] = new Fruits2(); i2 = i2+1; } } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> 要件1を満たす処理は下の部分です ``` /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); this.x = 0; this.y = this.random; ``` フルーツの時は両方共をランダムにしていましたが、今回はyのみをランダムにしました。これで横を左端に固定したままにできます。 要件2を満たす処理は下の部分です ``` //左から右へと1直線に移動するようにする this.x = this.x + 1; this.y = this.random; ``` 1フレームごとに.xを1増やせば左から右へだんだん移動することがきるようになります。 最後に要件3です。 ``` if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } ``` 基本はタイムオーバーの時と同じです。 これでクラスの完成です。 #### 爆弾を定期的に表示する まずは配列を用意していきましょう。 fruits1,2の配列の宣言部分を以下のようにしていきます。 ```javascript= //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //爆弾用の配列を用意する var bomb = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; //爆弾配列に入っている爆弾の個数確認用変数 var i3 = 0; ``` では爆弾を作る処理を作りましょう。 爆弾は上の画像の通り、ゲームが進むたびにランダムに表示されます。game.enterframeの中にif文を活用して1フレームに5%の確立で表示するようにしてみましょう。 それでは下のコードを148行目( game.onenterframe = function(){のした)に書いていきましょう。 ```javascript= //爆弾をランダムな確率で画面に出す //1から100までのランダムな値を作成する random = Math.floor(Math.random()*100+1); //ランダムな値が5以下の時爆弾を表示する if(random<=5){ bomb[i3] = new Bomb(); i3++; } ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); /*独自クラスBombの定義*/ Bomb = Class.create(Sprite, { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 24; /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); this.x = 0; this.y = this.random; game.rootScene.addChild(this); }, onenterframe: function() { //左から右へと1直線に移動するようにする this.x = this.x + 1; this.y = this.random; if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } } }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //爆弾用の配列を用意する var bomb = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; //爆弾配列に入っている爆弾の個数確認用変数 var i3 = 0; /* スコアを0に設定 */ score = 0; var random = 0;//ランダムな値を保存する変数 game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { //作るフルーツをランダムにする //0から1まででのランダムな値を作成する random = Math.floor(Math.random()*2); if(random == 0){ fruits1[i1] = new Fruits1(); i1 = i1+1; } if(random == 0){ fruits2[i2] = new Fruits2(); i2 = i2+1; } } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ //爆弾をランダムな確率で画面に出す //1から100までのランダムな値を作成する random = Math.floor(Math.random()*100+1); //ランダムな値が5以下の時爆弾を表示する if(random<=5){ bomb[i3] = new Bomb(); i3++; } if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> 配列を使って行うのでやり方はフルーツの時と同様です。 ### Step14 爆弾が画面端四方向から出てくるようにしよう では最後にクラスBombを書き換えて上下左右方向から爆弾が出てくるようにしましょう。 やり方はinitializeで初期設定を行うときにランダムとif文を使うことです。 ランダムに決めた値を使って爆弾の初期位置と向かう方向を決めていきましょう。 それではクラスBombを下のように書き換えていきましょう。 ```javascript= /*独自クラスBombの定義*/ Bomb = Class.create(Sprite, { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 24; //出てくる方向をランダムに決める 0:左 1:上 2:右 3:下 this.pattern = Math.floor(Math.random()*4); /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); //左から出るようにする if(this.pattern == 0){ this.x = 0; this.y = this.random; } //上から出るようにする if(this.pattern == 1){ this.x = this.random; this.y = 0; } //右から出るようにする if(this.pattern == 2){ this.x = 320; this.y = this.random; } //下から出るようにする if(this.pattern == 3){ this.x = this.random; this.y = 320; } game.rootScene.addChild(this); }, onenterframe: function() { //左から右へ直線移動する if(this.pattern == 0){ this.x = this.x+1; this.y = this.random; } //上から下へ直線移動する if(this.pattern == 1){ this.x = this.random; this.y = this.y+1; } //右から左へ直線移動する if(this.pattern == 2){ this.x = this.x-1; this.y = this.random; } //下から上へ直線移動する if(this.pattern == 3){ this.x = this.random; this.y = this.y-1; } if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; } } }); ``` <details> <summary>ここまでのコードです</summary> ```javascript= enchant(); /* 独自クラスBearの定義 */ Bear = Class.create(Sprite, { initialize: function(x, y) { Sprite.call(this, 32, 32); this.image = game.assets['images/chara1.gif']; this.x = x; this.y = y; /* 行きたい場所のX座標 */ this.tx = this.x; /* 行きたい場所のY座標 */ this.ty = this.y; this.frame = 10; game.rootScene.addChild(this); }, /* enterframeイベントのリスナーを設定 */ onenterframe: function() { slow = 30; this.x += (this.tx - this.x) / slow; this.y += (this.ty - this.y) / slow; }, }); /* 独自クラスFruits1の定義 */ Fruits1 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 15; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score++; scoreLabel.score = score;//スコアを更新する } }, }); /* 独自クラスFruits2の定義 */ Fruits2 = Class.create(Sprite, // Spriteクラスを継承 { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 16; /* 0から320未満の任意の整数を設定 */ this.x = Math.floor(Math.random() * 320); /* 0から320未満の任意の整数を設定 */ this.y = Math.floor(Math.random() * 320); game.rootScene.addChild(this); }, onenterframe: function() { if (this.within(bear)) { // 自分自身(フルーツ)を画面から消す game.rootScene.removeChild(this); score = score+2; scoreLabel.score = score;//スコアを更新する } }, }); /*独自クラスBombの定義*/ Bomb = Class.create(Sprite, { initialize: function() { Sprite.call(this, 16, 16); this.image = game.assets['images/icon0.gif']; this.frame = 24; //出てくる方向をランダムに決める 0:左 1:上 2:右 3:下 this.pattern = Math.floor(Math.random()*4); /* 0から320未満の任意の整数を設定 */ this.random = Math.floor(Math.random() * 320); //左から出るようにする if(this.pattern == 0){ this.x = 0; this.y = this.random; } //上から出るようにする if(this.pattern == 1){ this.x = this.random; this.y = 0; } //右から出るようにする if(this.pattern == 2){ this.x = 320; this.y = this.random; } //下から出るようにする if(this.pattern == 3){ this.x = this.random; this.y = 320; } game.rootScene.addChild(this); }, onenterframe: function() { //左から右へ直線移動する if(this.pattern == 0){ this.x = this.x+1; this.y = this.random; } //上から下へ直線移動する if(this.pattern == 1){ this.x = this.random; this.y = this.y+1; } //右から左へ直線移動する if(this.pattern == 2){ this.x = this.x-1; this.y = this.random; } //下から上へ直線移動する if(this.pattern == 3){ this.x = this.random; this.y = this.y-1; } if (this.within(bear)) { //ゲームオーバーになる game.end(); game.onenterframe = null; } } }); window.onload = function() { game = new Game(320, 320); game.preload('images/chara1.gif', 'images/icon0.gif', 'images/clear.png'); //果物用の配列を2つ用意する var fruits1 = Array(); var fruits2 = Array(); //爆弾用の配列を用意する var bomb = Array(); //配列に入っているフルーツの個数確認用変数 var i1 = 0; var i2 = 0; //爆弾配列に入っている爆弾の個数確認用変数 var i3 = 0; /* スコアを0に設定 */ score = 0; var random = 0;//ランダムな値を保存する変数 game.onload = function() { /* クマさんをつくる */ bear = new Bear(32, 32); /* フルーツを10個作る*/ for (i = 0; i < 10; i++) { //作るフルーツをランダムにする //0から1まででのランダムな値を作成する random = Math.floor(Math.random()*2); if(random == 0){ fruits1[i1] = new Fruits1(); i1 = i1+1; } if(random == 0){ fruits2[i2] = new Fruits2(); i2 = i2+1; } } // スコアラベルを作成 scoreLabel = new ScoreLabel(10, 10); scoreLabel.score = score; game.rootScene.addChild(scoreLabel); // タイムラベルを作成 timeLabel = new TimeLabel(26, 30, "countdown"); timeLabel.time = 30; game.rootScene.addChild(timeLabel); game.onenterframe = function(){ //爆弾をランダムな確率で画面に出す //1から100までのランダムな値を作成する random = Math.floor(Math.random()*100+1); //ランダムな値が5以下の時爆弾を表示する if(random<=5){ bomb[i3] = new Bomb(); i3++; } if(score==10){ /* クリア画面を出したいときは以下の記述 */ game.endScene = new SplashScene(); game.endScene.image = game.assets['images/clear.png']; game.end(); score++; } else if(score ==11){ alert(score + "点獲得しました!"); /* alertを何度も表示されないようにする処理 */ game.onenterframe = null; } if(timeLabel.time<0){//タイムが0を下回ったとき game.end(); game.onenterframe = null; alert(score + "点獲得しました!"); } }; }; game.rootScene.ontouchend = function(event) { /* クマの「行きたい場所」にタッチされたX座標を指定 */ bear.tx = event.x; /* クマの「行きたい場所」にタッチされたY座標を指定 */ bear.ty = event.y; }; /* game.debug()で動かすと,画像の枠がわかりやすくなるため,当り判定が確認しやすい */ // game.start(); game.debug(); }; ``` </details> this.patternという変数を用意してinitilizeの中でランダムに0から3の値を入れていきます。 ``` //出てくる方向をランダムに決める 0:左 1:上 2:右 3:下 this.pattern = Math.floor(Math.random()*4); ``` この変数pattermを使ってif文で初期位置や移動方向を決めていきましょう。 **初期位置のコード** ``` //左から出るようにする if(this.pattern == 0){ this.x = 0; this.y = this.random; } //上から出るようにする if(this.pattern == 1){ this.x = this.random; this.y = 0; } //右から出るようにする if(this.pattern == 2){ this.x = 320; this.y = this.random; } //下から出るようにする if(this.pattern == 3){ this.x = this.random; this.y = 320; } ``` **移動時のコード** ``` //左から右へ直線移動する if(this.pattern == 0){ this.x = this.x+1; this.y = this.random; } //上から下へ直線移動する if(this.pattern == 1){ this.x = this.random; this.y = this.y+1; } //右から左へ直線移動する if(this.pattern == 2){ this.x = this.x-1; this.y = this.random; } //下から上へ直線移動する if(this.pattern == 3){ this.x = this.random; this.y = this.y-1; } ``` これでゲームの完成です。 ## 最後に これで今回のゲーム「クマさんのフルーツ狩り」の説明は終了ですが、皆さんのアイデアを使えばより面白いゲームに作り変えることができます。そこで、 さらにこんな機能があったらおもしろくなるかもしれない というアイデアを少しだけここに書いておきます。 ``` ・フルーツもランダムに出てくるようにする。 ・クマをマウスクリックだけでなくキーボードの矢印キーでも動かせるようにする。 ・爆弾のでる数を増やして、タイムオーバーになったとき「clear」の画像がでるようにする ・取るとスコアの減るアイテムを増やしてみる。 ```