1. ホーム
  2. random

[解決済み] ゲームメーカーのirandom()に制限?

2022-02-16 01:41:50

質問

私は3つのオブジェクトを持っています。これらすべてのオブジェクトは、createイベントにおいて、それぞれアクション(コードの一部を実行する)を含んでいます。

obj_r01 => r01=0;

obj_r02 => r02=0;

obj_r03 => r03=0;

画像(説明しようとしたことを明確にするため) :

ここまではいいのですが、もう一つ、これら他の3つの変数を変更するオブジェクトがあります。 obj_control

その obj_control は2つのイベントを含んでいます。 作成 ドロー .

クレタイベント (obj_control)を使用します。

obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);

ドローイベント (obj_control)を使用します。

このイベントは3つのアクションを含んでおり、正確には3つの "コードの一部を実行する"です。

ピースワン :

draw_text(x,y,obj_r01.r01); => obj_r01に適用されます。

ピースツー :

draw_text(x,y,obj_r02.r02); => obj_r02に適用されます。

ピーススリー :

draw_text(x,y,obj_r03.r03); => は、obj_r03に適用されます。

部屋の中に以下のようにオブジェクトが配置されています。

実行すると、このようになります。

r01の値はランダムであるが、r02とr03の値はランダムでない。 また、obj_control作成イベントコードを :

randomize();
obj_r01.r01=irandom(9);
randomize();
obj_r02.r02=irandom(9);
randomize();
obj_r03.r03=irandom(9);

しかし、結果は変わりません。これでは irandom () 関数は、保存可能なランダム値しか作成できませんが、このような問題を解決できるでしょうか?


コードの先頭にだけrandomize()を入れてみたのですが、どうでしょうか?

randomize();
obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);

しかし、結果的には何の変化もなかった。

また、念のため、値がランダム化されてもいないのか、r02とr03の値が0にランダム化されているのかもテストし、そのために、それぞれのオブジェクトの作成時にその値を修正しました。

obj_r02で。

r02=10

obj_r03で。

r03=100

その結果

最初の値は(驚くには値しないが)ランダム化されたが、2番目と3番目の値はそうではなかった。 したがって、ランダム化が行われていないか、r02 と r03 のラジオマイゼーションの前に抽選イベントが発生していることは明らかである .

解決方法は?

以下は、この同じ質問で私が受け取った回答です。 https://gamedev.stackexchange.com/

質問のリンク => https://gamedev.stackexchange.com/questions/139368/limitation-on-irandom-of-game-maker


GameMakerで使用されている乱数発生器は、本当の乱数発生器ではありません。それは 擬似 乱数発生器(略称:PRNG)。PRNGは以下のような数値の列を返します。 見る ランダムに、しかし実際には決定論的な列である。PRNGが生成する数列はその初期状態、いわゆる シード値 . PRNGを同じ種で初期化すると、同じ数列が生成されます。

つまり、ゲームの実行ごとにユニークな体験をさせたい場合は、実行ごとに異なるPRNGのシード値を使用する必要があります。開発者としては、その値がどこから来たものであるかは気にしませんが、すでに使用したものと同じでないことだけは気にします。Game Makerの randomize 関数には、前回ゲームを実行したときと同じである可能性が低い新しいシードで、乱数ジェネレータを再シードする目的があります。この関数がそのために正確に何を行っているかは分かりませんが、おそらく現在の時刻やユーザーの入力など、さまざまなエントロピー源からシード値を算出しているのでしょう。この関数を呼び出すと randomize を何度も繰り返すと、それらのエントロピー源は変化しないかもしれないので、同じシードで再度初期化する。つまり、PRNGは同じシーケンスを返すことになります。

つまり、一般的には randomize() ゲーム開始時に一度だけ。それから irandom(n) 乱数が必要なときに、毎回異なる乱数(または同じ数...1/2の確率で)を返すはずです。 n ). つまり、ゲームの初期化関数は次のようになります。

randomize();
obj_r01.r01=irandom(9);
obj_r02.r02=irandom(9);
obj_r03.r03=irandom(9);

フィリップさん(@Philipp)の回答( https://gamedev.stackexchange.com/users/21890/philipp )


DMGregoryコメントの補足です "( philippの回答に対するユーザーのコメント )"の本当の使い方です。 randomize() .

シードを設定することになっており、すでに述べたように複数回行う必要はないのですが、さらに、いわく ここで

GameMakerで乱数関数を使用する場合は、ご注意ください。これはエラーのトレースやデバッグが非常に簡単になるからです。本当の乱数でテストしたい場合は、ゲームの開始時にこの関数を呼び出す必要があります。

つまり、呼び出さないことで、実行にわたって同じ結果を振りまくことができるのです。ベストなケースは、ゲーム開始時に一度呼び出すだけで、二度と呼び出さないことで真のランダムを実現することです。

回答は@DHさんよりいただきました。( https://gamedev.stackexchange.com/users/51087/dh )