星田オステオパシー

Rustでトランキライザーガン その05 弾丸をどうやって動かせば良いのか?

 じゃあ弾丸を発射して、プレイヤーとは無関係に一方向に飛んでいく・・ってのをやってみるか。
 うーん・・確か、オブジェクト指向的には基本タイプの構造を継承して新たなオブジェクトを設計するってのがあったはず。基本タイプがPlayerってのは大いに変だけど、座標とか向きとかは共通してるのでPlayerからBulletを作るべきなのか?そうでなくもて方法は知っておきたいので質問

 
 え、継承無いの!?

 あ、そのような目的の時に必要なのがトレイトなのか〜。ま、この際だから使い方をマスターするべく取り組もう。
 ふんふん・・上の例だとGameObjectというトレイト型の構造体的なものを作って、共通で行いたいメソッドとか関数を登録しておき・・


 Playerと共通のフィールドも別のフィールドも持つ別種の構造体を用意して


 implでGameObject構造体?を対象にして、それを実際に紐付ける構造体(ここではPlayer)をforで指定して、普通にメソッド定義をすると・・
 じゃあAnimalにもBulletにも共通の名前部分は同じものを書かないといけないわけ?うーん・・手間かかるだけじゃないか?別個で全部作ってるのと変わらないじゃないか。
 まあ継承って色々と悪い話も聞くから、思い切って使わないってのもありなのかな。


 ついでに、フィールドに自動行動のためのメソッドなりを実装した場合、そのフィールドの型は何になるのか?ってのを質問

 つまりAnima型のactionフィールドに入れる場合だな

 ああ、勘違いしてた。結局パターンマッチングのために書いてるだけなので、Enumで作って、実際はArmの先でメソッドを実行するってことか。
 え〜と、構造としては・・
・Enumで区分けとなる型(BehaviorPattern)と、その中の種類を定義
・Animal構造体に任意の行動フィールドを作成、型名は↑の区分けとなる型
・Animal構造体内でメソッドとして、実際のメソッドをそれぞれ定義
・パターンマッチのArm先で、実際のメソッドを実行
 ってことか。こういう風に文章にしないと理解できないんです


 実際のメソッド。ここ使われてる関数もAnimal構造体の中にImplしないといけないわけで・・これも慣れなのかも知れないけど設計が大変だなぁ



 述語もImpl内に。まあ、パッケージになってるようなものだから、管理は楽になるのかな


 ん?何だこれは?Enumのリストの中で引数の型を書いてるってことか?ちょっと調べないと・・

 ん〜なんかこんがらがって来た(いつもだが)。
 キー判定の中で弾丸発射(Spaceキー)をした場合、新たに弾丸インスタンスを作るんだよね?でも、ここで作ったからってスコープとかはどうなるんだ?どこに作られるのだろうか・・

 ん?もしかして予めBullets的な変数を作っておいて、そこに新たなインスタンスを送り込むということか?


 あ、なるほど〜・・・先に入れ物を作っておくという基本的な発想を欠いていた。

 それは良いとして、Bulletインスタンスを作ってもそれをPlayerとは独自で動かして命中判定をしてAnimalインスタンスの耐久度を減らして・・って言う全体の流れがピンと来ない。なので解説をお願いする

 まずはそれぞれの構造体を作りますよね?


 メソッドとしてスペースキーを押したらPlayer.bulletsにBulletインスタンスを新たに作ってPushするものを実装

 その後は手続き的にForでBulletsリスト(ここでは複数の弾丸を処理するデザインになってるけど、実際は弾は画面に1発しか存在できない)を回して弾丸の位置を更新
 描画は範囲から出たら消去(ここ、便利な書き方があるんですね、覚えておこう)
 それぞれ描画・・と

 先程の例は俺のコードに合わせて、Player構造体のフィールドとしてBulletsを設定してくれてたけど・・これってどう考えてもWorld・・つまり、ゲーム全体の構造体を作って、そのフィールドの1つとしてはBulletsやらMonstersを作るほうが良いよね?それでClaude先生はずっとGame構造体(World)を作る例ばっかり出してたのか〜。
 Game構造体にPlayer、Monsters、 Bulletsのフィールドを作って


 Updateメソッドを実装、Game構造体の中にPlayer構造体もあるので、Game.player.メソッドでアクセスできるのか・・同様に弾丸も動物もUpdateを作って回すわけか

 うーん、なんとなく全体の流れは分かってきた。いやコレ、大変だなぁ・・設計が。事前にちゃんと考えておかないといかんじゃないか(当たり前だけど)。

 ちゃんと作ってればMainの記述はすごくシンプルに出来るわけだな〜


 ::new()の初期値がどうなってのか?と疑問に思ったので質問。なるほど、Implの時点で初期値を決めておくことも出来るわけか


 よ、よし・・とりあえずこれで材料は揃った。
 明日は実際に弾丸を表示して動かすところをやりたいが・・今さらGame構造体を作って・・ってのはちょっと厳しいので、普通にMain内にBullet変数を作っておいて、そこに破壊的更新をして行くって形にしよう。次のゲームではちゃんとGame構造体方式やります

 しかし・・・結局の所、Claude先生に質問してカンニングしてるだけになってるなぁ。ま、今作はもう諦めた。次作の「ボンバーマンモドキ(予定)」の時にはちゃんと自分で書けるように頑張ろう。

 昨日もそうだったけど、29,30,31日は仕事が入ってて忙しいのと甥っ子が冬休みで接待マイクラをしないといけないので時間的にはちょっと厳しいんだよなぁ・・
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事