GameMaker 日本語掲示板

【Tips】if文テクニックまとめ

6 コメント
views
18 フォロー

if文の様々なテクニックをまとめてみました。

条件は「変数は左、定数は右」

if(10 > speed) //こっちより

if(speed < 10) //こっちのが読みやすい

範囲内かどうかは数直線で並べる

if(speed > 10 && speed < 50) //こっちより

if(10 < speed && speed < 50) //こっちのが読みやすい

一行だけ呼ぶなら{ }を省略可能

//こう書いても良いが
if(keyboard_check_pressed(vk_escape)) 
{
    game_end();
}

//こう書いてもよい
if(keyboard_check_pressed(vk_escape)) game_end();

※二行以上の処理やブレークポイントを置きたい場合などは推奨しない

条件をそのまま利用するのであればif文はいらない

//こっちより
if(keyboard_check_pressed(vk_space)) isJump = true;
else                                 isJump = false;

//こっちのがシンプル
isJump = keyboard_check_pressed(vk_space);

また関数をつくって条件を返したい場合も同様

//こっちより
function IsJump() 
{
    if(keyboard_check_pressed(vk_space)) return true;
    else                                 return false;
}

//こっちのがシンプル
function IsJump() 
{
    return keyboard_check_pressed(vk_space);
}

trueやfalseと比較しない

trueの場合

if(isJump == true) //こっちより
if(isJump) //こっちのがシンプル

falseの場合は「!」を使う

if(isJump == false) //こっちより
if(!isJump) //こっちのがシンプル

※!マークは文字に見えることもあるので慣れが必要

条件の反転のif文は「!」を使えばシンプルに!

エンター押したら条件変数を反転!

//こっちより
if(keyboard_check_pressed(vk_enter)) 
{
    if(isToggle) isToggle = false;
    else         isToggle = true;
} 

//こっちのがシンプル
if(keyboard_press(vk_enter)) 
{
    isToggle = !isToggle;
} 

数学関数の利用

上限値で制限

if(speed > 10) speed = 10;//speedが10より大きかったら10にする

speed = min(speed,10);//上と同じ

範囲で制限

//10と50の間で制限する
if     (speed < 10) speed = 10;
else if(speed > 50) speed = 50;

//clamp関数を使えば一発
speed = clamp(speed,10,50);

条件を計算に使う

true,falseを数値に変換した際はtrue=1,false=0になる
その性質を利用することでif文をなくすことができる
上下移動の計算(よくあるやつ)

//これを
var speed = 5;
if(keyboard_check(vk_right)) x += speed;
if(keyboard_check(vk_left))  x -= speed;
if(keyboard_check(vk_down))  y += speed;
if(keyboard_check(vk_up))    y -= speed;

//こうかける
x += (keyboard_check(vk_right) - keyboard_check(vk_left)) * speed;
y += (keyboard_check(vk_down)  - keyboard_check(vk_up))   * speed;

※シェーダーでは条件分岐一つで一気に重くなってしまうのでこのテクニックがよく使われる

三項演算子

シンプルなif文なら三項演算子を使うと簡潔

//これより
if(isDash) speed = 50;
else       speed = 10;

//こっちのが見やすい
speed = isDash ? 50 : 10;

※処理が複雑になると見にくくなるので注意
※また三項演算子を嫌う人も結構いる

局所化

//ヒット時はプレイヤーの画像を変更する
if(isHit)  draw_sprite(sprHitPlayer,0,x,y);
else       draw_sprite(sprPlayer,0,x,y);

//ローカル変数を用意して該当箇所を抜き出す
var spr = isHit ? sprHitPlayer : sprPlayer;
draw_sprite(spr,0,x,y);

短絡評価

if文の条件は先頭から順番にチェックされるので重そうな処理は後ろに入れると良い

//こっちより
if(place_meeting(x,y,oWall) || isDead)

//こっちのが早い
//isDeadがtrueならばplace_meetingの処理は呼ばれない
if(isDead || place_meeting(x,y,oWall)) 

早期リターン、早期コンティニュー

条件を反転させてreturnをうまく使えば複雑な入れ子をなくし、条件を箇条書きのように確認可能

//こっちより
function PlayerIsAlive(player) 
{
    if(player.hp > 0) //hpが0より大きいなら
    {
        if(global.lifeTime > 0) //生存可能時間が0より大きいなら
        {
            return true;
        }
    }
  
    return false;
}

//こっちのが条件を箇条書きのようにチェックできる
function PlayerIsAlive(player) 
{
    if(player.hp <= 0)       return false; //hpが0以下なら
    if(global.lifeTime <= 0) return false; //生存可能時間が0以上なら  
    return true;
}

loop文やwith構文ではcontinueが使える

//これより
with(oEnemy) 
{
    if(isAlive) //生存しているか
    {
        if(!isBoss) //ボスではない
        {
            if(!isMuteki) //無敵ではない
            {
                if(irandom(100) <= 10)  //10%の確率
                {
                    hp = 0;
                    isAlive = false;
                }
            }
        }
    }
}

//こっちのがよい
with(oEnemy) {
    if(!isAlive)          continue;//生存していなければループをスキップ
    if(isBoss)            continue;//ボスならループをスキップ
    if(isMuteki)          continue;//無敵ならループをスキップ
    if(irandom(100) > 10) continue;//90%の確率でスキップ

    hp = 0;
    isAlive = false;
}

番号によるif文は配列テーブルを用意する

//こっちより
if(num == 0) id = 10;
if(num == 1) id = 15;
if(num == 2) id = 30;
if(num == 3) id = 50;

//こっちのがよい(追加も楽)
table = [10,15,30,50];//Createで用意してもよし、関数内であればstaticで用意してもよし
id = table[num];
生高橋
作成: 2022/09/26 (月) 07:42:43
最終更新: 2022/09/27 (火) 12:53:55
通報 ...
1

盛りだくさんのTips、ありがたい!!!

2
生高橋 2022/09/27 (火) 12:52:55 >> 1

3
サトヤガンジ 2022/09/28 (水) 09:37:01

めっちゃ勉強になります!('ω')
ありがとうございまーす!

4

これはありがたいです!

5
ralsoon 2022/10/24 (月) 17:27:43

これも追加で

Null合体演算子(??)を使ってシンプルに

var val = gameData[?"time"];
if (is_undefined(val)) time = 100;
else                   time = val;

// 三項演算子でもいいが……
var val = gameData[?"time"];
time = is_undefined(val) ? 100 : val;

// こうするとシンプル
// gameData[?"time"]がundefinedなら100が代入される
time = gameData[?"time"] ?? 100;

ただしnooneは-4の定数なのでNull合体演算子(??)は使えない

var val1 = noone;
var val2 = val1 ?? 100; // val2には-4が代入される
6
生高橋 2022/10/28 (金) 10:44:55 >> 5

あざます!