Enemyのフレーム処理案
作者はEnemy.frameをオーバーライドするとして、書き換えて欲しくない部分はEnemy._frameに定義した上で、_frame()からframe()を呼び出すようにすれば安全なような気がする。
>>> import time; >>> class Enemy: ... def __init__(self): ... self.f = 0 ... ... def fire(self): ... print "%02d) Fire!" % self.f ... ... def _frame(self): ... self.frame() ... self.f += 1 ... >>> class SampleEnemy(Enemy): ... def __init__(self): ... Enemy.__init__(self) ... ... def frame(self): ... if self.f % 10 == 0: ... self.fire() ... >>> e = SampleEnemy() >>> e <__main__.SampleEnemy instance at 0x9a990> >>> while True: ... e._frame() ... time.sleep(0.1) ... 00) Fire! 10) Fire! 20) Fire!
実際のコードではwhile節の部分がメインループになる。メインループ内で呼び出すのは_frame()であってframe()ではない。frame()は_frame()から呼び出される。
_frame()にフレーム数を保持するfのインクリメントを委ねたことで、作者がオーバーライドするframe()では単純に「あるフレームで何をするか」さえ記述すれば良いことになる。単純なself.f+=1のし忘れミスを防げる。
また、本格的な考察はまだだが、Enemyの動作はタートルグラフィックスのように「10フレームかけて速度3で右に移動し、弾を撃って、左に5フレームかけて…」という形式でも規定できるようにしたい。
んで、それとこいつを併用すれば、例えば「弾の発射はframe()で、移動はturtle()で」みたいな分業で綺麗に書けるかもしれない。
上のコードでは_frame()はframe()だけを呼び出しているが、例えばturtle()の指定に従って動作を規定される_defined_by_turtle()も同じ_frame()で呼び出すようにするとか。