GMLにも拡張機能的なものがあるんですね.....!!ありがとうございます!!購入検討してみます!
一番有名なのはGMLiveというツールを使うことですかね。 実行中にコードを直接書き換えたり、roomのオブジェクトを移動させたりしたらそれが反映されるツールです。 ただし、有料であり資料もほとんど英語ですので使うときは公式ドキュメントとにらめっこが必要です。
一応数少ない日本語資料もあります。(古いバージョンですが) https://qiita.com/2dgames_jp/items/7e908ce8e4bf8a2f19f7
自前でやる場合はセーブファイルをつくって実行中にセーブとロードをして値を変更する方法もあります。 以前にそのような記事を書いたので参考にしてみてください。 https://zawazawa.jp/gamemaker_jp/topic/119
今のところ最新版は不具合が多く、新機能も使いににくい状態ですぐにアップデートするメリットは少ないです。 ですので安定したバージョンを使うことをおすすめします。
新しいバージョンが出たらすぐにアップデートする癖があるんですが、不具合のことも考慮するとすぐにアップデートしないほうがいいとかってありますか?
どうやらCompatibilityModeではなくcollision関数関連の挙動がおかしくなっているみたいです
GeneralGameOption->CollisionCompatibilityModeのチェックが外されました おそらくデフォルト値に更新されたのだと思います これによって当たり判定がおかしくなる不具合がおきました。
ただし、現在再定義する際どの項目を選択してるのかがわからない問題があります(バグ報告済み
ショートカットキーを自分で再定義できるみたいです
windows11 microsoftIME US配列キーボード環境下では日本語でテキスト入力ができませーん!
原因をいくつか考えてみました。
これはあさまどさんのコードのやつでチェックするとseqが存在しないとなってしまいます。 どこかのタイミングで以下のようなコードを使ってシーケンスのインスタンスをseqに入れてやる必要があります。
seq = layer_sequence_create("Assets1",0,0,Sequence1);//引数は適当です
どこかのコードでseq変数の中身を書き換えてしまっている場合は動きません。
移動より先に以下の削除のコードに到達している場合はインスタンスがないので動きません。
layer_sequence_destroy(seq);
カメラのx,yの値に変化がない場合は動作していないように見えるかもしれません。
シーケンスを使ったことがないので回答はできないのですが、このコードがどこに書かれているか知りたいところです。
あと、これを実行するとOutputにはなんと出力されますか?
if sequence_exists(seq) { show_debug_message($"camera.loc={oCamera.x}. {oCamera.y}"); layer_sequence_x(seq, oCamera.x); layer_sequence_x(seq, oCamera.y); } else { show_debug_message($"seqが存在しない"); }
ご回答ありがとうございます! すいません、記載ミスです。 layer_sequence_x(seq, oCamera.y); ↓ layer_sequence_y(seq, oCamera.y);
どちらもlayer_sequence_xになってるのが原因でしょうか?
その部分のコードと該当するオブジェクト名をここに貼ることはできるでしょうか あと、実行時エラーの内容をここにはることはできるでしょうか
place_meetingってスプライトがないと使えないんですね.......初めて知りました!!ありがとうございます!!!!
place_meetingはコリジョンマスクで当たり判定を行う関数なので、スプライトを持たない(コリジョンマスクを持たない)場合は使えません。 線で当たり判定をするにはcollision_lineかcollision_line_listを使ってください 矩形ならcollision_rectangle, collision_rectangle_list 円ならcollision_circle, collision_circle_list 楕円ならcollision_ellipse, collision_ellipse_list 点ならcollision_point, collision_point_list で当たり判定ができます
*_listは複数の対象との当たり判定をして、当たっている対象をlistで返すものです _listがついてないものは、最初に当たりを検出した対象を1つ返します(対象が1つだけと分かってるならこれで足ります)
生高橋さん、asaさんありがとうございます!その発想はなかったです!
一足先に生高橋さんが詳しく説明してくれてました!
同じStepイベント内でキー入力を2回拾っているのでそういう挙動になっています。 やりかたと書き方はいろいろありますが、例えば下記のような方法はどうでしょうか。
if(keyboard_check_pressed(vk_enter)) { if(a == 0) { a = 1; } else if (a == 1) { a = 2; } }
キーを押す条件を一つにして、その中に加算条件を入れてみました。 また、ifとelse ifでaの条件をまとめてみました。
//ステップ if(keyboard_check_pressed(vk_enter) { if(a == 0) { a = 1; } else if(a == 1) { a = 2; } }
ifとelse ifでまとめた条件は上からの順で条件を判定していき、合致したもののみを実行します。 if(a == 0)の条件が合致すればelse ifの条件は無視されます。 これで1フレーム内で特定の条件のみを実行することができます。 ifのみで構成すると、すべての条件をチェックしますので注意が必要です。 ifとelse ifなどの基本構文はどのプログラムでも使いますので覚えておくとよいと思います。
また、単純に数を加算するのであればエンターキーを押したら+1加算するというものにしてもいいかもしれません。
if(keyboard_check_pressed(vk_enter) { a++; }
す、すごい...。&&については初めて使いました...。 解決しました。ありがとうございます。
分かりやすい解説ありがとうございます!!!!!!!初めて重力系(?)のプログラムをやるので助かりました!!!!
ジャンプアクションの移動と当たり判定のテンプレートを一旦置いておきます。 細かく解説すると長くなってしまうので一部のみ抜粋して解説します。
//横方向の速度の計算 hsp = oInput.inputHsp * moveSpd; //着地判定 var isGround = place_meeting(x,y + 1,oBaseWall); if(!isGround) { vsp += grav; } //ジャンプ if(isGround && oInput.keyJump) { vsp = -jumpSpd; } //横方向の当たり判定 if(place_meeting(x+hsp,y,oBaseWall)) { while(!place_meeting(x+sign(hsp),y,oBaseWall)) { x += sign(hsp); } hsp = 0; } x += hsp; //縦方向の当たり判定 if(place_meeting(x,y+vsp,oBaseWall)) { while(!place_meeting(x,y+sign(vsp),oBaseWall)) { y += sign(vsp); } vsp = 0; } y += vsp;
自分で精密な当たり判定をする場合組み込みの変数vspeedやgravityなどは使わないほうがやりやすいです。 vspeedやgravityなどはstepイベントが終わった後自動で位置に加算されてしまい、細かく制御がしずらくなります。 ですので自分でvspやgravなどの変数を用意してやると良いでしょう。 xzyさんが挙げて頂いたサンプルだとy+=vspeedの箇所で位置を加算していますがこれだと2重に加算されますので速度がものすごいことになっています。
次に当たり判定がめり込む原因として、移動先で当たり判定をしていないことにあります。 ですので先に移動速度を計算してその速度を加味した位置で当たり判定を行います。 サンプルだとif(place_meeting(x,y+vsp,oBaseWall))の箇所です。 これで移動先で当たり判定することになります。 これで当たっていなければy+=vspと位置を計算するようにします。
ものすごく難しいかもしれませんが参考になればと思います。 念のため、Youtubeのチュートリアルもここに置いておきます。 英語ですがジャンプアクションシューティングの基礎的なことを学ぶことができます。(ここでめり込まない当たり判定も解説されています。) https://www.youtube.com/watch?v=izNXbMdu348&list=PLPRT_JORnIupqWsjRpJZjG07N01Wsw_GJ
\nを+=で追加する.......その発想はありませんでした!!ありがとうございます!!
方法論としては、 配列の要素数だけForなどでループして、 要素毎に変数(例:str)に、 要素の値と\n(改行) を追加します
str += $"{array[i]}\n";
最後にstrをdraw_text(x, y, str)で描画します
または、 配列の要素数だけForなどでループして、 要素毎に
draw_text(x, y+10*i, array[i]);
という感じで縦に並べて描画するのもありです
範囲を制限するには、For文のループ範囲で制限するかif文で制限すればOKです
すみません訂正させてください 2023.200.0.281にロールバック関連のバグが無いとは言い切れないと思います 2022年7月ごろのベータIDEであれば、多分バグが無いです (その頃にロールバックゲームのコンテストが開催されていて、個々の開発者たちがロールバック機能を使っていたので) それでもよく分からないバグが出た場合は色々IDEのバージョンを変えて試してみてください
❤
a.xが見つからないというエラーが起こってしまったので、代用でobjectAを作成のaの値に入れ、おかしな挙動にならないよう、b.a = aの後にアクティブになるようにしたところ上手くいきました!!今まで何となくで使ってきたので細かい説明助かりました、ありがとうございます!!
BとCのコードを変更をしてみました。 これで動作すると思われます。
objectB
//create a = noone;//aのインスタンスを保持する変数 visible=false //step x=a.x//cで受け取ったaの座標と同期 y=a.y
objectC
//create alarm[0]=1 a=0 //alarm[0] var a= instance_create_ layer(x,y,layer,objectA) var b= instance_create_ layer(x,y,layer,objectB) b.a = a;//bにaのインスタンスを渡す a.visible=true b.visible=true a++ if(a!=5){ alarm[0]=1 }
【細かい説明】 インスタンスとは生成されたオブジェクトのコピーことを言います(たぶん) 以下のソースコードだと、固有のインスタンスではなくおそらく最初に生成されたオブジェクトAの座標を取得することになります。
x=objectA.x y=objectA.y
objectAが一つしかない場合はこれで問題ないですが複数ある場合はどのobjectAを取得できるのか明確ではありません。 ですのでinstance_create_layerで変数を受け取ってそれを用いて変数を変更したり受け取ったりします。 今回変更したコードはCで生成されたobjectAのインスタンスをobjectBに渡して利用するコードになってます。 少々流れが複雑ですがわからないことがあれば聞いてください。
なるほど、移動する仕組み自体を作るわけですね。 参考になります、ありがとうございます。
ブートroom(orタイトル画面room) room_goto(room名) ↓ 最初のroom
という作りにしていて、room名を書き換えてやってます。
安直な考えかもしれませんが一時的に新しいオブジェクトを作って、そこに if(keyboard_check_pressed(vk_enter)){ room=ルーム名 } をstepに書いて、毎回確認したいルーム名に変更する......とかはどうでしょうか.....?
そうでしたか、とりあえずチュートリアルには従っておきます。 回答ありがとうございました!
避けられてるんですか。なんかあるんですかね?
わたしの場合特に理由もなくそのイベントは使ってないです。 ほぼ、Create、Step、Draw、たまにAlarmくらいしか使わないので。
エンターキーを押したときに、配列の変数「inv」内、現在のアイテム欄のカーソル位置ID(順番)を参照しようとしているが、配列が空だと参照しようがないのでエラーになっている状態です。
配列の範囲外を参照しないようにチェックするとエラーが出ないようにできます。
//もしアイテムを使用したら/////////////////////////////////////////////////////////////////////////// if keyboard_check_pressed(vk_enter){ inv[selected_item].siyou();
「inv[selected_item]」で配列の値を参照しているので、その前のif文で、配列が空だったら処理しないように条件文を追加します。
//もしアイテムを使用したら/////////////////////////////////////////////////////////////////////////// if( array_length(inv) > 0 && keyboard_check_pressed(vk_enter) ) {
配列変数invの配列要素数が0(アイテムがない状態)より大きい かつ キーボードのエンターキーが押されたら という条件にすれば配列要素数1以上の時に、エンターキーの処理を実行する状態になります。
「&&」は&&で両方の条件を満たしたときにtrueになります。
試してみてください。
GMEditも機能しなくなってます。僕の環境だけかもしれませんが。
GMLiveの2024.2フィクスが出たのでライブコーディング機能するようになったようです。
GMLiveがエラーで使用できません。現在開発者がアップデート中とのこと。 それまではライブコーディングできないと思います。
毎度のことながら説明が下手ですみません!!!!ありがとうございます!!これがやりたかったことです!!
やりたい動きと現状の無駄な動きがわからないので、こちらで推測して書きます。 オブジェクトの位置によってどっち回りに回転させるかという話で、角度が近い方に回転させたいのだと推測します。
angle_difference(角度1, 角度2);
で2つの角度の差を求めることができます。この値は正負の符号を持ちます。 この符号を利用すればどっち回りに回転させるかを制御できます。
diff = angle_difference(向きたい角度, 今の自分の角度);
image_angle += sign(diff);で符号によって回転の方向が変わります。
image_angle += sign(diff);
もし的外れだったらまた質問してください。
マニュアル(ver2~2.2.x) マニュアル(ver2.3~) YoYoGames YoYoGames 公式コミュニティ GM関連のYoutubeチャンネル集 解説・資料サイト集(日本語) 解説・資料サイト集(英語)
GMLにも拡張機能的なものがあるんですね.....!!ありがとうございます!!購入検討してみます!
一番有名なのはGMLiveというツールを使うことですかね。
実行中にコードを直接書き換えたり、roomのオブジェクトを移動させたりしたらそれが反映されるツールです。
ただし、有料であり資料もほとんど英語ですので使うときは公式ドキュメントとにらめっこが必要です。
一応数少ない日本語資料もあります。(古いバージョンですが)
https://qiita.com/2dgames_jp/items/7e908ce8e4bf8a2f19f7
自前でやる場合はセーブファイルをつくって実行中にセーブとロードをして値を変更する方法もあります。
以前にそのような記事を書いたので参考にしてみてください。
https://zawazawa.jp/gamemaker_jp/topic/119
今のところ最新版は不具合が多く、新機能も使いににくい状態ですぐにアップデートするメリットは少ないです。
ですので安定したバージョンを使うことをおすすめします。
新しいバージョンが出たらすぐにアップデートする癖があるんですが、不具合のことも考慮するとすぐにアップデートしないほうがいいとかってありますか?
どうやらCompatibilityModeではなくcollision関数関連の挙動がおかしくなっているみたいです
GeneralGameOption->CollisionCompatibilityModeのチェックが外されましたおそらくデフォルト値に更新されたのだと思いますこれによって当たり判定がおかしくなる不具合がおきました。
ただし、現在再定義する際どの項目を選択してるのかがわからない問題があります(バグ報告済み
ショートカットキーを自分で再定義できるみたいです
windows11 microsoftIME US配列キーボード環境下では日本語でテキスト入力ができませーん!
原因をいくつか考えてみました。
⓵seq変数にシーケンスのインスタンスが入ってない。
これはあさまどさんのコードのやつでチェックするとseqが存在しないとなってしまいます。
どこかのタイミングで以下のようなコードを使ってシーケンスのインスタンスをseqに入れてやる必要があります。
⓶seq変数の中身が削除、変更されている
どこかのコードでseq変数の中身を書き換えてしまっている場合は動きません。
⓷シーケンスを削除している。
移動より先に以下の削除のコードに到達している場合はインスタンスがないので動きません。
⓸カメラのx,yが動いていない
カメラのx,yの値に変化がない場合は動作していないように見えるかもしれません。
シーケンスを使ったことがないので回答はできないのですが、このコードがどこに書かれているか知りたいところです。
あと、これを実行するとOutputにはなんと出力されますか?
ご回答ありがとうございます!
すいません、記載ミスです。
layer_sequence_x(seq, oCamera.y);
↓
layer_sequence_y(seq, oCamera.y);
どちらもlayer_sequence_xになってるのが原因でしょうか?
その部分のコードと該当するオブジェクト名をここに貼ることはできるでしょうか
あと、実行時エラーの内容をここにはることはできるでしょうか
place_meetingってスプライトがないと使えないんですね.......初めて知りました!!ありがとうございます!!!!
place_meetingはコリジョンマスクで当たり判定を行う関数なので、スプライトを持たない(コリジョンマスクを持たない)場合は使えません。
線で当たり判定をするにはcollision_lineかcollision_line_listを使ってください
矩形ならcollision_rectangle, collision_rectangle_list
円ならcollision_circle, collision_circle_list
楕円ならcollision_ellipse, collision_ellipse_list
点ならcollision_point, collision_point_list
で当たり判定ができます
*_listは複数の対象との当たり判定をして、当たっている対象をlistで返すものです
_listがついてないものは、最初に当たりを検出した対象を1つ返します(対象が1つだけと分かってるならこれで足ります)
生高橋さん、asaさんありがとうございます!その発想はなかったです!
一足先に生高橋さんが詳しく説明してくれてました!
同じStepイベント内でキー入力を2回拾っているのでそういう挙動になっています。
やりかたと書き方はいろいろありますが、例えば下記のような方法はどうでしょうか。
キーを押す条件を一つにして、その中に加算条件を入れてみました。
また、ifとelse ifでaの条件をまとめてみました。
ifとelse ifでまとめた条件は上からの順で条件を判定していき、合致したもののみを実行します。
if(a == 0)の条件が合致すればelse ifの条件は無視されます。
これで1フレーム内で特定の条件のみを実行することができます。
ifのみで構成すると、すべての条件をチェックしますので注意が必要です。
ifとelse ifなどの基本構文はどのプログラムでも使いますので覚えておくとよいと思います。
また、単純に数を加算するのであればエンターキーを押したら+1加算するというものにしてもいいかもしれません。
す、すごい...。&&については初めて使いました...。
解決しました。ありがとうございます。
分かりやすい解説ありがとうございます!!!!!!!初めて重力系(?)のプログラムをやるので助かりました!!!!
ジャンプアクションの移動と当たり判定のテンプレートを一旦置いておきます。
細かく解説すると長くなってしまうので一部のみ抜粋して解説します。
自分で精密な当たり判定をする場合組み込みの変数vspeedやgravityなどは使わないほうがやりやすいです。
vspeedやgravityなどはstepイベントが終わった後自動で位置に加算されてしまい、細かく制御がしずらくなります。
ですので自分でvspやgravなどの変数を用意してやると良いでしょう。
xzyさんが挙げて頂いたサンプルだとy+=vspeedの箇所で位置を加算していますがこれだと2重に加算されますので速度がものすごいことになっています。
次に当たり判定がめり込む原因として、移動先で当たり判定をしていないことにあります。
ですので先に移動速度を計算してその速度を加味した位置で当たり判定を行います。
サンプルだとif(place_meeting(x,y+vsp,oBaseWall))の箇所です。
これで移動先で当たり判定することになります。
これで当たっていなければy+=vspと位置を計算するようにします。
ものすごく難しいかもしれませんが参考になればと思います。
念のため、Youtubeのチュートリアルもここに置いておきます。
英語ですがジャンプアクションシューティングの基礎的なことを学ぶことができます。(ここでめり込まない当たり判定も解説されています。)
https://www.youtube.com/watch?v=izNXbMdu348&list=PLPRT_JORnIupqWsjRpJZjG07N01Wsw_GJ
\nを+=で追加する.......その発想はありませんでした!!ありがとうございます!!
方法論としては、
配列の要素数だけForなどでループして、
要素毎に変数(例:str)に、 要素の値と\n(改行) を追加します
最後にstrをdraw_text(x, y, str)で描画します
または、
配列の要素数だけForなどでループして、
要素毎に
という感じで縦に並べて描画するのもありです
範囲を制限するには、For文のループ範囲で制限するかif文で制限すればOKです
すみません訂正させてください
2023.200.0.281にロールバック関連のバグが無いとは言い切れないと思います
2022年7月ごろのベータIDEであれば、多分バグが無いです
(その頃にロールバックゲームのコンテストが開催されていて、個々の開発者たちがロールバック機能を使っていたので)
それでもよく分からないバグが出た場合は色々IDEのバージョンを変えて試してみてください
❤
a.xが見つからないというエラーが起こってしまったので、代用でobjectAを作成のaの値に入れ、おかしな挙動にならないよう、b.a = aの後にアクティブになるようにしたところ上手くいきました!!今まで何となくで使ってきたので細かい説明助かりました、ありがとうございます!!
BとCのコードを変更をしてみました。
これで動作すると思われます。
objectB
objectC
【細かい説明】
インスタンスとは生成されたオブジェクトのコピーことを言います(たぶん)
以下のソースコードだと、固有のインスタンスではなくおそらく最初に生成されたオブジェクトAの座標を取得することになります。
objectAが一つしかない場合はこれで問題ないですが複数ある場合はどのobjectAを取得できるのか明確ではありません。
ですのでinstance_create_layerで変数を受け取ってそれを用いて変数を変更したり受け取ったりします。
今回変更したコードはCで生成されたobjectAのインスタンスをobjectBに渡して利用するコードになってます。
少々流れが複雑ですがわからないことがあれば聞いてください。
なるほど、移動する仕組み自体を作るわけですね。
参考になります、ありがとうございます。
ブートroom(orタイトル画面room)
room_goto(room名)
↓
最初のroom
という作りにしていて、room名を書き換えてやってます。
安直な考えかもしれませんが一時的に新しいオブジェクトを作って、そこに
if(keyboard_check_pressed(vk_enter)){
room=ルーム名
}
をstepに書いて、毎回確認したいルーム名に変更する......とかはどうでしょうか.....?
そうでしたか、とりあえずチュートリアルには従っておきます。
回答ありがとうございました!
避けられてるんですか。なんかあるんですかね?
わたしの場合特に理由もなくそのイベントは使ってないです。
ほぼ、Create、Step、Draw、たまにAlarmくらいしか使わないので。
エンターキーを押したときに、配列の変数「inv」内、現在のアイテム欄のカーソル位置ID(順番)を参照しようとしているが、配列が空だと参照しようがないのでエラーになっている状態です。
配列の範囲外を参照しないようにチェックするとエラーが出ないようにできます。
「inv[selected_item]」で配列の値を参照しているので、その前のif文で、配列が空だったら処理しないように条件文を追加します。
配列変数invの配列要素数が0(アイテムがない状態)より大きい かつ キーボードのエンターキーが押されたら
という条件にすれば配列要素数1以上の時に、エンターキーの処理を実行する状態になります。
「&&」は&&で両方の条件を満たしたときにtrueになります。
試してみてください。
GMEditも機能しなくなってます。僕の環境だけかもしれませんが。
GMLiveの2024.2フィクスが出たのでライブコーディング機能するようになったようです。
GMLiveがエラーで使用できません。現在開発者がアップデート中とのこと。
それまではライブコーディングできないと思います。
毎度のことながら説明が下手ですみません!!!!ありがとうございます!!これがやりたかったことです!!
やりたい動きと現状の無駄な動きがわからないので、こちらで推測して書きます。
オブジェクトの位置によってどっち回りに回転させるかという話で、角度が近い方に回転させたいのだと推測します。
で2つの角度の差を求めることができます。この値は正負の符号を持ちます。
この符号を利用すればどっち回りに回転させるかを制御できます。
image_angle += sign(diff);
で符号によって回転の方向が変わります。もし的外れだったらまた質問してください。