SVX日記
2022-06-04(Sat) タイヤがシュー…っとな!?
先日、ハードな場所を走りまくったからパンクしたのか? 無理もない……と思ったが、よく見るとクランプインバルブのゴムパッキン部分に亀裂が入っている。バルブを指で揺らすとシューシューいう。
面倒なことになったなぁ、運が悪い……とは思ったが、考えてみれば、問題なく家に帰ってこられてるわけだし、高価なタイヤの交換までは必要なさそうだし、50kPa以下には落ちないようでタイヤの変形ダメージは少ないだろうし、たまにはクルマの世話したいと思っていたし……むしろ非常に運が良かったのかもしれない。
自分でタイヤを交換した時に、ナットを締めすぎたのが原因かなぁ。いや、それはわかっていたのだから十分に気をつけたよなぁ。そもそも、既に4,000kmくらい走ってて問題なかったんだからなぁ。まぁ、考えても仕方ないか。また、ピットを予約して、自分で修理することにしよう。とりあえず、替えのパッキンを注文する。4セットもいらないけれど。
2022-06-21(Tue) オレの横シュー「スケルティウス」一応の完成
自分の興味はプログラミング、特にコードにあるので、とりあえずは「横シュー」というシステムを限りなく美しく記述することが一番の目的になる。だから、長らく構想していた横シューのタイトルは「グラッス」だった。グラディウスっぽく始まって何機か敵機が飛んできたと思ったら、閉じつつあるシャッターが現れて、そこを抜けると、中にデカい脳ミソがある、みたいな、最初と最後しかない「グラディウス」。だから「グラッス」。当然ながら、不本意な言語では書きたくない。その意味で、Coffee Scriptは悪くない。ブラウザで動くから、誰にでも気軽に遊んでもらえるし。
しかし、コードを書いてみると、いろいろと気付かされるものだ。それは、コードに関してよりも、それ以外の部分の重要性。グラフィックは割と適当に描いてもそれっぽく見えたり、そうでもなかったり、適当に描くだけでも結構な労力だったり。プレイヤを殺しにかかろうとステージを設定することなんか、簡単なんだなと思ったり。R-TYPEの1面なんかは異常なほどユルく作ってあったんだな、とか。
自分で言うものなんだが、今回書いたコードは、1980年台のオーソドックスなシューティングを実現するためのパーフェクトな骨組みである。だから名前も「SKELTIUS」だ。パターンチップを並べてスクロールする地形を表現するBG(バックグラウンド)や、重ね合わせ表示可能なオブジェクト(スプライト)、64方向への直線移動や、当たり判定も汎用的に扱えるようになっている。後は、敵機やボスの行動ロジックを書いたり、ステージの仕掛けを作ったり、グラフィックを描いたりすれば、あっという間にオリジナル横シューができあがる(あー、サウンド関係だけはまだだけど……)。
というわけで、誰かに面白い横シューを作ってもらいたいと思いつつ、自分でも作ってみたいとも思っている。まずは、先日のテトランを実装しなおしてみたいな。それと、なんかこう、宇宙戦艦のブリッジで艦長に頬を張られたところで…<以下略>。
2022-06-24(Fri) テトラン登場
と、いうわけで、試験的にテトランを実装してみた。
本体を定義するTetranクラス、1本の腕を定義するTetranArmクラス、腕の1関節を定義するTetranBoneクラスを記述して、Stageクラスに登場タイミングを追記するだけ。なんだか、これまでの人生でコードを書いた中でも最高クラスの楽しさだったな。
ただ、既存のキャラクタ移動用の三角関数テーブルを流用したら、ちょっと動きがぎこちない。何せ360/64度キザみだからな。4倍にして360/256度にしないと、滑らかな動きは期待できないかも。まぁ、でも、アルゴリズムは完璧に記述できているので、別に焦りはない。
それより、現状、残機のパターンを流用しているが、腕のパターンをなんとかしないといけない。角度毎に16か32パターンくらいは必要だろう。そうなると、いちいち手で描いていられない。もちろん、GIMPで作るのもよろしくない。
2022-06-26(Sun) トラディショナルな回転、拡大、縮小技術を再現
と、いうわけで、試験的に回転、拡大、縮小機能を再現してみた。「三角関数が必要なのは最初だけ、後は加算だけで処理できる」というようなコメントの記憶をもとに、コードを書いた。たぶん、その意図に沿っている。実際、ループの中は異常にシンプル。最初に算出した「斜め方向」に沿ってピクセルを拾っていくだけ。回転って、こんなに簡単だったんだ。そりゃ、ハードウェアで実装もできるはずだ。
def sclnrot(win, x0, y0, w, h, v, t = 0, dx = 0, dy = 0)
rxys = Vec.v2vxy(v, t); hxys = Vec.v2vxy(v + 32 & 0x3F, t); vxys = Vec.v2vxy(v + 48 & 0x3F, t)
_vx8 = dx * rxys[1] - dy * rxys[0] - (dx << 8)
_vy8 = -(dx * rxys[0] + dy * rxys[1]) - (dy << 8)
h.times {|y|
_hx8 = _vx8; _hy8 = _vy8
w.times {|x|
_hx8 += hxys[0]; _hy8 += hxys[1] # 横方向加算
c = LegacyGraphics.point(_hx8 >> 8, _hy8 >> 8)
win.pset(x0 + x, y0 + y, [c.red / 65536.0, c.green / 65536.0, c.blue / 65536.0])
}
_vx8 += vxys[0]; _vy8 += vxys[1] # 縦方向加算
}
end
v = 0
(0...4).each {|y|
16.times {|x|
sclnrot(win, x * 64, y * 64, 64, 64, v); v += 1
}
}
v = 0
(4...8).each {|y|
16.times {|x|
sclnrot(win, x * 64, y * 64, 64, 64, v, 0, -32, -32); v += 1
}
}
2022-06-27(Mon) テトラン完了
と、いうわけで、回転機能を使ってテトランの腕をレンダリングし、実装してみた。
腕の動きは360/64度キザみで再現した結果、だいぶガタついているのだが、回転パターンは360/16度キザみで十分だろう、との判断で実装してみた。そう。回転パターンはリアルタイムレンダではなく、プリレンダである。しかし、想定のとおり360/16度キザみで十分であった。
人間の目は、明るさには敏感だが、色調には鈍感である。YUV記録方式ではこの特性を利用し、情報量を低減している。これと同じく、人間の目は、動きには敏感だが、絵柄には鈍感なのではないか。動体視力、とかいう概念もあるしな。結局、人間は動いているものは、それほどよくは見えていないのだ。発見だなぁ。
そして、さらに発見。原作のグラディウスIIIのテトランをしげしげと見ていたら、腕の光のハイライトが逆になっている状況が散見される(わかる?)。これは、グラディウスIIのテトランも同じであった。最初はパターンをケチっているせいかと思ったが、逆のパターンも表示されているので、そういう理由ではなさそう。
自分が再現したものは、光のハイライトの方向は合わせてある。まぁ、光源を想定するならば、それもホントはおかしいのだが、それをおかしいというのなら原作もおかしいことになる。結局、理由はよくわからない。しかし、ゲームの場合、絵はだいぶいい加減でも気づかないものなのだ、ということはわかった。