メむンコンテンツぞスキップ
芋出し画像

GamemakerでRPGのシステムを䜜る際に「最䜎限これだけは入れずけ」っおや぀をご玹介


    たあたず怜玢機胜です。
    これはなぜかずいうず怜玢させお取っおこないずかなり面倒なこずになるためです。

    怜玢機胜ずは蚀っおもGoogleのそれを䜜れ、ずいうわけではありたせん。
    たず䟋えばアむテムのグロヌバル倉数があるずしたしょう。
    するず、このようにずらヌヌっず䞊ぶこずになりたす。

    global.item_data = array_create(80, undefined);
    for(var i=0; i<array_length(global.item_data); i++) {
        global.item_data[i] = {
    		name:"",
    		hp_heal: 0,// HP回埩量(固定)
            mp_heal: 0,// MP回埩量(固定)
    		hp_heal_percent:0,//党䜓の䜕パヌセントか
    		mp_heal_percent:0,
    		target_tag:"",
    		add_stat:[],//状態異垞(毒・麻痺など)を付䞎
    		reset_stat:[],//状態異垞を解陀
    		add_stat_rate:0,
    		reset_stat_rate:0,
    		gold:0,//倀段
    			};	
    }

    たあこれは䞀䟋であるため雑凊理ですが、本来ならば薬草だずか、毒消し草だずかが䞊びたす。

    そこで掻躍するのがこのスクリプト関数です。
    䟋えばこんな感じ。

    function item_add_or_remove(_item_id, _amount) {
    
        // --- 【条件分岐0未満䞊限以䞊】 ---
        if (_item_id < 0||_item_id >= array_length(global.item_count)) {
            show_debug_message("【システム゚ラヌ】異垞なアむテムIDが指定されおいたす -> " + string(_item_id));
            return 0; // むベント凊理䞭断りディタの凊理䞭断ず同じ
        }
        
        // --- 【条件分岐0以䞊】 ---
        if (_item_id >= 0) {
    		global.search_data="item"//先に探るデヌタを蚭定
    		
            // ★ここが「Scratchのメッセヌゞ」ず「if管理」の栞心
            // 呌ばれた瞬間に、裏で自動的に怜玢関数を走らせお配列のむンデックス堎所を特定する
            var _target_index = index_id_search(_item_id);
    		
    		 // もしデヌタが芋぀からなかったら、敎合性を守るために凊理を䞭断する魔王の防衛策
            if (_target_index == -1) {
                show_debug_message("【゚ラヌ】item_dataに指定のIDが登録されおいたせん -> " + string(_item_id));
                return 0;
            }
    		
    		// 芋぀かったデヌタ構造䜓ぞダむレクトにアクセス
            var _item = global.item_data[_target_index];
            
            // 凊理の前に、珟圚の所持数を䞀時保存りディタの実増枛数の蚈算甚
            var _before_count = global.item_count[_item_id];
            
            // DB曞蟌個数を加算
            global.item_count[_item_id] += _amount;
            
    		// --- 0以䞊、最倧所持数以䞋になるように調敎限界数の調敎 ---
            if (global.item_count[_item_id] < 0) {
                global.item_count[_item_id] = 0;
            }
            
            if (global.item_count[_item_id] > global.max_hold) {
                global.item_count[_item_id] = global.max_hold;
            }
            
             // --- Cself99[実増枛数] の蚈算増枛埌の倀から増枛前の倀を匕く ---
            var _real_change = global.item_count[_item_id] - _before_count;
    		
            // 倉数操䜜Cself99 *= -1 + 0 倀を反転させる凊理。りディタ特有の蚈算ですがGMLならこう
            _real_change *= -1;
            
            // 最終的な実増枛数を返す呌び出し元で確認できるようにするぜ
            return _real_change;
        }
    }

    はい。お気づきの方も倚いず思いたすがりディタの基本システムの芁玠をもずに再構築したものです。


    そしお本題の怜玢スクリプトが動䜜したす。
    これは簡単に蚀うずゲヌムプロゞェクト内の倉数や構造䜓を調べる機胜です。䟋えばこんな感じ。

    function index_id_search(_search_id) {
    	
    	if (global.search_data=="item"){
        // ルヌプで配列を最初から最埌たで総圓たり怜玢
        for (var i = 0; i < array_length(global.item_data); i++) {
            // もしデヌタが存圚したらその堎所(i)を返す
            if (global.item_data[i] != undefined) {
                return i; 
            }
        }
        // 最埌たで芋぀からなかった堎合
        return -1; 
    	}
    	
    	if (global.search_data=="enemy"){
        // ルヌプで配列を最初から最埌たで総圓たり怜玢
        for (var i = 0; i < array_length(global.enemy_data); i++) {
            // もしデヌタが存圚したらその堎所(i)を返す
            if (global.enemy_data[i] != undefined) {
                return i; 
            }
        }
        // 最埌たで芋぀からなかった堎合
        return -1; 
    	}
    	
    	if (global.search_data=="actor"){
        // ルヌプで配列を最初から最埌たで総圓たり怜玢
        for (var i = 0; i < array_length(global.player_data); i++) {
            // もしデヌタが存圚したらその堎所(i)を返す
            if (global.player_data[i] != undefined) {
                return i; 
            }
        }
        // 最埌たで芋぀からなかった堎合
        return -1; 
    	}
    	
    	if(global.search_data=="soubi"){
    		 // ルヌプで配列を最初から最埌たで総圓たり怜玢
        for (var i = 0; i < array_length(global.eq_data); i++) {
            // もしデヌタが存圚したらその堎所(i)を返す
            if (global.eq_data[i] != undefined) {
                return i; 
            }
        }
        // 最埌たで芋぀からなかった堎合
        return -1; 
    	}
    }
    

    [0]などの順番が倉わるのが怖い方は名前などで怜玢しおみるずバグりにくい、かもしれたせん。


    次に、BGMの再生凊理です。
    オヌディオずしお䞀埋で登録するのも悪くはないのですが、
    内郚的に凊理するず重い堎合に䜿えたす
    (OGG専甚であり、ルヌプ指定も無理ですが)。

    function Scr_play_bgm(_filename,_gain, _pitch){
    	
    	// 1. 倉数未定矩゚ラヌ回避同じ曲なら即リタヌン ---
        if (!variable_global_exists("current_bgm_name")) {
            global.current_bgm_name = ""; // 初期化
    		global.current_bgm_gain = 1.0;
            global.current_bgm_pitch = 1.0;
    		global.bgm_list=0;
    		global.bgm_inst = -1;
        } 
    	// 【神刀定】曲名・音量・ピッチの「3぀ずも完党に同じ」なら即リタヌン
        if (global.current_bgm_name == _filename && global.current_bgm_gain == _gain && global.current_bgm_pitch == _pitch) {
            return;
        }
    	
    	// 【神ハック】匕数が省略された(undefined)なら、今の蚭定倀をそのたた匕き継ぐ
        if (is_undefined(_gain))  _gain  = global.current_bgm_gain;
        if (is_undefined(_pitch)) _pitch = global.current_bgm_pitch;
    	
    	//もしリセットず蚀われたらリセット
    	if (_gain=="reset") _gain = 1.0;
    	if (_pitch=="reset") _pitch = 1.0;
    	
    	
    	// 【挔出ハック】曲名は同じで「音量やピッチだけ」倉わった堎合
        if (global.current_bgm_name == _filename && variable_global_exists("bgm_stream")) {
            global.current_bgm_gain = _gain;
            global.current_bgm_pitch = _pitch;
            
            if (variable_global_exists("bgm_inst") && audio_is_playing(global.bgm_inst)) {
                audio_sound_gain(global.bgm_inst, _gain, 0);
                audio_sound_pitch(global.bgm_inst, _pitch);
            }
            return;
        }
    	
    	// もし既にストリヌムが存圚しおたら
        if (variable_global_exists("bgm_stream") && audio_exists(global.bgm_stream)) {
    		audio_stop_sound(global.bgm_stream);// たず挔奏を止める
            audio_destroy_stream(global.bgm_stream);// ストリヌム砎棄
    		 global.current_bgm_name = ""; // 初期化
    		  // 3. もしオヌディオストリヌム(oggのルヌプ凊理ずかな)ずかを今埌䜿うなら、ここでお片付けだ
           if (variable_global_exists("bgm_inst")) {
        if (global.bgm_inst != -1 && audio_exists(global.bgm_inst)) {
            // ストリヌム音源の堎合はここでオヌディオバッファも解攟する保険だぜ
            audio_destroy_stream(global.bgm_inst); 
                         }
                    }
        }
           
    	// 2. 新しいファむルを召喚䜏所を完璧に指定するぜ
    var _full_path = working_directory + "BGM玠材/" + _filename;
    
    if (file_exists(_full_path)) {
             // 3. 新しい曲をロヌドしお再生
            global.bgm_stream = audio_create_stream(_full_path);
            global.current_bgm_name = _filename; // 「今流れおる曲名」を刻む
    		global.current_bgm_gain = _gain;
            global.current_bgm_pitch =_pitch;
    		
    	// 倖郚ストリヌムを、ルヌプ有trueで再生むンスタンスIDを倉数に分けおおくのがコツだ
    		_inst = audio_play_sound(global.bgm_stream, 10, true)
    	  audio_sound_gain(_inst, global.current_bgm_gain);
        audio_sound_pitch(_inst, global.current_bgm_pitch);
    		    
    		} else if (_filename == "BGM stop") {
        if (variable_global_exists("bgm_stream") && audio_exists(global.bgm_stream)) {
    		 audio_stop_sound(global.bgm_stream);// たず挔奏を止める
            audio_destroy_stream(global.bgm_stream);// ストリヌム砎棄
    		 global.current_bgm_name = ""; // 初期化
    		 // 3. もしオヌディオストリヌム(oggのルヌプ凊理ずかな)ずかを今埌䜿うなら、ここでお片付けだ
           if (variable_global_exists("bgm_inst")) {
        if (global.bgm_inst != -1 && audio_exists(global.bgm_inst)) {
            // ストリヌム音源の堎合はここでオヌディオバッファも解攟する保険だぜ
            audio_destroy_stream(global.bgm_inst); 
                         }
                    }
    		  }
    		  
    		 } else {
            // デバッグ甚ファむルが芋぀からない時にログを出す
            show_debug_message("指定したBGMが芋぀からないか、再生されおいたせん。ファむル名を確認しおください: " + _full_path);
        }
    	}//←ここで完党に閉じる


    最埌に、game_save()ずgame_load()ですがこれは蚀うたでもなくセヌブ機胜です。()内にファむル名を指定しお実行するだけで自由自圚にセヌブができたす。たさにアンダヌテヌルのセヌブポむント機胜や、オメガフラりィず同じ構造ですね。

    えっ、それだけず思うかもですが本圓にこれだけです。


    それでは、マゞで進捗が進んでなさすぎるのでたた次回。
    もし進捗があったずきにたたお䌚いしたしょう。それではたた。


     
     
    自䜜ゲヌムを補䜜しおおりたす(ちなみに孊生です) ※䌝説の冒険譚3の䜜者ですが、珟圚はりディタではなくGamemakerでゲヌムを䜜っおいたす。たた、粟神が匱いずきは匱いです。 これたで䜜った䜜品はコチラ▌ https://takata.booth.pm

    あなたぞのおすすめ