星田オステオパシー

プログラミング学習日記 2024/12/19〜

2025/01/17 他のゲームエンジンを物色する

 Pythonを使ってレトロゲーム風ゲームを作れるPyxelってのが良さげじゃないか?Pythonも復習したいし・・と公式ページを観てBunsen-Linuxの環境にインストールを試みるもPipが入れられない。
 Claude先生に尋ねると、どうもシステム保持のためにインストールを許してない時のエラーだという。そこで、代替案として出たうちの1つ、Pipxを入れてみることにした。
 が、駄目ェ!



 しょうがないので推奨案であった仮想環境を構築してのインストールを試す。いや、なんかパフォーマンスが落ちそうなイメージじゃないですか?仮想環境って。でも、こっちでは成功

 サンプルコードの実行実験、成功。でも、思ってたよりも全然ドキュメントが充実してない。出来るやつが見たら、このレベルのドキュメントでも作れるようになるんだろうけどさ〜・・
 実は近々Pyxelの本が出るので、手ほどきとしてそれに頼るのが正解かな?


 続いてLua言語を使った2Dゲームエンジン「Love2D」の環境を用意してみる。公式のインストール方法ではうまく行かなかったけど、SynapticにちゃんとLove名義で入ってたのでインストール。
 サンプルの実行方法もよく分からなかったけどClaude先生に聞いて試行錯誤した結果判明
 (少なくとも)Synapticで入れた場合はパスは通ってるみたいなので場所はどこでも良い。
 Main.luaファイルにコードを書いて用意。
 そのフォルダにてターミナルを起動し「love .」とコマンドすると

 ちゃんと起動した。拡張子.loveは色々なリソースを添付して作るものらしい。

 うーん・・どっちにすっかなぁ〜・・Lua言語は前から興味あったしなぁ・・とりあえずPyxel本が届くまで時間がかかるわけだし、Love2Dからやってみるか!


2025/01/14 今までなんか納得できてなかった参照の渡し方について質問する
 他の人(Claude先生含む)が書いたコードを見ると引数として渡す時に&mutが外れていたりしてるのが納得できない。ということで質問・・もしかして暗黙の省略が行われてるのか?と疑ったが・・・やっぱり!
 もうっ!このせいで型指定の理解が大幅に遅れたわ!これって初学者にはもっと何度も繰り返して注意スべきところじゃないか!?


 なるほどね


 俺は関数やメソッドの引き渡し時には明示的に書くぜ!

 そして本編で気になった処理を遅延させて一気に処理する方法。
 なんと新たな構造体を作ってしまうのか。ここにIDと新たな状態を保存すると


 なるほど・・まあでも今回ボクが書いてるようなデータをどんどん枝分かれした先に送りつけていく方法だと難しい気がするなぁ・・レイヤーが1層だけだったら返り値でPushすれば良いけど、深い派生先で発生した変更をPushするとしたら結局手間がかかるだけだし。でも、Rustでコレが許されてないとすると本来のデザインとしてデータを持ち運んでどんどん先で更新するってのは悪手ってことなんかねぇ


2025/01/12 Rustで音を鳴らしたい & シュタインズゲートコラボ
 なんとPrintlnで音が出るとな?

 はぇ〜普通にMp3とかも使えるのか!これは・・CLIの超チープな画面にオーケストラの超リッチな音楽を鳴らしたら笑えるだろうねw
 作ってるトランキライザーガンで弾丸発射と自機がやられた時に、単音で良いから効果音が欲しいんですよね。それと、原作と違って森の中に動物が入るときに動く方向が見えなくて不利なので、周囲8コマの中に動物が入ったら何か音でアラート出すようにしたいんですよね〜


 そう言えば数年前に予告を見たPaizaとシュタインズゲートのコラボ講座、全くチェックしてなかったので久々に行ってみたら、まだしっかりと残ってました!ちょっと別口で進めてみるかな〜

 とりあえずプロローグだけやりました。なんかラボメンにプログラミングを教えてゲームを作って活動資金を捻出するという。ほ〜・・Pythonの文法を思い出すついでにやってみるか。RustとかSchemeは無いだろうし


2025/01/11 Rustで外部ファイルにデータを置きたい

 トランキライザーガンが1000行を超えてきて、さすがに該当箇所を探すのが大変になってきてるので相談


 これ、定数でもいるのか?と思って調べたらいらんとのこと。別のクレートを使うときだけか。


 なるほど了解

 作るときにはPubで使うときは普段のクレートと一緒ってことやな

 テストは知らん


 なるほど・・まあ、今のところ関数とか定数とかをまとめておけるファイルが1つあれば良いけど、こういうのもあったなぁとボンヤリとでも覚えておこう

 これも良いね


 もともとトランキライザーガンでOld_coordinateでまとめた座標を空白表示した後、ベクターをキレイにしたかったので聞いたけど、結局単品だけで使ってるのでいずれまた使う時に思い出そう


 ところで引数を受け取る時に中身が空のベクターを受ける場合、この型指定で大丈夫なのか?と不安になったので・・


2025/01/10 RustのVec関連

 トランキライザーで外周の座標を出力する時に(0..=12)とかって使って一気に作りたいなぁ・・と思ったので質問
 Collectのことを完全に忘れてたわ


 後はベクタの結合。これはちょっとなぁ・・・

 これが良い!が、Concatってどういうメソッドなのか


 マジかよConcat良いじゃない!覚えてこう(多分忘れるけど)



2025/01/09 モナドとか
 書いてる時に誤ってブラウザを閉じてしまったのでダイジェストで。トランキライザーを書いてる解説の中で「モナド」という概念が出てきて気になったので質問。モナドを使わない方法で書いてもらったこの面倒くささ、使うしかないな!と。

 さっきのがこうなるんだからな。

 これ2つとも同じことなのか。それでも前の何も使わないのと比べるとエラい違い。?もいいね


 なるほど・・道理でClaude先生がやたらと?を推してくるわけだな。今までありがたみを感じてなかったのは基本的にエラーが出る書き方をしてないからかな?


 なるほど〜!これを最初から言ってくれれば良いのに。これで(多分)分かったぜ!


2025/01/08 Map生成とか

 Crosstermでのマップ判定、元になってるのが1次元のUsize配列なので、いちいち変換してチェックさせるのが面倒。でも、2次元マップだと元になるマップのデザインが大変そう・・なんかCrosstermで定番のマップ作成方法とかないのか?と。次に狙ってるのが桃鉄ライクゲームなので(ボンバーマンは・・なんかトランキライザーガンとかぶるのでやめた)、マップ作成が大変そう・・


 うーん・・まあ、解決にはなってないな。最終的にはこういう形になるんだろうけど。

 そうそう、トランキライザーガンでは構造体を使わなかったけど、ちょっと慣れてきたので次回は構造体で管理しようとは思ってます。
 ところで上のコード、newの入れ子*だったら分かるけどこの形でもHeight分増えるのか?.get、.and_thenが謎


 そしておおっ!?コレコレ!テキストファイルから読み込んで構造体マップを作るコード、こういうのが欲しかったのだ。知らなかったのはload_from_string部分だけ、これでマップ問題は解決した!Claude先生やりますねぇ


 では先程わからなかった部分を。Vecって要素の後に要素数で生成するんだっけ、忘れてた。じゃあOK

 ふんふん、二次元だからyでは行をまるごと取得、更にそこからx個目を取得と。でもand_thenとMapの違いは?

 えw ムズい。

 うーん、まあ理屈はともかく役割は分かった。型の入れ子を防ぐ?って事か。とりあえずはOption型から2次元で抜くときには思い出せるようにしておこう・・この場の意識だけは。駄目ならコンパイルの時に表示されるし

 というわけで、本編へ戻ります


2025/01/07 Rustの参照とか

 本編でRustでゲーム作りに挑戦してるんですけど、その中で出て来た疑問とか、新たな概念など学習が必要だな・・と思う部分についてはプログラミングの原則に則って分割して統治しようかと。でも、画像の選り分けとか面倒で本編でそのままやったりもしてますけどね!

 ずっと放ったらかしだった「ライフタイム」について、もう一度挑戦してみようと。ベクトルをいじったりとか単純なゲームだと不要だけど、構造体を徹底活用したりすると必要になるみたいなんだよなぁ。


 ま、これは分かりますよね。というか、こんなのだったらライフタイム使わなくても良くないか?


 まず、返り値がimplだってのが謎。

 む、なるほど?

 なんか具体的な数値で出来たイテレータが返ってくるということか

 この上と下が同じ意味とは全く理解できないがw



 あ、なるほどようやく分かった。シグネチャーは突然Lispみたいな内側から湧き出る形になってるんかい。そして最終的にはi32の形のイテレータになるが、それを省略してると。
 ま、いつか使うことになった時に理解できるんじゃないかな?


 ところで、トレイト境界ってなんなのか?前にドキュメントは読んでたけど全く理解できてなかった。今なら・・どうだろう
 えっ?そんだけの事なのか

 これもそんだけの事か・・って印象。えーと、<T: Display>でTがディスプレイトレイト境界って示してその後の(item: T)で、普通に型指定やってるようなもんですよね?なんだ、そんだけの事かよ〜・・でも、まだトレイト実装をしたことがないから本当の意味では分かってないが

 ちょっとはスッキリしたぜ!


2024/12/22 完成した

 チラツキ問題と関連して、延々と描画ループを繰り返すのではなくて入力やブロック下降などの「データが更新されたときだけ描画する」という(まっとうな)省エネ案は駄目なのか?というのを聞いてみる。示されたコードは結構シンプルなものだったので、これなら機会があれば実験をすることが出来そうだ。

 では自作のコードとチラツキ問題が改善されたコードを見比べていこう。エディタを分けられないので無理やりな方法で比較していく。
 なるほど、まず最初にカーソルを消してるわけか・・

 そしてスコアはFor内部で更新せずに、Loop内で一度だけ表示するようにすると・・あれ?もしかして最初の「カーソルを消す」ってのさえやったら大丈夫なんじゃないか?

 やっぱり!単にカーソルを消すだけで良かったのだ。なーんだw

 では表示が出来たので、続いてDown_blocks関数の部分だけコメントアウトアウトをして実行してみる。うおお!動いた〜!ちょっと挙動が変だけど、ま、それはソレ


 次の段階に進もうとしたところで謎のエラー。Result型の形に沿ってないので直せという。結果、返り値の型をstd::io::result::Resultに帰る事でちゃんと動くようになった。なんで?と思ったら・・別ライブラリで同名の型が存在するために上書きされていたのだった・・マジで何考えてんだ?

 ではいよいよ・・最大の問題である非同期のキー入力部分を残すのみ!
 迷路ゲームではこういう風になってるので・・・

 我がテトリスもどきのRotateとShift関数を当てはめるとこういう感じかな?どうせ間違ってるんだろうなぁ・・と思ったら

 この部分は合っていた!いや、こういう直感的に書けるってのは文法に統一感があるってことで大変ありがたい。
 でも、ブロックは落ちてくるのに操作が出来ない!なんでだ・・Claude先生はpollってのをやってみて、待ち時間も短くしてみては?と上のコードを出してくれたのだが・・それでも駄目

 途中で配列の外にデータが漏れてパニック発生。すると入力していたコマンドが一気にプロンプトに放出された・・なんだこの挙動は・・ヒントになるかな?

 と、

 心強い返事

 うーん、どこが変わってるのか?あれ?enable_raw_mode()・・・あっ・・・迷路ゲームの最初の最初にコレ書けって言われてたわ!もしかしてコレか

 あとは

 これと言って違いがないものな。で、実行してみた結果・・

 テトリスやん!やったーっ!

 コレよコレ・・一番基本的なのを書き忘れてたわ

 これ、多分書かなくても大丈夫だと推測

  ところがドッコイ駄目でした。どうもpollうんぬんを入れないと、ずっと入力待ちの状態になってしまうらしい。じゃあ非同期のリアルタイムゲームだと必須だな。逆に、ADVとかRPGなんかの場合には使わないってことで・・

 おいおい・・これ、もはや理論上は作れないゲームは無いんじゃないのか!?(←「MZ-700に不可能は無い」理論と同じ理屈)

 ぐわー!楽しくなってきた〜!

 とりあえずテトリスはもう良いから次へ行こう
・テトリスを改造して類似ゲームを作る
・超名作「トランキライザーガン」再現に挑む

 テトリス亜種は・・例えば合体ロボットのパーツでゲッター、コンバトラー(混乱ポイントとしてボルテスも混ぜる)などを使った「スパロボ+テトリス」(アルベガスはどのように組み合わせても大丈夫なのでジョーカー的につかえてダイラガー15は逆に超難度)とか、マイクラの資源ブロックを落として特定のオブジェクトを作る「マイクラ+テトリス」とか・・まあでもCrosstermじゃ絶対に無理だしな

 となると・・やっぱりトランキライザーガンかな!あれはホントよく出来たシステムだからなぁ・・相当なチャレンジになるぜ


2024/12/21 今日は忙しかった

 朝から夕方まで(珍しく)仕事、その後宿直バイト・・ということで(珍しく)一日中働いてました。

 よって日中プログラミング学習活動は出来ませんでした!

 で、夜ですが・・以前から気になってたバイト先の低スペLinuxマシンのOS入れ替えを行いました。ZORINを入れてたんですけど、やっぱり遅いわコレ!特に日本語入力をしていると、なんかすべての動作で0.2拍くらい遅れるって感じでストレス。
 普通なら問答無用でBodhi-Linuxを入れるんですけど、過去、なぜかこのマシンでは二度OSが壊れてしまってるので・・何か他の候補は・・

 と、考えていたらちょうどBunsenlabs-Linuxなるディストリビューションの記事が目に入った。ほう・・なんかシンプルで実用的でカッコいい・・ということで早速インストール!

 いや、コレが無茶苦茶苦労した。
・インストールの手順がクソ面倒。ネットでの体験記では旧バージョンのものが多く、最新版の手順を紹介してる記事が(なかなか)見つからなかった。
・OSに入ってしまえばイーサネットカードが普通に認識されるのにインストール中には何故か認識されない
・・そのためにアーカイブミラーの設定が行われず、Mozcを始め新たにプログラムを入れられない

 一応再度インストールしたけど同じ症状。ネットに助けを求めてもあまり使われてないディストリビューションなのか解説が全然見つからない(特に最新版)。
 でも既にZORINは消えてしまってるので、諦めてしまうと眠るまでやることがない。しょうがねぇなぁ・・と今までオートで設定されていたアーカイブミラーの手動書き換えなどを調べて設定することに。気づいたら深夜1時、4時半起きなんだけどなんかフクラハギが異様に痒くて眠れない・・というプチ地獄。乾燥肌とかアレルギー、アトピー持ちの人って本当に大変だと思う(朝になったら幸い治っていた。変なものを食べたっぽい)。

 苦労の末、BraveやPeek、Rustも入れて実用環境が整った!
 ただ、軽量との評価だったけど最新版では起動時でメモリ使用量600MB〜800MB。Braveを起動してタブを5枚くらい開くと使用メモリ1.3GBくらいに達しているじゃないか。うーん・・搭載メモリ2GBのクソスペマシンなので結構ギリギリだな。Bodhiならもっと少なくて済むのだろうか?

 気になって帰宅後早速チェック。えっ!?起動後Braveでタブ5枚というほぼ同様の状況がコレ。なんとメモリ使用量1.73GB。マジかよ、Bunsenの方が軽いじゃないか(インストール直後なので汚れてないってのを考えるとほぼ同じと考えて良いか)。

 Bunsenはちょっとだけ触ったけど
・反応はソコソコ良い、明らかにZORINよりもキビキビしている
・最初からVLCなど「普通入れるよね」ってのが入っている
・Windowsキーと同時押しで各種基本プログラムが起動できるようにConkyの中にショートカット一覧が常に表示されているマウスを極力使わない設計思想
・画面がシンプルでカッチョいい
・そして何より!Mozcの変換候補がちゃんとカーソル部分に追従して表示される!これ、BodhiもZorinも左下とかに固定されててついて来てなかったのが不満だったので感動した。
・最初からVLCが入ってて、Bodhiだと出なかったスピーカー出力音がちゃんと出る!(Zorinも出る)

 というわけで、次に触るのが楽しみなマシンに生まれ変わったクソスペ水没PCなのだった


2024/12/20 チラツキ問題

 とりあえず作ってみたDisplay関数を使った結果ですが・・
 こんな感じでカーソルが暴れるんですよね・・

 Clauede先生に相談したところ、原因はこれらだと。


 で、バッファを使って一気に出力するパターンに変えてくれたんだけど

 結果がコレ。うーん・・そうじゃないんだよなぁ。迷路ゲームだと特に問題は無かったのになぜに?
 しょうがないので「迷路ゲームだとカーソルが最後の部分だけに表示されてるんで、そのようにできませんか?」とリクエスト。その結果・・




 こういうコードが提案されて

 こ、コレだーっ!!

 なるほど・・まあ、素晴らしいゲームにはならんけども

 明日は自作のNGコードと成功コードを比較して違いを探します。これは今後すべてのCLI非同期ゲームで使える表示部分なので念入りにやってみよう。
 それと、今回みたいに「全部まるごと、延々と表示を切り替え続ける」他に、「データが更新されたタイミングのみ切り替える」という事も可能ならばそれも知りたいもんだなぁ。


2024/12/19 ようやくCrosstermへ
 まずは迷路ゲームのコードを観察しよう。キモはこのDisplay部分と見た。ふーむ・・クロージャを作って全マス放り込んでいくという感じか

 入れ子Forで全マスを書き換えという部分。ふーむ・・プレイヤー部分と迷路部分を分けて描画してるのか・・自作テトリスモドキだと対象がVecのCellsで管理されてるので、分けなくても良いのでは?と思うのだが

 最後はこういう感じで締め。決まり文句みたいなものなんだろうけど、一応文法の意味を知りたいな

 ほうほう

 どうやらCrosstermは座標を2次元配列?で処理する模様

 ちゃんと理解したいので解説を頼む。Claude先生、Crosstermにも対応してるとは・・やりますねぇ!

 なるほどなるほど

 ふんふん、なるほどね。座標は文字ベースなのでCLIの流用で使えそうだな。というところで昼の部終了。

 というわけでテトリス用に書き換えて行くか。MoveToの引数はU16の必要があるので書き換えと。座標の型はもとのコードだとIsizeだけど念の為にUsizeにしておく。ほかは変える必要がないな

 最初はテトリミノの種類によって色を変えようと思ってたけど、飛躍的に面倒になる予感がしたので全種類同じ色で(とりあえずは)作ることに。
 結局、全マス走査して特定の内容だったら対応する表示をするだけ・・なんだ簡単じゃないか?


-> Resultの<>内が()なのはなぜか?って疑問から<_>ってのもあったよなぁ?と思い出して質問。<_>だと推論して決めてくれるらしい。それでエエやん!あ、他者が読むとき困るのか?

 まあ、慣れてきて大量に書かないといけなくなってきたら活用するかな〜

 ということでテトリスモドキ版のDisplay関数が(多分)完成した

 いろんなエラーが出るので、今テストに不要な部分は全部コメントアウトして、Cellsを表示してみる・・さてどうなるか?

 おお!表示された!これが出来たら、後はCellsを更新すれば常に最新の状態に更新し続けられるというわけだな。

 が・・

 これ・・SSだと分かりませんけど、猛烈な勢いでちらついてるんですよね・・カーソルが異様な速さで移動してるのが知覚出来ると言うか。確か迷路ゲームの時にはこんな事なかったのだが・・おそらくは
・全部書き上がった時点でバッファから呼び出す仕組みがあったはず?
・もしかして変化のある部分だけ書き換えるような仕組みになってたのかも?

 明日はこれを調査しよう
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

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

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