投稿記事

栗片いづも/妄想御殿 2023/10/16 01:34

カード式で多数vs多数のシステム

ヒロインのターンで攻撃関係で、それなりに理想の動きになるところまでできました
敵の攻撃とコスト周りの設計ができたら、とりあえずのゲームにはなるかなといった状態ですね
遊べるエロゲ用システムとして作ってるので、あんまりゲームがゲームするのも合わないと思ってますし、ほどよくそれっぽい感じを目指してます


この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

栗片いづも/妄想御殿 2023/10/15 09:55

自分向けGodot備忘録 #4

Nodeのパスを作るタイミング

@exportが一番確実とはいえ使いたくない場面は多いです
「エディタで毎回ドラッグ&ドロップするのが面倒」から「動的生成するからエディタでのアタッチができない」まで
その場合はget_node()/$を使ってパスを作るのですが、このタイミングが動的生成時には特に問題になる場合があります
一番多いパターンは「func _ready()」内や、変数宣言時に「@onready」で読み込ませる方法だと思います
しかし動的生成して生成後に関数を使う場合、パス生成が終わってない状態でアクセスしてしまう場合は当然発生します
なので動的生成では生成後の最初だけ動かす関数の最初にget_node()/$をしてやるのが安全だと思います
動的生成したSceneの変数がそのScene内だけで完結するのであれば、あまり気にしなくてもいいです


スクリプトを跨ぐクラスの扱い方

素直に

const 「スクリプト用の変数」 = preload(「スクリプトのパス」)

で変数を先読みしてその変数からクラスを呼び出すのが無難
とはいえ、何かと面倒なのでよほどの理由がないならDictionary型で処理した方が楽だし安全だと思います
どうしてもクラスが必要であるなら「クラスとDictionary型を相互変換する何かを用意する」とかをすればいいと思います


RichTextLabelのInspectorにフォントサイズの設定タブが無い

なぜか無いので、位置決めにも困る
なので最初に[font_size=xx]を書いておくのが楽
そもそもBBCode使わないならLabelの方が楽
テキスト表示の時にも、処理としてテキストデータの最初に[font_size=xx]を差し込む仕組みにしておくと楽だと思います


intの乱数が欲しい場合に使うrandi_range()

よく忘れるので

randi_range(x、y)

は、x以上y以下の整数
C#とかのrand関数だとy未満になるので、うっかりしがち

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

栗片いづも/妄想御殿 2023/10/06 08:19

自分向けGodot備忘録 #3

これまでに感じたトラップ的な要素です


ColorRectよりPolygon2DやSprite2Dの方が無難

マウス入力のためのArea2Dがある場合に、マウスポイント直下にColorRectがあるとなぜか反応しません
ほかにもこういうことがあるかもしれないし、そもそもシンプルな四角形はもっぱら何かの代用なので素直に「Polygon2Dで四角形を作る」「10pixel四方の白い四角い画像を用意してそれをテクスチャにSprite2Dにしてサイズを合わせる」あたりにしておいた方がいいと思いました


フォルダ構成変更でtscnファイルが壊れるときがある

フォルダの構成変更で移動させたファイルを参照してるSceneが保存されているtscnファイルがたまに壊れます
フォルダ構成を変更する場合には臨時でプロジェクトをまるごとバックアップしておいた方がいいです



GDScriptのArrayは多次元配列を扱うにはちょっと面倒

マップとかでの横8マス縦5マスの広さみたいな感じはゲームではよく使いますし、そのときにMapData[x, y]とかMapData[x][y]みたいな感じにしてデータを収納したくなります
しかしArray[Array[Sprite2D]]みたいなのはできないので、Sprite2Dを2次元配列したい場合は

var DataArray:Array

const X_count = 8
const Y_count = 5

func _DataArraySet():
	var _data_array_y:Array[Sprite2D]
    for x in X_count:
    	DataArray.append(_data_array_y)

な感じでひな形を作ってあげるといいです
マップとかではSprite2Dとなってるところは個々のマップパネルデータの自作クラスだったりとかが入ると思います

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

栗片いづも/妄想御殿 2023/10/04 02:26

Godot練習でのモック版カード型戦闘ゲーム

というわけで今後よく使うであろう部分の練習製作としてのカード方式戦闘をGodotで作ってみました
双方ダメージ与えあって終わりでエロもゲーム要素もなく、本当に実運用としての実装テストな仕上がりになっています

MockCardGame.zip (24.75MB)

ダウンロード

マウスの左クリック : カードやボタンの選択・メッセージを進める
Ctrlキー : メッセージを進める
ESCキー : タイトルに戻る


手札の追加も手札の使用もEN消費は1です
ENは毎ターン3回復します
カードのPowerがモンスターに与えるダメージです
どちらかのゲージが0になったらゲーム終了です

カードを引くには「Draw+1」をクリックしてください
ターンエンドするには「Turn End」をクリックしてください



このゲームの実装で気になったことがあればコメントに書いておいてもらえると、答えられる範囲なら備忘録で答えられると思います

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

栗片いづも/妄想御殿 2023/09/30 15:39

自分向けGodot備忘録 #2

今回はボタン系です
2項目くらいごとが見やすいなと思いました


ボタン的な役割を持たせた画像

ボタンそのものは用意されていますが「画像の上にマウスオーバーさせたときに何かさせる」とかそういうのをやる場合はUnityの時もそうですが自前で作ってしまったものの方が扱いがしやすいというのがあります

ButtonNode
└Area2D
	├CollisionShape2D
    └ボタン用画像(Sprite2D)

このようなSceneがボタン用のNodeになります
CollisionShape2DはShapeをRectangleShape2Dにして、ボタン画像と同じサイズに変更してください
ボタン画像を「とりあえず四角の画像でいいや」でColorRectで作ったら動きませんでした

親NodeのButtonNodeに新規スクリプトをアタッチして、Area2Dのノートタブからinput_eventとmouse_enteredとmouse_exitedを接続してください
これでArea2Dからでるsignalが接続され、対応したコードが3つ追加されています

func _on_area_2d_input_event(viewport, event, shape_idx):
func _on_area_2d_mouse_entered():
func _on_area_2d_mouse_exited():

そこから必要なコードを書いてこうなります

signal BtnClick_R
signal BtnClick_L
signal BtnEnter
signal BtnExit

func _on_area_2d_input_event(viewport, event, shape_idx):
	if event is InputEventMouseButton and event.pressed:
    	if  event.button_index == MOUSE_BUTTON_RIGHT:
    		emit_signal("BtnClick_R")
    	if  event.button_index == MOUSE_BUTTON_LEFT:
    		emit_signal("BtnClick_L")


func _on_area_2d_mouse_entered():
	emit_signal("BtnEnter")
    
    
func _on_area_2d_mouse_exited():
	emit_signal("BtnExit")

これでCollisionShape2Dの範囲内でマウスを操作するとButtonNodeからボタン信号をだす仕組みができます

func _on_area_2d_input_event内で右クリックと左クリックを検知して、検知したらBtnClick_RとBtnClick_Lを発信させます
_on_area_2d_mouse_enteredはマウスがCollisionShape2Dの範囲内に侵入したときに呼び出されるので、そのときにBtnEnterを発信させます
_on_area_2d_mouse_exitedはマウスがCollisionShape2Dの範囲内から出た時に呼び出されるので、そのときにBtnExitを発信させます

もしマウスオーバーでボタンの画像を変えたり、ボタンの一部を変えたい場合は、_on_area_2d_mouse_enteredと_on_area_2d_mouse_exitedにそのための処理を増やすだけになります


重なったカード画像の一番上を取得する方法

カードゲームの手札などでよくある重なった演出で使う、重なった画像の一番手前のものを取得する方法です

まずカード単体のSceneを上のボタン的なものと同じように作ります

CardNode
	└Area2D
      ├CollisionShape2D
      └カード画像(Sprite2D)
      

CardNodeにアタッチしたスクリプトもほぼ同じで

signal BtnEnter(card_no)
signal BtnExit(card_no)

var CardNo:int


func _on_area_2d_mouse_entered():
	emit_signal("BtnEnter", CardNo)
    
func _on_area_2d_mouse_exited():
	emit_signal("BtnExit", CardNo)

ここでの違いはsignalに引数を持たせることです
複数のカードにCardNoという変数を持たせることで、BtnEnterとBtnExitがどこから来た信号なのかをわかるようにします


そしてカードを選択するSceneとして

CardSelectNode
	├CardNode_0
 	└CardNode_1

とします
新規Sceneを作り、その子Nodeとして上記で作ったCardNodeのSceneを入れただけです

CardSelectNodeに新規スクリプトをアタッチして、そこに

@export var CardNode:Array[Node2D]

func _ready():
	for i in CardNode.size():
    	CardNode[i].CardNo = i
        CardNode[i].BtnEnter.connect(_SelectAdd)
		CardNode[i].BtnExit.connect(_SelectRemove)
        
func _SelectAdd(card_no):
	pass
    
func _SelectRemove(card_no):
	pass

と記述します
そしてエディタ上でCardNodeに子ノードのCardNodeをツリーの上から順に追加してください

これによって、このSceneが動いたら自動的に2つの子Nodeの信号をCardSelectNodeのスクリプトへ接続でき、子Nodeにはそれぞれカード番号が振られます
子Nodeのsignalはそれぞれ
・BtnEnterは_SelectAddに引数付き
・BtnExitは_SelectRemoveに引数付き
への接続となります

そしてここから接続先への処理を記述します

var _SelectCardArray:Array[int]

func _SelectAdd(card_no):
	if not card_no in _SelectCardArray:
      _SelectCardArray.appent(card_no)
    
func _SelectRemove(card_no):
	if card_no in _SelectCardArray:
      _SelectCardArray.erase(card_no)

これによりカードにマウスが乗った場合には「_SelectCardArrayにそのカード番号が無ければ追加」となり、カードからマウスが外れた場合には「_SelectCardArrayにそのカード番号があれば削除」という処理ができるようになりました

そして最後に

func _process(delta):
	if _SelectCardArray.size() > 0:
    	_SelectCardArray.sort()
        var _card_index = SelectCardArray.size() - 1
        print(_SelectCardArray[_card_index])

とすると、カードにマウスが乗っている時に、マウス直下の一番上に表示されている(ツリーで一番下)のカード番号がデバッグログに表示され続けるようになります

これを_SelectCardArrayへのNodeの登録番号とカード番号を同じにすることで、いろいろな演出や操作ができるようになりました

カードのオブジェクトを動的生成とも相性がよかったです

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

1 2 3 4 5 6 7

月別アーカイブ

限定特典から探す

記事を検索