Newer
Older
Ruby / mygame / test5log.rb
#!/usr/bin/ruby
# coding: utf-8
require 'dxopal'
include DXOpal


# 箱のサイズ
BOX_WIDTH = 600
BOX_HEIGHT = 420
# 定数
R = 8.31
NA = 6.02e23
T = 300
E = 1.00e-3
A = 0.5e-6
Z = 6*3.14159*E*A
DT = 1e-7
M = 1.00e-15
DX = 1.00e-10
class BoxMuller
  def initialize(mu, sigma)
    @mu = mu
    @sigma = sigma
    @r = Random.new
    @z2 = nil
  end

  def rand
    if @z2
      z1 = @z2
      @z2 = nil
    else
      x = @r.rand
      y = @r.rand
      z1 = Math.sqrt(-2.0 * Math.log(x)) * Math.sin(2 * Math::PI * y)
      @z2 = Math.sqrt(-2.0 * Math.log(x)) * Math.cos(2 * Math::PI * y)
    end
    @sigma * z1 + @mu
  end
end


# 円を描いて塗りつぶすためのクラスを追加(Imageクラスの継承)
# r:半径, color:塗りつぶす色
class CircleImage < Image
  def initialize(r, color)
    # 透過に使う色
    acolor = C_BLACK
    
    super(2 * r, 2 * r, acolor)
    self.set_color_key(acolor)
    self.circle_fill(r, r, r, color)
    #self.box_fill(0,0,r,r,color)
  end
end
class Items
   N = 3
  def initialize

    @items = []
    @player = Circle.new(250,200,20,C_YELLOW)
    @px = []
    @py = []
    
    N.times do
    # 円の初期位置(ランダム)
      x = rand(BOX_WIDTH-10)
      y = rand(BOX_HEIGHT-10)
    
    # 円の初期速度(ランダム)
      vx = 0
      vy = 0
      @items.push(Circle.new(x, y, 50,C_CYAN))
    end
  end
  def update
    Sprite.check(@player,@items)
    Sprite.update([@player])
    # Sprite.update(@items)
    if @px.length >= 500
      @px.shift
      @py.shift
    end
    @px.push(@player.cx)
    @py.push(@player.cy)
  end
  def draw
    Sprite.draw(@items)
    Sprite.draw([@player])
    (1..(@px.length-1)).each do |i|
      Window.draw_line(@px[i],@py[i],@px[i-1],@py[i-1],C_GREEN)
    end
  end
  def r2
    return ((@px[-1] -@px[0])**2+(@py[-1] -@py[0])**2)*DX**2
  end
end
# 円のクラスを追加(Spriteクラスの継承)
# x:x座標, y:y座標, r:半径, vx:x方向の速度, vy:y方向の速度, color:塗りつぶす色
class Circle < Sprite
  def initialize(x, y, r, color)
    @r = r
    @bm = BoxMuller.new(0,Math.sqrt(2*Z*R*T/(M**2*NA*DT)))
    @vx = 0
    @vy = 0
    super(x, y, CircleImage.new(@r, color))
    self.collision = [r, r, r]
  end

  # 円の中心のx座標
  def cx
    return self.x + @r
  end

  # 円の中心のy座標
  def cy
    return self.y + @r
  end

  def update
    px = @bm.rand
    py = @bm.rand
    @vx += (-Z/M*@vx+px)*DT
    @vy += (-Z/M*@vy+py)*DT
    # 速度分だけ移動
    self.x += @vx/DX*DT
    self.y += @vy/DX*DT
    # 壁で跳ね返らせるため速度を反転
    if (self.cx - @r < 0 || self.cx + @r > BOX_WIDTH)
      self.x -= @vx/DX*DT
      @vx = -@vx
    end
    if (self.cy - @r < 0 || self.cy + @r > BOX_HEIGHT)
      self.y -= @vy/DX*DT
      @vy = -@vy
    end
  end
  def speed(vx,vy)
    @vx = 100
    @vy = 100
    
  end
end
Window.load_resources do
  # フレームレート(デフォルトは60)
  Window.fps = 100
  items = Items.new
  maxstep = 180
  step = maxstep
  r2 = []
  Window.loop do
    if step > 0
    # 移動
    items.update
    step -= 1
    else
      r2.push(items.r2)
      printf("%d,%g",r2.length,r2.sum/r2.length)
      items = Items.new
      step = maxstep
    end
    # 描画
    Window.draw_box_fill(0, 0, BOX_WIDTH, BOX_HEIGHT, [200, 200, 200])
    items.draw
   # Window.draw_font(100, 100, items.r2,Font.default)
   # print items.r2.round(6)

  end
end