GameMaker 日本語掲示板

views
17 フォロー
1,131 件中 441 から 480 までを表示しています。
1

私の場合、exeと同じ場所に外部ファイルがある形にしてます。
(exeファイルと同じ場所に置きたくないという要望を満たす回答にはならずすみません)

雑にしか理解してないんですが、GMS1.4の頃は外部ファイルも全部exeファイルの中に入る形にビルドされていたので、配布するゲームは外部ファイルが見えない(というか存在しない)形になっていたんですが、GMS2になってそれができなくなり、今の形になりました。
インストーラーで外部ファイルを展開する場所をC:\Users\username\AppData\以下などに指定できたらいいのですが、その方法は、私の知る限りは無いようです。

■すぐに見つからない場所に置く(隠す)
上記のように、方法は無いっぽいです。

■拡張子を変える
少しは効果があるかもしれませんが、データを見てやろうという意思がある人は開いちゃうと思います。

■難読化する
ファイルを開いても内容を読めなくすることは選択肢の1つだと思います。これも完全じゃないですが多くの人は読むことを諦めるでしょう。



ということで現在は「ソロプレイのゲームなら」という条件つきですが、「読みたい人は読めばいい、プレイする本人が自分の意志で見たくて見るならそれを止める理由は無いかもしれないな」と開き直って、それ以上考えないようにしてます!🙈

他の人がどうやってるのか、私も知りたいです!

9

ステート毎に終了条件(遷移条件)が違い遷移先も条件で複数変わるので、仕方なくステート内にそれらを書いていましたが、ステートをインスタンス化するときにこういう方法でfunctionを渡すことができるんですね。

あと、進行方向とアニメの向きが必ずしも一致しないというのはその通りですね。後退しながら攻撃したり、体を対象の方に向けながら歩き回ったり。
ステートを、アニメの開始から終わりまでという単位で考えていたのでステートとアニメを一体化して捉えていましたが分けたらスッキリするなら分けたいですね。

考え方とサンプルコードで勉強になります。参考にさせて頂きます。
ありがとうございます!

8
hayate212 2022/07/15 (金) 10:10:18

何に関心(AI,メニュー遷移,etc...)を持って実装をするかで大きく構造が変わるなと思い
オブジェクトの Sprite を管理するステートマシンを実装してみました

asa さんが最初に提示した実装例から以下のようなことを考えました

  • ステート内に遷移条件が実装されている
    • 開発が進むにつれステート内部が複雑になっていきそう
  • ステート内に挙動とアニメーション管理が実装されている
    • 前方への攻撃アニメーションを再生しつつ後退する場合、後退が行われた瞬間に攻撃アニメーションはキャンセルされる?
      • 場合によっては前方への攻撃アニメーションを残しつつ後退することも考えられるので、挙動=アニメーションではないはず
  • 新たにジャンプステートを実装する場合、ジャンプしながらの横移動処理はジャンプステートにも実装される?
    • 実装の重複は修正漏れ考えると避けたい・・・

そこでアニメーションの管理のみを行うステートマシンを実装しました。
以下が仕様です。

  • アニメーションステート(以下ステート)は Sprite を必ずひとつ持つ
  • 遷移条件構造体は遷移条件関数と遷移先のステート名を持つ
    • 遷移条件関数は遷移条件を満たしたかどうかの Bool 値を必ず返す
  • ステートをステートマシンに登録する際には以下の情報が必要
    • ステート名
    • ステート
    • 遷移条件構造体の配列
  • 毎ステップ、条件付きループ(for)で遷移条件構造体の配列の中から順番に遷移条件関数を実行し true が返った場合、遷移条件構造体の遷移先ステート名を元にステートを現在のものから置き換え、ループを抜ける
  • 毎ステップの最後に現在のステートから Sprite をオブジェクトに割り当てる

これにより挙動とアニメーション管理を分離出来ます。

*上記仕様をもとに実装しステートマシンを使用している部分
画像1

7

友人さん ありがとうございます。

characterに各motionインスタンスを全部持たせて、init()とloop()もそっちに移動、
motionはloopから呼ばれるactionのロジックだけにするという構造なんですね。

いろいろ勉強させていただきます。
サンプルコードから詳しい説明まで、ありがとうございます!!

6

別口でご回答させていただきましたが、為念こちらにも。

gameMakerは学んだことがなく知識や仕様理解は暗いですが、気になった点としてインスタンスの生成を上げさせていただきました。
もう1点、idleとwalk内で同様の処理が記述されていることも、冗長になりがちな点と、コピペミス等で不具合が発生する原因になりそうであったため、少し気になりました。

上記2点をとりあえず解決するという目的で、自分ならこうするかな? という観点でコードを記載させていただきます。

先に述べました通り、gameMakerには疎いため、文法等に不備等がありましたらご容赦ください。(withってなんやレベルでした)
あくまで考え方のひとつとして見ていただければと思います。

function character(_obj) constructor {
	obj = _obj;
	cnt;

	current_motion;
	idle = new motion(obj, spr_player_idle, 60, 0.01);
	walk = new motion(obj, spr_player_walk, 60, 0.2, 2);
	
	init = function() {
		cnt = 0;
		idle.next_motion = walk;
		walk.next_motion = idle;
		current_motion = idle;
	}
	
	loop = function() {
		if (cnt >= current_motion.limit) {
			current_motion = current_motion.next_motion();
			cnt = 0;
			obj.sprite_index = current_motion.sprite;
			obj.image_speed = current_motion.image_speed;
		}
		current_motion.action();
		cnt++;
	}
}
function idle(_obj, _sprite, _image_speed, _limit) constructor
{
	obj = _obj;
	sprite = _sprite;
	image_speed = _image_speed;
	limit = _limit;

	next_motion;
	
	action = function() {
	}
}
function walk(_obj, _sprite, _imgspd, _limit, _speed) constructor
{
	obj = _obj;
	sprite = _sprite;
	image_speed = _image_speed;
	limit = _limit;
	speed = _speed;
	next_motion;

	action = function() {
		with (obj) x += speed;
	}
}

以下、メモ書きです。

それっぽくかんがえたこと

  • idleとwalkのインスタンスを別の構造体の中に持たせてみた
      newしないで切り替えできるように
      (ここだけ見ると構成的にo_playerに持たせてもよさそうな?)
      ついでにidleとwalkで共通していた処理も1か所書けばいいようになった気がする
  • 現在のモーション(idleかwalk)を、current_motionに保持
      何かしら実行するときはこれだけ見てればいい
      gameMakerで出来るかどうかは知見のなさ故に不明瞭ですが、たぶんできるやろの精神
  • idleとwalkに、次の遷移先を持たせる
      本当はアドレス指定よりKey値で指定できる形が望ましいと思いますが、とりあえずの形で
      切り替えるときはloopで60cntした時だったところを、limit変数にしてみた
      limitもidleとかに持たせたのでidleは60f, walkは40fとか個別指定もできるかも?
  • idleとwaikからマジックナンバーを消してみた
      全く別のobjからもidleやwalkが使える
      移動量とかも全部インスタンス生成時に設定できるからmotionで指定するとかできそうな気がする
      汎用性は低そうなのでそこまでする必要があるかどうかは不明
  • ソースよりコメントに時間がかかってしまった
      長文になってしまい申し訳ございませぬ・・・
5

遷移する度にインスタンスの破棄とインスタンス化をするのが負荷になる可能性があるという指摘も頂きました。
いろいろ考えるべきことがありますね~

4

stateをオブジェクトにすることでかえって複雑になる可能性があるということですかね。

3
生高橋 2022/07/08 (金) 17:59:24 修正

自分もこんな感じでポーズメニューをつくりました。
自分の知識が浅いからなのか思ったよりも複雑なった印象を受けました。

GameMakerは他の言語と違ってポリモーフィズムをする際の制約がないんですよね。
インターフェースがないのでstateごとに同名の関数の存在が保証されないです。
新しいstateを追加したときに関数の作り忘れが起きてしまったら一気にバグります。
まぁコピペすればいいだけなんですが。

ただし、新しい関数を追加したり名前や引数を変更してしまったら他のstateも全部変更が必要です。
stateが少なければこれもまぁ問題ないかもしれません。
他の言語ではVisualStudioを使っていると名前の一括変換などの機能があるので楽なんですよね。

そして、特定のステートのみの共通な処理や他のstateのデータを利用するとなったとき若干やっかいです。
無理に共通化したりすると他のstateにも影響をうけます。
ここらへんから自分は複雑になってきた印象があります。

ただ自分はまだ設計が浅いのでもしかしたらもっとちゃんと設計すればそれらもスッキリ解決できるんじゃないかと勉強中です。

2

遷移に係わる部分は各stateの、

stateを終了する条件の部分

if (cnt++ == 60) end_state();

と、遷移先のstateを決めて遷移する部分

end_state = function()
{
  with(obj) scr_state_change(new idle(id));
}



これを切り分けてstateの外に実装するのがよいということでしょうか。

1
hayate212 2022/07/08 (金) 17:27:08

idle や walk といったステートは状態の実装のみを責務として、ステートの遷移は実装を切り分けるのはどうでしょうか?
ステート遷移が複雑になるほどステートの内部も複雑化してしまう気がしまして・・・

また、切り分けることでステートを自由に組み合わせることが出来るようになるため使いまわしも用意になるかなと
例えばマグロ🐟は walk <-> attack の遷移しか出来ないことをステートを使いまわした上で表現出来るようになります

5
生高橋 2022/07/08 (金) 17:20:35 >> 4

idを算術演算として利用する人なんているんすね...
本当に近年のプログラムスタイルに近づいて行ってる間隔があります

4
asa 2022/07/07 (木) 08:24:54 修正

不確定な情報ですが。

今まではインスタンスidもブール値も数値で、数値としての計算にも使えていましたが、

  • 未定義、空、の意味で-1やnoone(-4)を使う
  • nooneをfalseと等価に使う
  • boolを0, 1で表現する
    などは、今後は型の区別がされて通用しなくなるかも知れません。

バージョン2022.6.023に関して、公式フォーラムに、
「instance.idは独自の型であるため、算術演算が使えなくなりました」というスタッフからの投稿がありました。
https://forum.yoyogames.com/index.php?threads/2022-6-release-thread.96639/page-2#post-582867

3

IDE 2022.6.0.23

Featherを使ってるとコードエディタがくそ重くなります。
ひどい時は入力してから目に見えるラグの後でようやく画面に入力されます(カーソル移動ももたつきます)。
Featherを切ったら軽くなりましたので、同様の症状が出る人はFeatherオフにしてみてください。

3

確かにオブジェクトだと冗長な場合は struct で問題ないですね👍

2
asa 2022/07/05 (火) 08:32:59 修正

具体的なサンプルコードまである説明をいただきありがとうございます!
なるほどGameMakerでの委譲ってこういうことなんですね。
内包する、所持する、というのは具体的にどういうことなのかバシッと見えてきました。

GameMakerのオブジェクトはいろいろ装備されてますので、諸々の機能が必要なく、最小のものにしたければ下記のようにstructを使うのもありなのでしょうか…


script weaponsBattery(struct)のコンストラクタを書いておく

function Battery(_bullet_remain) constructor
{
  bullet_remain = _bullet_remain;
  
  bullet = function(_x, _y, _deg, _speed)
  {
    bullet_remain = max(0, bullet_remain-1);
    if (bullet_remain == 0) return;

    instance_create_layer(_x, _y, "Instances", objBullet);
  }
}



objShip(船オブジェクト): create eventで砲台を作成して保持し、その機能を使う

battery = new Bullet(10);
battery.bullet(self.x, self.y, deg, speed);



いろいろ試してみようと思います。
ご説明ありがとうございました!

1

移譲は has-a (所持している)関係なので、機能を持たせたいオブジェクトの変数に、オブジェクトのインスタンスを持たせることで実現できます

  • objBattery: 移譲元 (このオブジェクトを拡張したい)
  • objShip: 移譲先 (拡張したオブジェクト)

■objShip の Createイベントで以下のように記述する

// 砲台オブジェクトを所持する
_battery = instance_create_layer(0, 0, "Instances", objBattery);

// 弾を撃つ関数
bullet = function(deg, speed) {
  // objBatteryの機能で弾を撃つ
  return _battery.bullet(self.x, self.y, deg, speed)
};

※サンプルコードはビルドしていないので参考までに…

敵キャラを拡張するために基底となる敵キャラを内包しても良いですし、サンプルコードのように部品(機能)を所持する、という使い方でも良いです

9

IDE 2022.6.0.23
Feather使用

入力補完のリストに存在する変数が出てこなかったりしますね。

2

マルチプレイヤーゲーム作りたい人はいるでしょうね!いるでしょうね!
期待しています。

How to Create a Multiplayer Game | GameMaker
https://www.youtube.com/watch?v=VPgAosG7QSU

8

コードを編集していると

[Feather] Unable find function 'o_bomb_normal_Event_Create$$anon_function_27_24', which should exist!

というようなメッセージがOutputにズラッと出力されます。
***という関数があるはずなのに見つからない!という意味らしいですが、この関数はあるんです。
あるのになぜ見つからないというメッセージが出るのか、原因不明です。

7
生高橋 2022/07/01 (金) 18:53:19

フェザーいいですねぇ。コードエディタ上でアセット名変更はまじでいい機能!!

6

マニュアルを翻訳

アセットリファクタリング
アセットブラウザでアセットの名前を変更すると、Featherはプロジェクトのコード内のアセットに関するすべての言及を自動的に更新するため、これらの参照が壊れることはありません。これは、フェザー設定で有効または無効にできます。

コードエディタを使用してアセットの名前を変更することもできます。テキストカーソルをアセット参照に置き、CTRL / CMD + SHIFT+Rを押します。

5

こういう場合は「エラーとする」、「警告とする」、「提案にする」、「無視する」
というのを、設定できるようになってます。
「とりあえず今はうるさいから、その問題はいちいち指摘しないでくれ!」という時は無視するの「ignore」にすればOKです。

4

下記のようなコードを書くと警告してきます。
今までと違って型を強く意識させられます。

img = spr_player_walk;
if (img == noone) ...
my_number = 100;
my_number = "empty";

こういうことをすると
「おい、違う型使ってるぞ?いいのか?」と言ってきます。

画像1

boolenも文字列も数字もいい加減に使えていましたが、ちゃんと型チェックしてきます。
でもコンパイルは通ります(今のところ)。

3
asa 2022/07/01 (金) 12:57:02 修正

enumにマウスオーバーすると内容一覧が出てきます。
画像1

spriteの場合こんな感じです。
画像1

Featherは与えてくれる情報がとても多いです。
これちゃんと使えるようになったらプログラミングする上でかなり便利だと思います。

2
生高橋 2022/07/01 (金) 12:51:33

バグですかねぇ...

ちょっと今自分はバージョン上げられない状態なんですが、なんか便利な機能があったらぜひ共有お願いします。

1
生高橋 2022/07/01 (金) 12:50:22

ベータ版なんですが、マルチプレイヤーが簡単につくれるようになるみたいです。(本当か!?)
https://gamemaker.io/en/blog/gamemaker-multiplayer

1

このバツ印は何でしょう?
画像が読めてない表示っぽいですが。IDE再起動しても変わりません。
画像1

Feather Messageの左側のこれも同じでしょうか。
(エラーと警告が凄まじいのはスルーして……)
画像1

3
生高橋 2022/06/30 (木) 12:03:29 修正

それはわからないですね。
ただ、有名なGameMaker製のゲームにはだいたい絡んでますね。
最近出たDownellのもっぴんさん新作ポインピーにも技術協力とかで参加してましたし。

1
生高橋 2022/06/27 (月) 23:59:43

GameMakerはjujuとYellowAfterlifeのVadymさんの貢献度がえぐいっす

2
ハンドルのネーム 2022/06/23 (木) 23:04:19

Localの中からプロジェクト名のフォルダを見つけ、その中にありました。
「GameMakerStudio2」という関係ないフォルダを開いていたために起きた問題でした。
ありがとうございます。助かりました!

1
生高橋 2022/06/23 (木) 14:21:45

保存場所はデフォルトだとC:>ユーザー>ユーザー名>Appdata>Local>プロジェクト名になってると思います。
おそらくそこに保存されているんじゃないでしょうか?

11
yOichi 2022/06/21 (火) 01:59:46

備忘録も兼ねて…。
自分の起動しない問題はこちらの内容を参考にして、解決しました。

https://forum.yoyogames.com/index.php?threads/missing-or-corrupt-gamemaker-build-tools-0x4f030002.96206/

3

解決できてよかったです
どんな基本的なことでも遠慮なく何でもどうぞ!

2

非常に丁寧に教えていただきありがとうございます。
ゲームオプションの項目にまず気付いておらず、やはり基本的な事を聞いてしまったようです。
重ねてありがとうございました。

1

ウィンドウサイズをドラッグで変えるのはデフォルトでは出来ないようになってますがGame option設定で変えられます。


これをクリックして、Game Optionsを開きます。
画像1


windows > graphics > の、Allow window resize をチェックして[OK]をクリック。
そしてビルドすると出来るようになってるはずです。
画像1

22
asa 2022/06/10 (金) 10:50:47 修正

指定した座標とspriteで、原点とBBOXを描画する関数

/// @func scr_dev_draw_bbox();
/// @param x {number}
/// @param y {number}
/// @param sprite {sprite_index}
function scr_dev_draw_bbox(_x=x, _y=y, sprite=sprite_index)
{
	draw_rectangle(_x, _y, _x, _y, false);
	
	var _spr_ltx = _x - sprite_get_xoffset(sprite);
	var _spr_lty = _y - sprite_get_yoffset(sprite);
	var _bb_ltx = _spr_ltx + sprite_get_bbox_left(sprite);
	var _bb_lty = _spr_lty + sprite_get_bbox_top(sprite);
	var _bb_rbx = _spr_ltx + sprite_get_bbox_right(sprite);
	var _bb_rby = _spr_lty + sprite_get_bbox_bottom(sprite);
	draw_rectangle(_bb_ltx, _bb_lty, _bb_rbx, _bb_rby, true);
}
2

おおおお!
教えていただいた方法でやってみたら、うまくいったみたいです!
「ローカルパッケージ」というものの存在を全く知りませんでした!
これからは作業が楽になりそうです。
ありがとうございました!

1

単純にルームだけをコピーしたいということでしたら、

ツールメニュー>ローカルパッケージを作成、プロジェクトの中からほかのプロジェクトに移動したいアセットを選択。
今回の場合、移動したいルームを、右側のリソースリストから選択し追加ボタンをクリック。
左側の表示名とパッケージIDを適当に決めてから、右下のOKをクリック。
ファイルの保存先を決めるダイアログが出るので好きな場所の保存する。
拡張子yympsのファイルが出来上がる。

次に、インポートしたいプロジェクトを開き、ツールメニュー>ローカルパッケージをインポートで、先ほど作ったファイルを選択して開く。

これで、ルームの情報だけインポートすることができました。

私は、自分がテストしているプロジェクトを2つフォルダごとコピーして、1つをコピー先、もう一つはルームをコピーして別名のルームにして、上記のローカルパッケージをルームだけ入れたもので作成しました。
コピー先となるプロジェクトを開きローカルパッケージをインポートしてみて、実際には同じルームをコピーしたものなので、オブジェクト等は同じものが配置されていますが、asaさんのやり方のように、同じオブジェクトやスプライトが追加(コピー)されてしまう状態にはなりませんでした。

上記の方法を実験してみてください。

IDEバージョン:2022.5.0.8

10
yOichi 2022/06/04 (土) 14:00:28

「変数名を変えても、デバッグウィンドウでは変更前の変数で実行されている」という謎挙動、今作っていた部分が落ち着いたのでバージョンを上げました。
今度は起動自体はできましたが、画像が表示されず真っ黒のママになってしまったので、またバージョンを戻そうかと考えています。インストールも不安定な印象があった(2度ほどエラーが出た)ので、こりゃ次まで待ちですね……。