多関節キャラ2
マウスのほうを向くようにして、オマケで角度に乱数を導入してみたらなんかすごく気持ち悪い動きになったので置いておく。
#!ruby -Ks require 'dxruby' class Parts < Sprite attr_accessor :prev, :joint_xp, :joint_yp, :joint_xn, :joint_yn, :joint_angle attr_reader :next def initialize super @next = nil @joint_xp = @joint_yp = @joint_xn = @joint_yn = @joint_angle = 0 end def next=(n) @next = n n.prev = self end # ベースパーツは引数省略で呼ばれる。接続パーツのupdateを呼ぶ。 def update(jx = nil, jy = nil, angle = 0) if jx @joint_angle += rand() * 1.2 - 0.6 self.angle = @joint_angle + angle self.x = -@joint_xp + jx self.y = -@joint_yp + jy self.center_x = @joint_xp self.center_y = @joint_yp if @next jnx = (-@joint_xp + @joint_xn) * Math.cos(Math::PI * self.angle / 180) - (-@joint_yp + @joint_yn) * Math.sin(Math::PI * self.angle / 180) + jx jny = (-@joint_xp + @joint_xn) * Math.sin(Math::PI * self.angle / 180) + (-@joint_yp + @joint_yn) * Math.cos(Math::PI * self.angle / 180) + jy @next.update(jnx, jny, self.angle) end else if @next jnx = (@joint_xn - self.image.width / 2) * Math.cos(Math::PI * self.angle / 180) - (@joint_yn - self.image.height / 2) * Math.sin(Math::PI * self.angle / 180) + self.x + self.image.width / 2 jny = (@joint_xn - self.image.width / 2) * Math.sin(Math::PI * self.angle / 180) + (@joint_yn - self.image.height / 2) * Math.cos(Math::PI * self.angle / 180) + self.y + self.image.height / 2 @next.update(jnx, jny, self.angle) end end end def draw super @next.draw if @next end def guide mx,my = Input.mouse_pos_x, Input.mouse_pos_y x = (@joint_xn - @joint_xp) * Math.cos(Math::PI * self.angle / 180) - (@joint_yn - @joint_yp) * Math.sin(Math::PI * self.angle / 180) + self.x + @joint_xp y = (@joint_xn - @joint_xp) * Math.sin(Math::PI * self.angle / 180) + (@joint_yn - @joint_yp) * Math.cos(Math::PI * self.angle / 180) + self.y + @joint_yp mangle = Math.atan2(my - y, mx - x) / Math::PI * 180 +90 angle = (mangle + (180 - (self.angle % 360))) % 360 if 180 < angle @joint_angle = @joint_angle + 1 if @joint_angle > 30 @joint_angle = 30 @prev.guide if @prev end elsif 180 > angle @joint_angle = @joint_angle - 1 if @joint_angle < -30 @joint_angle = -30 @prev.guide if @prev end end end end # ベースパーツ pb = Parts.new pb.image = Image.new(60,60).circle_fill(30,30,30,[255,255,255]) pb.joint_xn = 30 # 次のパーツへの接続x pb.joint_yn = 10 # 次のパーツへの接続y pb.x = 300 pb.y = 300 p = pb parts = [[255,0,0], [0,255,0], [0,0,255], [0,255,255], [255,0,255], [255,255,0]].map do |color| p = p.next = Parts.new # nextに次のパーツオブジェクトを入れる p.image = Image.new(60,60).circle_fill(30,30,30,color) p.joint_xp = 30 # 前のパーツからの接続x p.joint_yp = 50 # 前のパーツからの接続y p.joint_xn = 30 # 次のパーツへの接続x p.joint_yn = 10 # 次のパーツへの接続y p end Window.loop do parts[5].guide pb.update pb.draw end