Javaプログラミング基礎

夏休みの課題

夏休みの課題

前期の「プログラミング入門」に引き続き、 後期の「プログラミング基礎」に向けて夏休みの課題を出題する。 この課題の提出内容は、後期の「プログラミング基礎」の成績に反映されることとなる。

解答は

に提出しなさい。ソースファイル (〜.java) のみを提出。 提出は gFTP 等の ftp ソフトを用いて行うこと。

なお、この課題は過年度対応科目「コンピュータ基礎および演習II」の履修者も対象となる。 「コンピュータ基礎および演習II」の履修者で 自分の学籍番号の提出フォルダの無い人は、 9/18(木)の授業で対応するので申し出ること。

提出期限: 9月24日(水曜日) 13:10

課題の概要

パラパラマンガ風にアニメーションを行うプログラムを考えてみよう。

アニメーションのようなものは、本来グラフィック表示する方法が適しているが、 今回はまだ学んでいないので、文字を組み合わせて表示するもので我慢する。

ここでは、次のような方針でアニメーションを行うことを考える。

アニメーションは複数のコマからなっている。 (国内の通常のテレビの規格 (NTSC) では1秒間に約30コマ) 1コマごとに画面の消去とシーンの描画を繰り返し行う。 これを高速に繰り返せば、アニメーションのように見えるはずである。

プログラムの中では、 アニメーションの1コマ1コマの処理を、繰り返しの処理と考えると 次のような考え方でアニメーションを行うことができる。

while (無限の繰り返し) {
    アニメーションに必要な座標などの計算

    画面の消去

    アニメーションの1コマの表示
}

そして、これをJavaで書くと、 おおよそ次のような枠組みのプログラムでアニメーションを行うことができる。

注意: 実行中のプログラムを終了するためには、 Ctrl+C (Ctrlキーを押しながら「C」を押す) を押す。 Emacs の shell モードでは表示が乱れることがあるので、 通常の端末エミュレータ (ターミナルエミュレータ) で実行すること。

while(true) {

    //アニメーションに必要な座標などの計算
    ......
    ......

    // 画面を消去するおまじない
    System.out.print("\u001b[H\u001b[2J");

    // アニメーションの1コマの表示
    ......
    ......

    // 時間稼ぎ (0.2秒) をするためのおまじない
    try {
	Thread.sleep(200);
    }
    catch(Exception e) {
    }
}

以下の例題1〜3のプログラムを読み実行してアニメーションの原理を理解したあと、 さらにその後に示す「夏休みの課題」を行い提出しなさい。

例題

例題1: 1から10まで順番にアニメーション風に表示する

1から10までの数字をアニメーション的に順番に表示する プログラムを考えよう。

[ ダウンロードして実行してみよう ]

/*
  1 から 10 までの数字を表示するようなアニメーションを行うプログラム
 */

class OneToTenAnimation {
    public static void main (String[] args) {
	// 1 から 10 までを数える変数
	int x = 0;

	while(true) {

	    // 1コマごとにxを1ずつ増やす
	    x = x + 1;

	    // 10を越えたら繰り返しを終了する
	    if (x > 10) {
		break;
	    }

	    // 画面をクリアするおまじない
	    System.out.print("\u001b[H\u001b[2J");

	    // 数字を表示する
	    System.out.println(x);

	    // 時間稼ぎ (0.2秒) をするためのおまじない
	    try {
		Thread.sleep(200);
	    }
	    catch(Exception e) {
	    }
	}
    }
}

例題2: ボール「o」を左から右へ移動するアニメーション

次に、ボール「o」を左から右へ移動するようなアニメーションを考えてみよう。 この場合ボール「o」の位置を表す変数 x を用意し、 アニメーションの1コマごとにこの変数の値を変化させる。

ボール「o」を表示する際には、 x の値ぶんの空白を表示しその次に o を表示すれば良い。

[ ダウンロードして実行してみよう ]

/*
  o→ ..... o
  のようなアニメーションを行うプログラム
*/

class BallSlider {
    public static void main (String[] args) {
	// 「o」の位置を表す変数
	int x = 0;

	while(true) {

	    // 1コマごとに「o」の位置を右に移動
	    x = x + 1;

	    // 7つ進んだら繰り返しを終了する
	    if (x > 7) {
		break;
	    }


	    // 画面をクリアするおまじない
	    System.out.print("\u001b[H\u001b[2J");

	    // 変数xのぶんだけ空白を表示し、次に「o」を表示する
	    for(int i = 0; i < x; i++) {
		System.out.print(" ");
	    }
	    System.out.println("o");

	    // 時間稼ぎ (0.2秒) をするためのおまじない
	    try {
		Thread.sleep(200);
	    }
	    catch(Exception e) {
	    }

	}
    }
}

例題3: ボール「o」が往復するアニメーション

ボール「o」が左右に行ったり来たりするアニメーションを考えてみよう。

この場合、ボールの位置を表す変数 x の他に、 ボールの進む方向を表す変数 direction が必要になる。 ボールを移動させていき、端まで来たら逆の方向に進むようにする。

[ ダウンロードして実行してみよう ]

/*
  o→ ..... o
  o ..... ←o
  のようなアニメーションを繰り返すプログラム
*/

class KnightRider {
    public static void main (String[] args) {
	// 「o」の位置を表す変数
	int x = 0;

	// 進む方向を表す変数 (1: 右, -1: 左)
	int direction = 1;

	while(true) {

	    // 進む方向によって「o」の位置を移動
	    if (direction == 1)
		x = x + 1;
	    else
		x = x - 1;

	    // 左端に着いたら進む方向を右に
	    if (x < 0) {
		x = 0;
		direction = 1;
	    }
	    // 右端に着いたら進む方向を左に
	    if (x > 7) {
		x = 7;
		direction = -1;
	    }


	    // 画面をクリアするおまじない
	    System.out.print("\u001b[H\u001b[2J");

	    // 「o」を表示する
	    for(int i = 0; i < x; i++) {
		System.out.print(" ");
	    }
	    System.out.println("o");

	    // 時間稼ぎ (0.2秒) をするためのおまじない
	    try {
		Thread.sleep(200);
	    }
	    catch(Exception e) {
	    }
	}
    }
}

夏休みの課題

ビリヤードのように2次元平面上をボールが転がっていき、 端までいったら跳ね返るようなアニメーションを行うプログラムを考える。

基本的なアニメーションを行う ひな型のプログラムは以下の通りである。 今回の課題ではこのプログラムを元に機能拡張を行うことになる。

[ ダウンロードして実行してみよう ]

class MyBall {
    public static void main (String[] args) {
	// 枠のサイズの指定
	int width = 46;
	int height = 20;
	
	// ボールの座標
	int x = 0;
	int y = 0;
	
	// ボールの速度 (x方向とy方向)
	int vx = 1;
	int vy = 1;
	
	// ボールの移動をくり返し続ける (プログラムを止めるにはCtrl+Cを押す)
	while(true) {
	    
	    // 移動を行った結果が枠外に、はみでていれば
            // 進む方向を逆にする (速度の正負を反転させる)
	    if (x + vx < 0 || x + vx > width)
		vx = -vx;

	    // ボールを移動
	    x = x + vx;
	    
	    // 移動を行った結果が枠外に、はみでていれば
            // 進む方向を逆にする (速度の正負を反転させる)
	    if (y + vy < 0 || y + vy > height) 
		vy = -vy;
	    
	    // ボールを移動
	    y = y + vy;

	    // 画面をクリアするおまじない
	    System.out.print("\u001b[H\u001b[2J");
	    
	    // 枠を書き、ボールを表示する
	    for (int i = 0; i <= width+2; i++)
		System.out.print("-");
	    System.out.println();
	    for (int i = 0; i <= height; i++) {
		System.out.print("|");		
		for(int j = 0; j <= width; j++) {
		    // 座標 i,j の位置にボールがあるならば o を表示、
		    // なければ空白を表示
		    if (i == y && j == x)
			System.out.print("o");
		    else
			System.out.print(" ");
		}
		System.out.print("|");		
		System.out.println();		
	    }
	    for (int i = 0; i <= width+2; i++)
		System.out.print("-");
	    System.out.println();
	    
	    // 時間稼ぎ (0.2秒) をするためのおまじない
	    try {
		Thread.sleep(200);
	    }
	    catch(Exception e) {
	    }
	}
    }
}

課題1

ひな型のプログラムを機能拡張し、ボールを示す文字「o」を、 ボールの進む向きによって変化するようにしなさい。

右方向に進んでいるときには「<」が、 左方向に進んでいるときには「>」が表示されるようにしなさい。

プログラム名は FlippingBall とする。

課題2

ひな型のプログラムを元に、 各自で考えた追加機能を1つ以上 (複数可) 実現しなさい。 追加機能は各自で自由に考えるものとするが、 例えば、次のような機能のなかから選択することなどが考えられる。

実現した機能の数や実現できた難易度によって評価されるので、 各自工夫を凝らしてがんばって欲しい。

アニメーションに変化をつける (難易度: ★)

ボールの運動に変化をつける (難易度: ★★)

ボールを2つにする (難易度: ★★★)

ボールが消える判定を行う (難易度: ★★★〜★★★★)

ボールを複数にする (難易度: ★★★★)

ボールを跳ね返る条件を増やす (難易度: ★★★★★)

プログラム名は MyBall とする。

提出物は以下のとおり:

  1. プログラムのソースファイル (ファイル名: MyBall.java)
  2. プログラムの説明 (テキスト形式の文章, 200字程度) (ファイル名: MyBall.txt)