プログラミング実習I : 課題 R11
目標
- 教科書の 9 章の内容を理解し,イベント処理に関する基礎知識を得る
R11_1
準備
- 教科書 p.168 から p.178 までをよく読み,8 章の内容を理解する
課題
- 以下の質問とその回答( 1 〜 3 行程度 )をレポートにまとめよ(プログラムの作成は行わなくてよい)
- イベント駆動型のプログラムとは何か?教科書の説明に従って答えよ.
- リスナーやイベントリスナーとは何か?教科書の説明に従って答えよ.
- 図 9.2 や図 9.3 のように赤波線が表示された時,どのように対処すればよいか? それぞれ答えよ.
- リスト 9.4 のプログラムに書かれた implements KeyListener の意味は何か? 教科書 p.172 のカラムの内容に基づいて答えよ.また,これを書くことによって Car クラスに,どのようなことをしなければならなくなったか?
- keyPressed イベントと keyTyped イベントの違いは何か? 教科書 p.172 のカラムの説明に従って答えよ.
- Car クラスのオブジェクト car0 をキーリスナーに登録するにはどのようにしたら良いか?
- 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 クラスを変更する必要はない
実行例
図1: R11_2 で作成するプログラムで表示されるウィンドウの例
提出物
- 作成した Car.java
- 使用した Vehicle.java
- 作成した PlayerAnimation.java
R11_3
準備
課題
条件
- 自動車(Car クラスのオブジェクト)に関して,以下とすること
- 中心座標の初期値を (50, 50) とすること
- 幅と高さは (32, 24) とすること
- 中心座標の変化量の初期値を (0, 0) とすること
- 自動車の色は黒とすること
- 円に関して以下とすること
- 円の半径を 10 とすること
- プログラムが開始した際に,以下の四角形内に中心座標が存在する円をランダムに作成すること
- 左上座標 (50, 50) で,幅と高さがともに 300 である四角形
- ※ 確認しやすいように,この四角形も描画すること(色は好きな色でよい)
- ※ n は学籍番号を 5 で割った余り
- 左上座標 (50, 50) で,幅と高さがともに 300 である四角形
- 円の中心座標と自動車の中心座標の距離が半径 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() で取得できる
- "implements MouseListener" の意味
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 を埋めて,実行してみよ
- 準備で作成した 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 とすること
- 円の色は,赤 → 黄緑 → 青 → 赤 → … と周期的に変化させること
- ただし
- クリックした座標 (cx, cy) を中心座標とする円(Circle クラスのオブジェクト)を生成し,circles に追加
実行例 (ループ再生)
提出物
- 使用した Circle.java
- 作成した ClickAnimation.java
R11_6 (オプション)
課題
条件
- 実行開始直後から 3×3の盤を表示させること
- 盤のマス目がクリックされた時,そのマス目にまだコマが置かれてなければコマを置くこと
- コマの色は,黒→白→黒→… と交互になること
提出物
- 作成した Circle.java
- 作成した TicTacToe.java
R11_7 (オプション)
課題
条件
- 実行開始直後から 3×3の盤を表示させること
- 盤のマス目がクリックされた時, 勝敗が決まってない,かつ, そのマス目にまだコマが置かれてなければコマを置くこと
- コマの色は,黒→白→黒→… と交互になること
- 勝敗が決まった際には,以下を表示させること
- 黒が勝った場合 →「Black Wins!」 という表示を行う
- 白が勝った場合 →「White Wins!」 という表示を行う
提出物
- 使用した Circle.java
- 作成した TicTacToe.java
R11_8 (オプション)
課題
条件
提出物
- PingPongGame.zip (※作成したプログラムファイル一式を zip ファイルにまとめたもの)