2012年7月12日木曜日

[ドリトル] 回転するカメ


前回の記事で タイマーが使えるようになったので使ってみる。
自転しならが円を書く Turtle を作ってみよう。

プロトタイプとしてして作って、使うときにはなるべく自然に Turtle として使えるようにする。

基本戦略。
  • 自身で回転専用の Timer を保持し、一定の速度で自身を回転させる。
  • 実際に進む向きは、専用のプロパティとして保持する。
  • forward をオーバーライドして、実際に進む向きから自身の移動位置を算出する。
  • right/leftturn をオーバーライドして、実際に進む向きのプロパティ値の更新をする。
こんな感じ。create 時に回転速度を引数として与えるようにしてある。

SpinTurtle = Turtle!create.
SpinTurtle!hide.

// speed: rotate / sec. 
SpinTurtle:create = [ | speed  ; create | 
    obj = ! create.
    obj ! (speed) init.
    obj.
].

SpinTurtle:init = [ | speed | 
    self:rotateTimer = Timer ! create. 
    self:rotateTimer ! 0.05 interval ((1 / 0.05) * 300) times.
    self:rotateTimer ! [
        // use parent "leftturn" 
        | ; leftturn |
        ! (360 * speed / 20) leftturn.] execute.
    self:forwardAngle = 0.
    self ! show.
].

SpinTurtle:forward = [
    | step ; forward dx dy | 
    dx = step * cos( self:forwardAngle ).
    dy = step * sin( self:forwardAngle ).
    ! ( (!xposition?) + dx) ( (!yposition?) + dy) moveto. 
    self.
].

SpinTurtle:leftturn = [ | d |
    self:forwardAngle = (self:forwardAngle) + d.
    self.
].

SpinTurtle:rightturn = [ | d |
    self:forwardAngle = (self:forwardAngle) - d.
    self.
].

// -------- End of SpinTurtle definition. -----------

t1 = SpinTurtle! 1 create.
timer1 = Timer!create .
timer1 ! 0.05 interval 360 times.
timer1 ! [
  t1 ! 10 forward.
  t1 ! 5 leftturn.
] execute.

こんな感じで、カメ が勝手に自転しながら円を描く。



問題もあって、circle や polygon 命令など、自身の向きに関係する既存のメソッドも手を入れないといけない。
今は何もしていないので、このような命令を使うとどっち向きに描くかはタイミング次第になってしまう。

...
// -------- End of SpinTurtle definition. -----------

t1 = SpinTurtle! 1 create.
timer1 = Timer!create .
timer1 ! 0.7 interval 5 times.
timer1 ! [
  t1 ! 100 4 polygon.
] execute.
タイミングによって四角形を描く向きがバラバラで、しかも描いている途中で回転が入ってしまったので図形もずれてしまった。

まあ、良しとしよう。


0 件のコメント:

コメントを投稿