プログラミング実習I : 課題 R11

目次

目標

  • 教科書の 9 章の内容を理解し,イベント処理に関する基礎知識を得る

R11_1

準備

  • 教科書 p.168 から p.178 までをよく読み,8 章の内容を理解する

課題

  • 以下の質問とその回答( 1 〜 3 行程度 )をレポートにまとめよ(プログラムの作成は行わなくてよい)
    1. イベント駆動型のプログラムとは何か?教科書の説明に従って答えよ.
    2. リスナーやイベントリスナーとは何か?教科書の説明に従って答えよ.
    3. 図 9.2 や図 9.3 のように赤波線が表示された時,どのように対処すればよいか? それぞれ答えよ.
    4. リスト 9.4 のプログラムに書かれた implements KeyListener の意味は何か? 教科書 p.172 のカラムの内容に基づいて答えよ.また,これを書くことによって Car クラスに,どのようなことをしなければならなくなったか?
    5. keyPressed イベントと keyTyped イベントの違いは何か? 教科書 p.172 のカラムの説明に従って答えよ.
    6. Car クラスのオブジェクト car0 をキーリスナーに登録するにはどのようにしたら良いか?
    7. KeyEvent クラスの getKeyCode はどういう値を返すメソッドか? 教科書の説明に従って答えよ.

R11_2

準備

  • まず,R10_2 で作成した Car.java および Vehicle.java をコピーせよ
  • 次に,以下の内容を持つ PlayerAnimation.java を作成せよ
    • ※ リスト 9.6 とほぼ同じ内容だが,R10_2 の Car クラスを使用できるように変更している
public class PlayerAnimation extends MyFrame2 {

    public void run() {

        int x = 100;  // 自動車の中心 x 座標
        int y = 200;  // 自動車の中心 y 座標

        int cw = 32;  // 自動車の幅
        int ch = 24;  // 自動車の高さ

        Car player = new Car(x, y, cw, ch, 0, 0); // 止まった自動車の作成

        addKeyListener(player);

        while(true) {
            clear();
            player.draw(this);
            player.move();
            sleep(0.1);
        }
    }

    public static void main(String[] args) {
        new PlayerAnimation();
    }
}

課題

  • リスト 9.4,リスト 9.9 および リスト 9.10 を参考にして Car.java を修正し,Car クラスのオブジェクトを上下左右の矢印キーで動かせるようにせよ
    • ただし,上下の矢印キーに対するキーコード定数は以下である

      キー キーコード定数
      上矢印 KeyEvent.VK_UP
      下矢印 KeyEvent.VK_DOWN
  • PlayerAnimation クラスを実行し,以下の図のように,自動車を上下左右の矢印キーで操作できることを確認せよ
    • ※ 図 1 では,どの矢印キーが押されているかを表示しているが,そのように PlayerAnimation クラスを変更する必要はない
    • 実行例

      R11_2.gif

      図1: R11_2 で作成するプログラムで表示されるウィンドウの例

提出物

  • 作成した Car.java
  • 使用した Vehicle.java
  • 作成した PlayerAnimation.java

R11_3

準備

  • R11_2 で作成もしくは使用した以下をコピーせよ
    • Car.java
    • Vehicle.java
    • PlayerAnimation.java
  • R6_3 で作成した fillCircleWithCC メソッドを PlayerAnimation クラスにコピー&ペーストせよ

課題

  • R11_2 で使用した PlayerAnimation クラス の run メソッドを修正し,図 2 のように,自動車を移動させて円を集めるプログラム(PlayerAnimation.java) を作成せよ
    • 2 には,集めた円の数 nc を表示している
    • 以下の 条件 を満たすように作成すること
    • 実行例

      R11_3.gif

      図2: R11_3 で作成するプログラムで表示されるウィンドウの例

条件

  • 自動車(Car クラスのオブジェクト)に関して,以下とすること
    • 中心座標の初期値を (50, 50) とすること
    • 幅と高さは (32, 24) とすること
    • 中心座標の変化量の初期値を (0, 0) とすること
    • 自動車の色は黒とすること
  • 円に関して以下とすること
    • 円の半径を 10 とすること
    • プログラムが開始した際に,以下の四角形内に中心座標が存在する円をランダムに作成すること
      • 左上座標 (50, 50) で,幅と高さがともに 300 である四角形
        • ※ 確認しやすいように,この四角形も描画すること(色は好きな色でよい)
        • ※ n は学籍番号を 5 で割った余り
    • 円の中心座標と自動車の中心座標の距離が半径 r 以下となったら,上記の四角形内のランダムな位置に円を移動させること
      • 参考: 以下の不等式が満される場合,座標 \((x_0, y_0)\) と 座標 \((x_1, y_1)\) の距離が \(r\) 以下である

        \begin{align} (x_0 - x_1)^2 + (y_0 - y_1)^2 \le r^2 \end{align}
    • 円の色は赤とすること
  • 集めた円の数 nc を表示させること

提出物

  • 使用した Car.java
  • 使用した Vehicle.java
  • 作成した PlayerAnimation.java

R11_4

準備

  • 以下の内容を持つ Circle.java を作成せよ

    public class Circle {
        int cx;   // 円の中心 x 座標
        int cy;   // 円の中心 y 座標
        int r;   // 円の半径
        int c;   // 円の色
    
        /** コンストラクタ */
        public Circle(int cx, int cy, int r, int c) {
            this.cx = cx;
            this.cy = cy;
            this.r = r;
            this.c = c;
        }
    
        /** 中心座標 (cx, cy) および半径 r の円を描画(色を整数 c = 0, 1, 2で指定)  */
        public void draw(MyFrame2 frame) {
    
            // TODO: (その1) R6_3 で作成した fillCircleWithCC メソッドをベースに円の描画を行う
    
    
        }
    
        /** main メソッド(Circle メソッドのテストコード)*/
        public static void main(String[] args) {
    
            MyFrame2 f = new MyFrame2();
    
            Circle[] cs = new Circle[3];
            for(int i = 0; i < cs.length; i++) {
                int cx = 100*(i+1);
                int cy = 100*(i+1);
                int r =  10*(i+2);
                int c = i;
                cs[i] = new Circle(cx, cy, r, c);
                cs[i].draw(f);
                f.setColor(0, 0, 0);
                f.drawLine(cx, 0, cx, 400);
                f.drawLine(0, cy, 400, cy);
            }
        }
    }
    
    
  • 以下の内容を持つ ClickAnimation.java を作成せよ

    • 補足
      • "implements MouseListener" の意味
        • ClickAnimation クラスをマウスリスナー(クリックなどのマウスイベントに反応して動作するリスナー)にする
      • mouseClicked メソッド: マウスをクリックした際に実行されるメソッド
        • クリックした場所の xy 座標は,e.getX() および e.getY() で取得できる
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.Vector;
    
    public class ClickAnimation extends MyFrame2 implements MouseListener {
    
        public static void main(String[] args) {
            new ClickAnimation();
        }
    
        Circle circle; // 円(Circle クラスのオブジェクト)
    
    
        public void run() {
    
            circle = new Circle(200, 200, 10, 0); // 中心座標(200, 200) および半径 10 の円(赤)を作成
    
            addMouseListener(this); // 自身を MouseListener に登録
    
            while(true) {
                clear();
    
                // TODO: (その 2) 円(Circle クラスのオブジェクト circle)を描画
    
                sleep(0.1);
            }
    
        }
    
        /** マウスがクリックされた時に実行されるメソッド */
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
            int cx = e.getX();   // クリックされたウィンドウの x 座標を取得
            int cy = e.getY();   // クリックされたウィンドウの y 座標を取得
    
            int r = 10;  // 描画する円の半径
    
            // TODO: (その 3) 円(Circle クラスのオブジェクト circle)の中心座標をクリックされた座標に変更
    
    
        }
        @Override
        public void mousePressed(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseExited(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
    }
    

課題

  • 準備で作成した Circle.java にある TODO を埋めて,実行してみよ
    • TODO (その 1) : R6_3 で作成した fillCircleWithCC メソッドに基づいて Circle クラスの draw メソッドを完成させる
    • 特に問題がなければ,実行してみると,図 3 のようなウィンドウが表示される

      Circle.png

      図3: Circle.java の実行で表示されるウィンドウ

  • 準備で作成した ClickAnimation.java にある TODO を埋めて,以下の実行例のように,クリックした場所を中心に円を描画するプログラム(ClickAnimation.java) を作成せよ
    • ※ 作成するプログラムでは,円の中心座標(cx, cy) は表示させなくてよい
    • TODO (その 2)
      • 円(Circle クラスのオブジェクト circle) を描画
    • TODO (その 3)
      • 円(Circle クラスのオブジェクト circle) の中心座標をクリックした座標に変更
    • 実行例 (ループ再生)

提出物

  • 作成した Circle.java
  • 作成した ClickAnimation.java

R11_5

準備

  • R11_4 で作成した Circle.java をコピーする
  • R11_4 で作成した ClickAnimation.java を,以下の内容に変更せよ

    • R11_4 の準備のサンプルプログラムと「(★★)」の部分だけ異なる
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.Vector;
    
    public class ClickAnimation extends MyFrame2 implements MouseListener {
    
        public static void main(String[] args) {
            new ClickAnimation();
        }
    
        Vector<Circle> circles; // 円(Circle クラスのオブジェクト)を管理する Vector オブジェクト(★★)
    
        public void run() {
    
            circles = new Vector<Circle>(); // Vector オブジェクトの作成(★★)
    
            addMouseListener(this); // 自身を MouseListener に登録
    
            while(true) {
                clear();
    
                // TODO: (その 1) circles に格納された円(Circle クラスのオブジェクト)を全て描画(★★)
    
                sleep(0.1);
            }
    
        }
    
        /** マウスがクリックされた時に実行されるメソッド */
        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
            int cx = e.getX();   // クリックされたウィンドウの x 座標を取得
            int cy = e.getY();   // クリックされたウィンドウの y 座標を取得
    
            int r = 10;  // 描画する円の半径
    
            // TODO: (その 2) 半径 r および中心座標 (cx, cy) の円(Circle クラスのオブジェクト)を circles に追加(★★)
    
    
        }
        @Override
        public void mousePressed(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
        @Override
        public void mouseExited(MouseEvent e) {
            // TODO 自動生成されたメソッド・スタブ
    
        }
    }
    

課題

  • 準備で修正した ClickAnimation.java にある TODO を埋めて,以下の実行例のように,クリックした場所を中心に円を 追加で 描画するプログラム(ClickAnimation.java) を作成せよ
    • ※ 作成するプログラムでは,描画した円の数 nc は表示させなくてよい
    • TODO (その 1)
      • circles (Vector オブジェクト)に格納された円(Circle クラスのオブジェクト) を全て描画
    • TODO (その 2)
      • クリックした座標 (cx, cy) を中心座標とする円(Circle クラスのオブジェクト)を生成し,circles に追加
        • ただし
          • 円の半径は 10 とすること
          • 円の色は,赤 → 黄緑 → 青 → 赤 → … と周期的に変化させること
    • 実行例 (ループ再生)

提出物

  • 使用した Circle.java
  • 作成した ClickAnimation.java

R11_6 (オプション)

準備

  • R11_5 で使用した Circle.java をコピーする
  • R11_5 で作成した ClickAnimation.java をコピーし,TicTacToe.java に名前を変更する

課題

  • R11_5 で使用した Circle.java を修正し,白と黒の円が描画できるように修正せよ.
  • R9_4 で作成した三目並べのプログラム(TicTacToe.java) を参考に,以下の実行例のように,クリックした盤のマス目にコマを置いて遊べるプログラム(TicTacToe.java) を作成せよ
    • ただし,以下の 条件 を満たすように作成すること
    • 実行例 (ループ再生)

条件

  • 実行開始直後から 3×3の盤を表示させること
  • 盤のマス目がクリックされた時,そのマス目にまだコマが置かれてなければコマを置くこと
    • コマの色は,黒→白→黒→… と交互になること

提出物

  • 作成した Circle.java
  • 作成した TicTacToe.java

R11_7 (オプション)

課題

  • R11_6 のプログラム(TicTacToe.java) に,R9_5 で作成した三目並べの勝敗判定を行う機能を追加し,以下の実行例のように,三目並べを行って遊べるプログラム(TicTacToe.java) を作成せよ
    • ただし,以下の 条件 も満たすように作成せよ
      • R11_6 の条件との変更箇所を太字で示している
    • 実行例 (黒が勝つケース,ループ再生)

条件

  • 実行開始直後から 3×3の盤を表示させること
  • 盤のマス目がクリックされた時, 勝敗が決まってない,かつ, そのマス目にまだコマが置かれてなければコマを置くこと
    • コマの色は,黒→白→黒→… と交互になること
  • 勝敗が決まった際には,以下を表示させること
    • 黒が勝った場合 →「Black Wins!」 という表示を行う
    • 白が勝った場合 →「White Wins!」 という表示を行う

提出物

  • 使用した Circle.java
  • 作成した TicTacToe.java

R11_8 (オプション)

課題

  • R6_4R7_5 などで作成したプログラムを修正して,以下の実行例のように,一人ピンポンゲームを行うプログラム(PingPongGame.java) を作成せよ
    • ただし,少なくとも以下の 条件 を満たすように PingPongGame.java を作成すること
    • ※ 以下の実行例では,円の座標 (x, y) や,ブロックの x 座標の範囲 [tx0, tx1] を表示しているが,作成するプログラムでは表示させる必要はない
    • 実行例 (ループ再生)

条件

  • 四角形の下辺に接するブロックを描画すること
    • ブロックは,左右の矢印キーで移動できるようにすること
  • R6_4R7_5 などで作成したプログラムと同様に,円や四角形を描画すること
  • R6_4R7_5 などで作成したプログラムと同様に,円が四角形内を移動すること
    • ただし,四角形の下辺にぶつかった場合は,ブロックがある場合にのみ,円が跳ね返ったように移動させること
  • 円がウィンドウから消えた際には,円を四角形内のどこかに移動させること

提出物

  • PingPongGame.zip (※作成したプログラムファイル一式を zip ファイルにまとめたもの)

著者: Yusuke Sakumoto

Created: 2022-12-14 水 17:32

Validate