ここからはオブジェクト指向プログラミングを使って、アニメーションを作っていきたいと思います。
まず、下のプログラムを実行してみましょう。
1: /** 2: * タートルで書いた絵をまわすプログラム 3: * 4: * Yoshiaki Matsuzawa 5: * 2003/06/16 6: */ 7: public class RotateHouse extends Turtle { 8: 9: //起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new RotateHouse()); 12: } 13: 14: //タートルを動かす処理 15: public void start() { 16: 17: House house = new House(); //家を生成 18: 19: //アニメーションループ 20: while (true) { 21: 22: //待つ 23: sleep(0.1); //0.1秒 24: 25: //処理を行う 26: house.rt(5); 27: 28: //再描画する 29: update(); 30: } 31: 32: } 33: 34: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
ここでは、Houseのプログラムオブジェクトとして生成しています。 つまり、いままでタートルで作った絵を使うことができるのです。
タートルを使って自分の作ったオブジェクトを生成するには、次のような命令文を書きます。
例えば、RotateHouse.javaアニメーションで、House.javaを使う場合は、 その2つを同じフォルダに置く必要があります。
同じフォルダに置いていないとコンパイルエラーが出るので注意してください。
RotateHouse.javaをもう一度よく見てみましょう。 特に、
while(true){ //待つ //処理 //再描画 }
ここの部分が、今までと異なる所で、アニメーションをするプログラムの特徴です。 どのようなアニメーションをするプログラムでも基本構造は同じです。 図解すると下のようになります。
ちなみに、House.javaは次のようなプログラムでした。
1: /* 2: * 家を書くプログラム 3: * 2003/05/08 4: * Yoshiaki Matsuzawa 5: */ 6: public class House extends Turtle { 7: 8: //起動処理 9: public static void main(String[] args) { 10: Turtle.startTurtle(new House()); 11: } 12: 13: //タートルを動かす処理 14: public void start() { 15: 16: //屋根を書く 17: rt(30); //30度右を向く 18: fd(50); //50歩前に進む 19: rt(120); 20: fd(50); 21: rt(120); 22: fd(50); 23: 24: //本体を書く 25: lt(90); 26: fd(50); 27: lt(90); 28: fd(50); 29: lt(90); 30: fd(50); 31: lt(90); 32: fd(50); 33: 34: } 35: 36: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
sleep()命令の中の数字を小さくすることによって、アニメーションを早くすることができます。 しかし、コンピュータの能力にも限界があります。 軽いアニメーションならば0.01秒(秒間100コマ)ぐらいまでならなんとか動きますが、 画像などを使うといくら小さい値を入れても、コンピュータの計算が追いつかなくなります。
人間が目に分かるのは、秒間30コマまでといわれています(テレビがそれぐらいです)ので、 それぐらいを目安に数値を決めると良いでしょう。
オブジェクトになっても、基本的なタートルの命令はどれでも使うことができます。 次のプログラムは、円を描く家のプログラムです。
1: /** 2: * 家で円を描くプログラム 3: * 4: * Yoshiaki Matsuzawa 5: * 2003/06/16 6: */ 7: public class CircleHouse extends Turtle { 8: 9: //起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new CircleHouse()); 12: } 13: 14: //タートルを動かす処理 15: public void start() { 16: 17: House house = new House(); //家を生成 18: 19: //赤い軌跡を描く準備 20: house.color(java.awt.Color.red); 21: house.down(); 22: 23: //アニメーションループ 24: while (true) { 25: 26: //待つ 27: sleep(0.1); //0.1秒 28: 29: //処理を行う 30: house.rt(5); 31: house.fd(5); 32: 33: //再描画する 34: update(); 35: } 36: 37: } 38: 39: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
down() 命令で、ペンを下ろして軌跡が描かれるようになっています。
いままでのタートルでは、down()命令をしなくても、 最初はペンを下ろした状態から始まっていました。
しかし、アニメーションでは、軌跡は要らないことが多いので、 初期値がペンを上げた状態になっています。
プログラムを書くときには、"最初の状態"を意識する必要があります。 これを「初期値」や「デフォルト値」といいます。
次に示すのは、家が右に動いていくプログラムです。
1: /** 2: * 家を右に動かすプログラム 3: * 其の1 : 右に向けて動かす方法 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class MoveRightHouse1 extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new MoveRightHouse1()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: house.rt(90); //右に向ける 21: 22: //アニメーションループ 23: while (true) { 24: 25: //待つ 26: sleep(0.1); //0.1秒 27: 28: //処理を行う 29: house.fd(5); 30: 31: //再描画する 32: update(); 33: } 34: 35: } 36: 37: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
今までの方法では、前か後ろにしか進めませんが、 家は上向きのまま、右に動かしたい場合があります。
いままでの方法でも、下のように工夫することによって目的は達成できますが、 ここでは、warp命令を使ったエレガントな解決方法を考えます。
1: /** 2: * 家を右に動かすプログラム 3: * 其の2 : 上に向いたまま右に動かす 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class MoveRightHouse2 extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new MoveRightHouse2()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: //アニメーションループ 21: while (true) { 22: 23: //待つ 24: sleep(0.1); //0.1秒 25: 26: //処理を行う 27: house.rt(90); 28: house.fd(5); 29: house.lt(90); 30: 31: //再描画する 32: update(); 33: } 34: 35: } 36: 37: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
warp命令を使うと、回転せずに、好きな所にオブジェクトを移動することができます。
1: /** 2: * 4つの家をワープを使って配置するプログラム 3: * 4: * Yoshiaki Matsuzawa 5: * 2003/06/16 6: */ 7: public class WarpHouse extends Turtle { 8: 9: //起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new WarpHouse()); 12: } 13: 14: //タートルを動かす処理 15: public void start() { 16: 17: House house1 = new House(); //家1を生成 18: House house2 = new House(); //家2を生成 19: House house3 = new House(); //家3を生成 20: House house4 = new House(); //家4を生成 21: 22: //アニメーションループ 23: while (true) { 24: 25: // --- 待つ --- 26: sleep(0.1); //0.1秒 27: 28: // --- 処理を行う --- 29: house1.warp(100, 100); 30: house2.warp(100, 200); 31: house3.warp(200, 100); 32: house4.warp(200, 200); 33: 34: // --- 再描画する --- 35: update(); 36: } 37: 38: } 39: 40: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
このプログラムの実行結果は以下のようになります。
ちなみに、一般にコンピュータ環境では、数学とはちょっと違った座標体系が使われます。 タートルの場合もそうです。以下のようになっているので気をつけてください。
さあ、ワープを使って、家を右に移動しましょう。
1: /** 2: * 家を右に動かすプログラム 3: * 其の3 : 上に向いたまま右に動かす(ワープを使う) 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class MoveRightHouse3 extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new MoveRightHouse3()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: int x; //x座標を入れる変数 21: int y; //y座標を入れる変数 22: 23: //アニメーションループ 24: while (true) { 25: 26: //待つ 27: sleep(0.1); //0.1秒 28: 29: //処理を行う 30: x = house.getX(); //家のx座標を取得する 31: y = house.getY(); //家のy座標を取得する 32: house.warp(x + 5, y); //右に移動 33: 34: //再描画する 35: update(); 36: } 37: 38: } 39: 40: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
さらに、右端までいったら左端にワープするように改造します。
1: /** 2: * 家を右に動かすプログラム 3: * 其の4 : 右端に行ったら左端に戻す(ワープを使う) 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class MoveRightHouse4 extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new MoveRightHouse4()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: int x; //x座標を入れる変数 21: int y; //y座標を入れる変数 22: 23: //アニメーションループ 24: while (true) { 25: 26: // --- 待つ --- 27: sleep(0.1); //0.1秒 28: 29: // --- 処理を行う --- 30: x = house.getX(); //家のx座標を取得する 31: y = house.getY(); //家のy座標を取得する 32: 33: //右に移動 34: house.warp(x + 5, y); 35: 36: //右端だったら左端にワープ 37: if (x >= 300) { 38: house.warp(0, y); 39: } 40: 41: // --- 再描画する --- 42: update(); 43: } 44: 45: } 46: 47: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
だんだんアニメーションらしくなってきました。
オブジェクトは、大きさを変更することもできます。
1: /** 2: * 家を大きくするプログラム 3: * 其の1 : 大きさを測る 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class LargeHouse extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new LargeHouse()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: //アニメーションループ 21: while (true) { 22: 23: // --- 待つ --- 24: sleep(0.1); //0.1秒 25: 26: // --- 処理を行う --- 27: 28: //家を大きくする 29: house.size(200, 200); 30: 31: // --- 再描画する --- 32: update(); 33: } 34: 35: } 36: 37: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
アニメーションループをうまく利用すれば、徐々に大きくなっていくプログラムが書けます。
1: /** 2: * 家を大きくするプログラム 3: * 其の1 : 大きさを測る 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class LargerHouse extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new LargerHouse()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: int width; //width座標を入れる変数 21: int height; //height座標を入れる変数 22: 23: //アニメーションループ 24: while (true) { 25: 26: // --- 待つ --- 27: sleep(0.1); //0.1秒 28: 29: // --- 処理を行う --- 30: 31: width = house.getWidth(); //家の横の長さを取得する 32: height = house.getHeight(); //家の縦の長さを取得する 33: 34: //家を大きくする 35: house.size(width + 2, height + 2); 36: 37: // --- 再描画する --- 38: update(); 39: } 40: 41: } 42: 43: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
大きくなりすぎたら、小さく戻してあげましょう。
1: /** 2: * 家を大きくするプログラム 3: * 其の2 : 大きくなりすぎたら小さくする 4: * 5: * Yoshiaki Matsuzawa 6: * 2003/06/16 7: */ 8: public class LargerHouse2 extends Turtle { 9: 10: //起動処理 11: public static void main(String[] args) { 12: Turtle.startTurtle(new LargerHouse2()); 13: } 14: 15: //タートルを動かす処理 16: public void start() { 17: 18: House house = new House(); //家を生成 19: 20: int width; //width座標を入れる変数 21: int height; //height座標を入れる変数 22: 23: //アニメーションループ 24: while (true) { 25: 26: // --- 待つ --- 27: sleep(0.1); //0.1秒 28: 29: // --- 処理を行う --- 30: 31: width = house.getWidth(); //家の横の長さを取得する 32: height = house.getHeight(); //家の縦の長さを取得する 33: 34: //家を大きくする 35: house.size(width + 2, height + 2); 36: 37: //横幅が大きくなりすぎたら小さくする 38: if (width >= 300) { 39: house.scale(0.25); //0.25倍の大きさにする 40: } 41: //縦幅が大きくなりすぎたら小さくする 42: if (height >= 300) { 43: house.scale(0.25); //0.25倍の大きさにする 44: } 45: 46: // --- 再描画する --- 47: update(); 48: } 49: 50: } 51: 52: }
下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。
星を書くプログラム(Star.java)を使って、流れ星のプログラムを書いてみて下さい。
ダウンロードはこちらから
流れ星は、次の手順で進めていくとうまくできます。