二足歩行させるメカを作ってみよう

メガドライブミニにガンスターヒーローズと魂斗羅が収録されることが決定しましたね。この二つは当時のハードながらも多関節キャラが動きまくって度肝を抜かれた記憶があります。
たまにこれらの技術の一部がわが心の師である元コ〇ミのmieki256さんのブログに書いてあったりするのですが、2足歩行する敵のRubyプログラムも公開してあるので、私も憧れの多関節を再現してみたいと思いました。

ただ、元のプログラムは16bitマシン風のアルゴリズムだったので、もうちょっとrubyの数学関数を駆使して短いコードになるようにしました。さらに余弦定理を使って角度を求めるようにしたので各関節の長さが異なるモデルにも対応できそうです。

require "dxopal"
include DXOpal

# 関節の座標を計算する
def joint_pos(x1, y1, x2, y2)
  f1, f2 = 70, 60 # 足の長さ
  dw = x2 - x1
  dh = y2 - y1
  d = Math.sqrt(dw*dw + dh*dh)
  a = Math.atan2(dh, dw) # 着地点までの角度
  cosa = (d*d + f1*f1 - f2*f2) / (2*d*f1) # 余弦定理
  s = a + Math.acos(cosa) # 角度
  return x1 + Math.cos(s) * f1, y1 + Math.sin(s) * f1
end

# 歩行する足
def foot(x1, y1, angle)
  x2 = 200 + Math.cos(angle) * 32
  y2 = 200 + [Math.sin(angle) * 32, 0].min  # 足先
  jx, jy = joint_pos(x1, y1, x2, y2)
  Window.draw_line(x1, y1, jx, jy, C_WHITE)
  Window.draw_line(x2, y2, jx, jy, C_WHITE)
end

angle = 0
x, y = 200, 100
Window.loop do
  Window.draw_line(0, 200, Window.width, 200, C_WHITE)
  angle -= 0.04
  foot(x, y, angle)
  foot(x, y, angle + Math::PI)
end
棒人間の下半身?

歩いているように見えるかな?腕を振る上半身も作れば走る棒人間とか作れるかもしれません。

逆関節メカも作れます。上手くデザインしてゲームに登場させたい。

基本的な概念が理解できれば色々と応用が利きそうな技術です。しかし行き着く先はインバースキネマティクスだったり物理エンジンだったりと車輪の再発明になるわけで最初からそっちを使う方が早いのかもしれません。
まあ自分でコードを書いて動かすという所が楽しいのですが。

0