うっほー!ゴッリラだよ!
いよいよ本格的に寒くなってきたね!!
朝目覚めると、凍っていることがしょっちゅうだよ(´・ω・)


さて!氷も溶けたところで、今回は前回の続きを作っていくよ!
まだ、パート①、②、③をやっていないよ!っていう人は、先にそっちを終わらせてね!
★目次
7. 前回の補足
いよいよ、このシリーズも終わりに近づいてきたね!
今回のパートでは、スコア、プレイヤーの残機、タイトル画面を追加するよ!
素材ファイルに2つ画像を追加したからダウンロードしておいてね!
新しい工程に取り掛かる前に、前回のパートで追加するのを忘れていた、
プレイヤーと隕石の当たり判定、弾の削除処理を追加していこう!
・プレイヤーの当たり判定を追加
まずは、Add Eventをクリックして、Collision Eventを追加しよう!

Colision Eventは、インスタンス同士が重なり合った時に呼び出されるイベントだよ!
プレイヤーが隕石と衝突した時に、破壊される処理を追加しよう!
1 2 3 4 5 6 7 8 |
//宇宙船を削除
instance_destory(); //破片を10個作成
repeat(10)
{
instance_create_layer(x,y,"Instances",o_debris);
} |
前回の弾と隕石の衝突時の処理とまったく同じコードなので、説明は省略するね!
・弾丸オブジェクトにOutside Room Eventを追加しよう
Add Eventをクリックして、Outside Room Eventを追加しよう!

今回初登場のOutside Room Eventは、インスタンスが画面外に飛び出した時
呼び出されるイベントの事だよ!
今の所、隕石に衝突しなかった弾丸はそのまま存在し続けてしまっているんだ!
ここままだと、弾丸の数が増えていく毎にメモリーの使用率が上がってしまうので、
弾丸がゲーム画面から飛び出したときに削除されるようにしよう!

1 2 |
//弾丸がゲーム画面外に飛び出した時インスタンスを削除
instance_destory(); |
8. Roomを追加しよう!

説明するのが遅れたけど、これが今回のゲームの流れになるよ!
見ての通り4つのゲーム画面(Room)が必要になるので新しく追加していこう!
画面右Resource内のRoomsを右クリック → Create Room

Roomを3つ追加したら、それぞれ画面のサイズを500×500に変更しよう!
画面右側のRoomをクリック → 左下のProperties内のWidth, Height 欄に500を入力

サイズが変更出来たら、画像の通りに名前を変更しよう!
最初に作成したゲーム画面は、r_gameと名付けてね!
roomを選択して右クリック → Renameを選択
ゲームを起動したとき、Roomsの一番上に表示されている画面から読み込まれるんだ!
このままだとゲーム画面が一番最初に表示されてしまうので、r_gameをドラッグ&ドロップして
優先順位を入れ替えよう!

9. 管理システムを作ろう!

ゲーム画面も追加したところで、いよいよ本題に入ろう!
今回はゲームのスコア、残機、Room間の移動などを管理する、
ゲームオブジェクトを作成していくよ!
・ゲームオブジェクトを作成
画面右Resource内のObjectを右クリック → Create Objectを選択

①オブジェクトの名前を変更しよう!
おすすめはo_gameだよ!
・Create Eventを追加しよう!
②Add Eventをクリックして、Create Eventを追加しよう!
ここでは、スコアと残機を宣言するよ!
1 2 |
score = 0;
lives = 3;
|

どのオブジェクトからでもアクセスすることができるんだ!
・Step Eventを追加しよう
③Add Eventをクリックして、Step Eventを追加しよう!
ここでは、ENTERキーが押された時Roomに合わせた処理を実行させるよ!
以下のコードを記述してね!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
if(keyboard_check_pressed(vk_enter)) { switch(room) { //開始画面であればゲーム画面に移動 case r_start: room_goto(r_game); break; //ゲームオーバー/クリア画面であればゲームを再起動 case r_gameover: case r_win: game_restart(); break; } } if(room == r_game) { //スコアが1000以上であればクリア画面へ if(score >=1000) { room_goto(r_win); } //残機が0以下であればゲームオーバー画面へ if(lives <=0) { room_goto(r_gameover); } } |
switch文の使い方については、以前の記事で紹介したので省略するね!
処理の流れとしてはSpaceキーが押された時、開始画面だった場合
1 2 3 4 |
//スタート画面
case r_start:
room_goto(r_game);
break;
|
room_goto関数を使って、ゲーム画面に移行しているよ!
room_goto(room)関数は、呼び出すと指定したroomに移動してくれんだ!
Roomに関しての関数は他にもいくつかあるので、公式ページを確認してみてね!
そして、Spaceキーが押されたとき、ゲームオーバー/クリア画面だった場合
1 2 3 4 5 |
//ゲームオーバー/クリア画面であれば
ゲームをリセットして開始
case r_gameover:
case r_win:
game_restart(); break; |
game_restart()関数を使い、ゲームをリセットして再開しているよ!
定数式を続けて書くことで、if文で言うところのor処理をさせることができるんだ!
最後のif分ではroomがゲーム画面の時、2つの条件を確認していて
1 2 3 4 5 6 7 8 9 10 11 |
if(room == r_game) { if(score >=1000) { room_goto(r_win); } if(lives <=0) { room_goto(r_gameover); } } |
1つは、プレイヤーのスコアが1000以上に達した時、
さっき説明した、room_goto関数を使ってクリア画面に移動させているよ!
もうひとつは、プレイヤーの残機が0以下になった時、
ゲーム画面をゲームオーバー画面に移動させているんだ!

・Draw Eventを追加しよう!
④Add Eventをクリックして、Step Eventを追加しよう!

Draw Eventは、画面に何かを描写したい時に使用するイベントなんだ!
今回は、ゲームのタイトル、スコアを表示するのに利用するよ!!
Dropboxの素材フォルダーに、新しいSpriteを3つ追加しておいたので、
ダウンロードしてSpriteとして読み込もう!
Spriteが読み込めたら以下のコードを追加してね!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
switch(room) { case(r_start): draw_sprite(s_game,0,0,0,); break; case(r_game): draw_text(20,20,"SCORE: "+string(score)); draw_text(20,40,"LIVES: "+string(lives)); break; case(r_gameover): draw_sprite(s_gameover,0,0,0); break; case(r_win): draw_sprite(s_win,0,0,0); break; } |
どう?さっきのStep Eventと比べてみるとほとんど一緒だよね!
ただ、2つ初登場の関数があるのでそれだけ解説するね!
draw_sprite()は、Sprite, Spriteの開始番号, xy座標を引数として受け取る関数で、
指定した位置にSpriteを描写してくれるよ!
draw_text()はxy座標、文字列を引数として受け取る関数で、
指定した位置に文字列を表示してくれるんだ!

・Persistentにチェックマークを入れよう
⑤Persistentをクリックしてtrueにしよう!
本来オブジェクトは、設置されたRoomを超えて存在することが出来ないんだ!
だけど、o_gameはスコアの値を管理しているため、全ルームに存在していてほしいよね?
だけど、ルームごとにインスタンスを設置すると毎回スコアがリセットされてしまう!
そんな時に役に立つのがPersistentだよ!
PersistentがONになっているインスタンスは、Roomが変わっても同じ位置に存在し続けるんだ!

ついに!タイトル、スコア画面が追加されたね!!
これでよりゲームぽくなってきたよ!
最後にゲームオブジェクトをDrag&Dropして、r_startに配置してね!
*インスタンスの配置方法

10. 残機管理、スコアシステムを追加
・プレイヤーの残機を減らす処理しよう!
プレイヤーが隕石と衝突した時、残機を管理している変数”lives”の値を1つ減らそう!
さっきも言った通りlivesは、グローバル変数なのでそのまま呼び出すことができるよ!
Collision Event に以下の1行を追加してね!
1 2 3 4 5 6 7 8 9 10 11 12 |
//これを追加 //残機を一つ減らす lives -=1; //宇宙船を削除
instance_destory(); //破片を10個作成
repeat(10)
{
instance_create_layer(x,y,"Instances",o_debris);
} |
説明するまでもないと思うけど、ここではプレイヤーが隕石に衝突した時、
残機の数を管理しているlivesから値を1引いているよ!
そしてlivesがゼロ以下になった時、さっきgameオブジェクトに追加した、
Step Event内の以下のコードが実行されて、ゲームオーバー画面に移行するよ!
1 2 3 4 5 6 7 |
...省略 //残機が0以下であればゲームオーバー画面へ if(lives <=0) { room_goto(r_gameover); } } |
今の所、プレイヤーが破壊されてから画面に復活する手段がないので、
次にその処理を追加していこう!
・プレイヤーのリスポーン処理を追加
まずは、gameオブジェクトを開いてアラームイベントを追加しよう!
Add Eventをクリックして、Alarm Event 0を追加

以前の記事でも紹介したけど、Alarm Eventは指定したフレーム後に、
記述したコードを実行してくれるイベントの事だよ!
Alarm Eventについて詳しく知りたい人はこちらの記事をチェック!
イベントを追加出来たら以下のコードを記述してね!
1 |
room_restart(); |
room_restart()関数は、その名の通りRoomを再起動してくれるんだ!
つまり、残機が一つ減った状態でゲームが再開されるということだね!
今追加したAlarm Eventを、プレイヤーと隕石が衝突した時に呼び出そう!
もう一度プレイヤーと隕石の衝突イベントを開いて、以下のコードを追加してね!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//残機を一つ減らす lives -=1; //これを追加 with(o_game) { alarm[0] = 60; } //宇宙船を削除
instance_destory(); //破片を10個作成
repeat(10)
{
instance_create_layer(x,y,"Instances",o_debris);
} |
ここでは、プレイヤーが隕石と衝突してから1秒後にさっき追加した、
Alarm Eventを呼び出しているよ!
アラームイベントをgameオブジェクト内で宣言したため、
with構文を使って呼び出しているんだ!
・スコア増加処理を追加しよう!
いやー長かったね!(;´Д`)これでこのパートは最後!スコア増加処理を追加しよう!
弾丸と隕石の衝突イベントを開いて、以下のコードを追加してね!

1 2 3 4 5 6 7 8 |
//これを追加 score+=10; instance_destroy(); with(other) { ...省略 } |
これも説明する必要はないと思うけど、一応!
弾丸が隕石にヒットする度に、スコアの値を10増加させているよ!
スコアが1000以上に達した時、gameオブジェクト内のStep Event内の
以下のコードが実行されて、ゲームクリア画面に移行するよ!
1 2 3 4 5 6 7 8 9 10 11 |
if(room == r_game) { if(score >=1000) { room_goto(r_win); } if(lives <=0) { ...省略 } } |
・ゲームをテストしてみよう!
今回のパートでは、沢山の機能を追加したよ!一度ゲームを実行して、確認してみてね!
新しく追加したインスタンスが、画面に配置されているかチェックしてね!


まとめ
お疲れ様!これで今回のパートはおしまいだよ!
今までで一番長い回だったね(゜o゜)
アステロイドシリーズの更新が遅れてしまってごめんね(´;ω;`)
なんだか調子が悪くて、ちょっと書いては閉じてまた開いて~、、、
結果130くらいこの記事を編集していたよ(‘Д’)
ただ苦労して書いた甲斐があって、かなり完成に近づいたね!
恐らく次の最終パートでは、隕石の自動生成システムと、音を
追加するよ!更新を楽しみに待っていね!
それじゃあ!この記事が少しでもみんなの役に立ったことを祈っているよ!
質問があればいつでも@hellomanaki、またはコメントで大歓迎!

すみません 質問なんですけど、spritesをroomに置こうとして、ルームのレイヤーがInstancesだと置けないのに、レイヤーをBackgroundにすると置くことができます。これはなんでなんですか?
Spriteはあくまで画像なので、インスタンスレイヤーに配置することはできません! 配置したい物がある場合は、からのオブジェクトを作成してそれにSpriteを割り当ててください! BackGroundレイヤーはSprite(主に背景)を1枚割り当てることができます!
何回もごめんなさい objectに割り当てたsprirteでもspritesから引っ張ってきて、BlackGroundレイヤーに置けば画像として読み込まれて、objectで設定したコマンドは無視される。objectから引っ張ってきて、インスタンスレイヤーに置けばobjectのコマンドも実行されるっていうことでいいんですか??
そうです! オブジェクトに与えたSpriteのみに記述したコードが実行されるので、Backgroudレイヤーには影響を与えることはありません!