アイワナ製作

はじめに

ここではギミックの作り方や、ちょっとしたテクニックについて解説していきます。
ギミック制作に必要な基礎的な部分にも触れていきます。
アイワナの基礎部分についてはI wanna be the engine yuuutu edition ver2.13の初期状態を参考にしていきます。
質問や要望があればツイッター、または掲示板にてお願いします。

メニュー

実績機能の作り方

実績とは?

実績とは、デス数が一定数を超えた時や、隠しアイテムを取得時に取得できるトロフィーのようなものです。
実績は取得時に自動的に保存される為、通常と違う形のセーブ方法が必要になります。
実績機能を作る為に必要な機能としては

となります。
今回はI wanna kill the kamilia3の実績機能を例に解説していきます。
実績の数は10個とします。

実績を保存する機能

実績を保存する為に、セーブ機能に実績を保存する変数を追加します。
Scripts
saveGameItem

file_bin_write_byte(f,global.item[8]);
file_bin_write_byte(f,global.music);

//自分で新しく変数を追加したいときはこの下に記述してください
-------------------追加部分-------------------
file_bin_write_byte(f,global.result1);
file_bin_write_byte(f,global.result2);
file_bin_write_byte(f,global.result3);
file_bin_write_byte(f,global.result4);
file_bin_write_byte(f,global.result5);
file_bin_write_byte(f,global.result6);
file_bin_write_byte(f,global.result7);
file_bin_write_byte(f,global.result8);
file_bin_write_byte(f,global.result9);
file_bin_write_byte(f,global.result10);
-------------------ここまで-------------------
file_bin_close(f);

saveExe

global.item[8] = file_bin_read_byte(f);
global.music = file_bin_read_byte(f);

//自分で新しく変数を追加したいときはこの下に記述してください
-------------------追加部分-------------------
global.result1 = file_bin_read_byte(f);
global.result2 = file_bin_read_byte(f);
global.result3 = file_bin_read_byte(f);
global.result4 = file_bin_read_byte(f);
global.result5 = file_bin_read_byte(f);
global.result6 = file_bin_read_byte(f);
global.result7 = file_bin_read_byte(f);
global.result8 = file_bin_read_byte(f);
global.result9 = file_bin_read_byte(f);
global.result10 = file_bin_read_byte(f);
-------------------ここまで-------------------
file_bin_close(f);

を追加します。

次にScriptssaveResultを新規作成します。
saveResultの中身は

var f;
f = file_bin_open("save"+string(global.savenum),1);
file_bin_seek(f,37);
file_bin_write_byte(f,global.result1);
file_bin_write_byte(f,global.result2);
file_bin_write_byte(f,global.result3);
file_bin_write_byte(f,global.result4);
file_bin_write_byte(f,global.result5);
file_bin_write_byte(f,global.result6);
file_bin_write_byte(f,global.result7);
file_bin_write_byte(f,global.result8);
file_bin_write_byte(f,global.result9);
file_bin_write_byte(f,global.result10);
file_bin_close(f);

を入力します。

セーブの解説

これで準備は完了ですが、使用方法の前にセーブについて解説しておきます。
yuuutu edition ver2.13のセーブ方法は、バイナリファイルを利用しています。
バイナリファイルは、file_bin_openで開き
データの先頭から順に、読み込みまたは書き込みをする仕様になっています。
そしてfile_bin_write_bytefile_bin_read_byteで書き込み、または読み込むと
一つ先のデータへ移動するという性質を持っています。
※関数に関する詳しい内容はGamemakerまとめwikiなどをご参照ください。
saveExeを例にすると

var f,roomTo;

if(file_exists("save"+string(global.savenum)) == true){
f = file_bin_open("save"+string(global.savenum),0);ファイルを開いたここから
roomTo = file_bin_read_byte(f)*10000;0番目
roomTo += file_bin_read_byte(f)*100;1番目
roomTo += file_bin_read_byte(f);2番目



global.item[8] = file_bin_read_byte(f);35番目
global.music = file_bin_read_byte(f);36番目
//自分で新しく変数を追加したいときはこの下に記述してください
global.result1 = file_bin_read_byte(f);37番目



file_bin_seek(f,37);37という数字は、今回追加した部分の37番目を指しています。
※他にも追加している変数がある場合は数字が変わるので注意してください。
saveResultでは file_bin_seek(f,37);により37番目より前のバイナリを変更せずに37番目に移動することで
プレイヤーの位置や、デス数、タイム等を変更せずに、実績の変数だけを保存することが可能になります。

これで、セーブ機能に実績を保存する変数の追加と、実績だけをセーブする為のsaveResultが完成しました。
実績取得時にsaveResultを実行することで実績を保存することが出来るようになりました。
詳しい使用方法は次の項目で説明していきます。

実績の取得を表示する機能

今回は2つのパターンの表示を解説していきます。

デス数が一定値を超えた実績の取得

global.result1をデス数1000の実績とした場合
playerオブジェクトroom startイベント

if(global.death==1000){
if(global.result1==false){
global.result1=true;
instance_create(700,600,実績取得表示オブジェクト);
saveResult();
}
}

実績取得表示オブジェクトについては一定時間表示して削除するだけなので割愛させて頂きます。

アイテムA取得による実績の取得

global.result2をアイテムAの実績とした場合
アイテムAオブジェクトを新規作成し
collisionイベントplayerオブジェクト)に

if(global.result2==false){
global.result2=true;
instance_create(700,600,実績取得表示オブジェクト);
saveResult();
instance_destroy();
}

createイベント

if(global.result2==true){
instance_destroy();
}

実績取得表示オブジェクトについては一定時間表示して削除するだけなので割愛させて頂きます。

スイッチに弾が当たらないバグについて

スイッチに弾が当たらないバグとは?

スイッチを撃った際、高さは合っているはずなのに反応しない時があります。
これはplayerが発射した弾の移動速度がデフォルトで16
スイッチのサイズが16ドット以下の場合に
スイッチに当たらず飛び越えて起きる現象です。
弾は16ドットずつ移動しており
座標16→座標32に移動した場合、その間座標17~座標31のオブジェクトには当たりません。
また、スイッチとブロック同時に接触しても削除されてしまうので(下記にて説明あり)
今回はその対策をしたいと思います。

問題点

初期状態では
bulletオブジェクト
stepイベント

if(place_meeting(x+hspeed,y,block)){//現在の座標+hspeed(次の座標)にblockがあったら
a=instance_place(x+hspeed,y,block)//blockのIDを取得
if(a.object_index=block)instance_destroy()//blockだった場合削除(parentがblockの場合を除く)
else if(a.visible=1)instance_destroy()//parentがblockかつvisibleがtrueの場合削除
}

alarm[0]イベント

instance_destroy()//アラームが起動したら削除

となっており、
次の座標でスイッチとブロック同時に接触する場合も
上記のstepイベントで先に削除されてしまうので、
collisionイベントが起こりません。
※イベントの順番についてはGamemakerまとめwikiのワンポイントにてご確認ください。
なので、以下の方法で対策をとります。

対策

bulletオブジェクト
stepイベント

if(place_meeting(x+hspeed,y,block)){
a=instance_place(x+hspeed,y,block)
if(a.object_index=block){move_contact_solid(direction,speed);alarm[0]=1;speed=0;visible=0;}--変更部分--
else if(a.visible=1){move_contact_solid(direction,speed);alarm[0]=1;speed=0;visible=0;}--変更部分--
}

と変更します。
instance_destroy()を{move_contact_solid(direction,speed);alarm[0]=1;speed=0;visible=0;}に変更することで
ブロックに貼り付き、もしスイッチがあった場合はスイッチのcollisionイベントが発動し、
なかった場合は、alarm[0]=1;(1ステップ後)に削除されます。

PAGE TOP

    inserted by FC2 system