• 検索結果がありません。

Animals サンプル Step3 張り付けた動物の上をクリックすると それぞれの鳴き声で鳴く その鳴く間 一定時間 ( ここでは 1 秒間 ) 画像が別のものに変わる <アニメーションの基礎 : タイマーについて> アニメーションは アプリケーションが指定する間 一定間隔でどんどん画像をおきかえ

N/A
N/A
Protected

Academic year: 2021

シェア "Animals サンプル Step3 張り付けた動物の上をクリックすると それぞれの鳴き声で鳴く その鳴く間 一定時間 ( ここでは 1 秒間 ) 画像が別のものに変わる <アニメーションの基礎 : タイマーについて> アニメーションは アプリケーションが指定する間 一定間隔でどんどん画像をおきかえ"

Copied!
6
0
0

読み込み中.... (全文を見る)

全文

(1)

-1- 張り付けた動物の上をクリックすると、それぞれの鳴き声で鳴く。 その鳴く間、一定時間(ここでは1 秒間)画像が別のものに変わる <アニメーションの基礎:タイマーについて> アニメーションは、アプリケーションが指定する間、一定間隔でどんどん画像をおきかえていくもの である。 このサンプルでは、動物画像の上をクリックすると画像を切り替え、1 秒後、もとの画像に戻す操作を する。これは、1 秒間隔で2回の操作が必要となり、間隔も長いし操作回数が少ないが、ある意味アニメ ーションの一種となる。 Swingでアニメーションを簡単に実現するには、javax.swingパッケージのTimerクラスを使う。Timer によって一定間隔でイベントを発生させ、イベント処理をするメソッド(関数)に画像を描画しなおす 処理を記述すると、アニメーションになる。タイマーの作成方法は一般に以下のようになる。

Timer timer = new Timer(イベント発生間隔, アクションリスナ); timer.start(); // タイマーが発動する 具体的にはアクションイベント(ActionEvent)という種類のイベントが発生する。このイベントを処理 するのはアクションリスナ(ActionListener)というインターフェースを実装(implements)したクラスで、 必ずactionPerformed というメソッドをもつ。このメソッドにイベント処理の記述を行う。 <作成手順> 今回はMainPanel.java に必要な部分を書きたすだけでよい。

(2)

-2- 2 import java.awt.Graphics; 3 import java.awt.Graphics2D; 4 import java.awt.SystemColor; 5 import java.awt.event.ActionEvent; 6 import java.awt.event.ActionListener; 7 import java.awt.event.MouseEvent; 8 import java.awt.event.MouseListener; 9 import java.io.File; 10 import java.util.ArrayList; 11 import java.util.List; 12 13 import javax.sound.sampled.AudioFormat; 14 import javax.sound.sampled.AudioInputStream; 15 import javax.sound.sampled.AudioSystem; 16 import javax.sound.sampled.Clip; 17 import javax.sound.sampled.DataLine; 18 import javax.swing.ImageIcon; 19 import javax.swing.JOptionPane; 20 import javax.swing.JPanel; 21 import javax.swing.SwingUtilities; 22 import javax.swing.Timer; 23 24

public class MainPanel extends JPanel implements MouseListener, ActionListener{

25 26

private int animalType = 0; // 動物の種類

27

private Animal clickedAnimal = null; // クリックされた動物

28

private List<ImageIcon> images; // 動物の画像リスト

29

private List<ImageIcon> images2; // 画像2のリスト

30

private File[] audioFiles; // 音声ファイル

31

private List<Animal> animals; // 動物のリスト

32 33

private int imgWidth = 100; // 画像幅

34

private int imgHeight = 100; // 画像高さ

35 36

private int x,y; // クリックされた座標の一時保管用フィールド

37 38

private final String IMG = "img"; // 描画モードその1

39

private final String IMG2 = "img2"; // 描画モードその2

40

private String imgType = IMG; // 描画する画像の種類 int や boolean でも実装可能

41

private Timer timer;

42 43 /** 44 * コンストラクタ 45 */ 46 public MainPanel() { 47 super(); 48 // マウスイベントを受け取れるようにする 49 addMouseListener(this); 50 // 初期化 51 /* List は直接 new できず、リストの種類を指定する必要がある。 52

* 普通に使う List は ArrayList で new すれば問題ない。*/

53

images = new ArrayList<ImageIcon>();

54

images2 = new ArrayList<ImageIcon>();

55

animals = new ArrayList<Animal>();

56 // タイマー生成 new Timer(ミリ秒でイベント発生間隔, アクションリスナ) 57 /* 新たに ActionListener を implements したので 58 * 自分自身をアクションリスナとして登録できる */ 59

timer = new Timer(1000, this);

60 // タイマーが発動するまでの遅延時間を設定(ミリ秒) 61 timer.setInitialDelay(100); 62 } 63

(3)

-3- 64 /** 65 * ファイル数に応じて各インスタンスを初期化 66 * new したあと必ず呼ぶ 67 * @throws MyException 68 */ 69

public void init() throws MyException {

70 // img ディレクトリ、img2 ディレクトリを取得 71 /* File クラスはディレクトリを含むファイルの概念を表す 72 * 相対パスで書くことができる */ 73

File imgDir = new File("img");

74

File img2Dir = new File("img2");

75

// img ディレクトリにあるファイルを配列にして全て取り出す

76

File imgFiles[] = imgDir.listFiles();

77

File img2Files[] = img2Dir.listFiles();

78

// ファイルの数が合わなかったら Exception

79

if (imgFiles.length != img2Files.length)

80

throw new MyException("画像ファイルの数が合いません");

81

// List に画像オブジェクトを追加

82

/* getAbsolutePath 関数:ファイルの絶対パスを String で返す*/

83

for (int i=0; i<imgFiles.length; i++) {

84 images.add(new ImageIcon(imgFiles[i].getAbsolutePath())); 85 images2.add(new ImageIcon(img2Files[i].getAbsolutePath())); 86 } 87 // サウンドファイルを sounds ディレクトリから取り出す 88

audioFiles = (new File("sounds")).listFiles();

89

// 画像ファイルとサウンドファイルの数が合わなかったら Exception を発生させる

90

if (imgFiles.length != audioFiles.length)

91

throw new MyException("音声ファイルの数が合いません");

92 } 93 94 /** 95 * 描画メソッド<br> 96 * repaint 関数から呼ばれる 97 */ 98 @Override 99

public void paintComponent(Graphics g) {

100 /* パネルにボタンなどが配置されているときのため 101 * 今回は実際に意味はないが、慣例として忘れないよう書いておく*/ 102 super.paintComponents(g); 103 // より様々な描画方法が可能になるようにキャスト 104 Graphics2D g2d = (Graphics2D)g; 105 // システムカラー(背景色)を設定 106 g2d.setColor(SystemColor.control); 107 // 画面をいったんクリア 108

g2d.fillRect(0, 0, this.getWidth(), this.getHeight());

109

// 動物描画

110

/* Java5 からは可変長配列 List のループを以下ように書くことができる

111

* animal には animals リストから順にとった Animal オブジェクトがはいる */

112

for (Animal animal : animals) {

113 // 画像を描画 114 /* drawImage(画像オブジェクト, x 座標, y 座標, 幅, 高さ, ImageObserver) 115 * ImageObserver は画像のロードを通知するもの。たいていは this でよい */ 116 g2d.drawImage(images.get(animal.getAnimalType()).getImage(), 117 animal.getCenterPoint().x-animal.getSize().width/2, 118 animal.getCenterPoint().y-animal.getSize().height/2, 119

animal.getSize().width, animal.getSize().height, this);

120 } 121 // 描画モードが"img"だったらタイマーで画像切り替えの必要はなくなる 122 if (imgType.equals(IMG)) { 123 // タイマーが動いていたらストップ 124 if (timer.isRunning()) 125 timer.stop(); 126

(4)

-4- // 描画モードが"img2"だったら鳴いてる動物の画像を描画しなおす 128 else { 129 // 画像その2を描画 130 g2d.drawImage(images2.get(clickedAnimal.getAnimalType()).getImage(), 131 clickedAnimal.getCenterPoint().x-clickedAnimal.getSize().width/2, 132 clickedAnimal.getCenterPoint().y-clickedAnimal.getSize().height/2, 133 clickedAnimal.getSize().width, 134 clickedAnimal.getSize().height, this); 135 } 136 } 137 138 139 /** 140 * マウスクリックで呼ばれる関数 141 */ 142 @Override 143

public void mouseClicked(MouseEvent e) {

144 // クリックされた座標を取得 145 x = e.getX(); 146 y = e.getY(); 147

int onImageIndex = 0; // 画像上クリックなら index(動物の種類),そうでなければ ListSize

148

/* animals の中の Animal オブジェクトを順に見て、クリックされた場所が

149

* 動物画像の中に含まれるかどうかをみていく*/

150

for (Animal animal : animals) {

151 // 動物画像の中でクリックされていたらループから抜ける 152 if (animal.contains(x, y)) 153 break; 154 onImageIndex ++; 155 } 156 // 動物画像の中でクリックされていたら鳴き声を再生 157 if (onImageIndex < animals.size()) { 158 try { 159 // クリックされた動物を取得 160 clickedAnimal = animals.get(onImageIndex); 161 // タイマーをスタートしてアクションイベントを発生させる 162 // すると、actionPerformed メソッドが呼ばれる 163 timer.start(); 164 // 動物の種類に応じた鳴き声を再生 165 play(clickedAnimal.getAnimalType()); 166

} catch (MyException ex) {

167 // タイマーをとめて画像の描画モードを初期化 168 timer.stop(); 169 imgType = IMG; 170 // エラーをダイアログ表示 171 // JOptionPane.showMessageDialog(フレーム,メッセージ,タイトル,アイコンの種類) 172 JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(this), 173 ex.getMessage(), "再生エラー発生", JOptionPane.ERROR_MESSAGE); // 上と合わせて 1 行 174 } 175 } 176 // 動物画像の外でクリックされていたら画像を表示 177 else { 178 // Animal オブジェクトを生成 179

Animal animal = new Animal(animalType, imgWidth, imgHeight);

180 // 中心座標を設定 181 animal.setCenterPoint(x, y); 182 // リストに追加 183 animals.add(animal); 184 // 再描画 185 repaint(); 186 } 187 } 188 189

(5)

-5- /** 190 * 音声再生メソッド 191 * @param index 192 * @throws Exception 193 */ 194

private void play(int index) throws MyException {

195

try {

196

// オーディオ入力ストリームを取得

197

AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFiles[index]);

198

// オーディオ形式を取得

199

// AU、AIFF、WAVE 形式に対応している

200

AudioFormat format = audioStream.getFormat();

201

// データラインの情報(フォーマットなど)を作成

202

DataLine.Info di = new DataLine.Info(Clip.class, format);

203

// 情報に基づいてラインを取得

204

// Clip はデータをメモリ上に読み込んでおいてから再生する

205

Clip clip = (Clip) AudioSystem.getLine(di);

206 // ラインを開く 207 clip.open(audioStream); 208 // ラインでのデータ入出力を可能にする 209 clip.start(); 210 // ラインからキューに入っているデータを排出 211 clip.drain(); 212 } catch (Exception e) { 213

throw new MyException("再生失敗:"+e.getMessage(), e);

214 } 215 } 216 217 /* MouseListener を implements しているため、 218 * mouseClicked・mouseEntered・mouseExited・mousePressed・mouseReleased の 219 * 4つとも記述しなければならないが、このサンプルで使うのは 220 * mouseClicked だけなので後は空でよい。 */ 221 222 @Override 223

public void mouseEntered(MouseEvent e) {

224 } 225 226 @Override 227

public void mouseExited(MouseEvent e) {

228 } 229 230 @Override 231

public void mousePressed(MouseEvent e) {

232 } 233 234 @Override 235

public void mouseReleased(MouseEvent e) {

236 } 237 238 /** 239 * Timer によるイベント発生時の実行メソッド 240 */ 241 @Override 242

public void actionPerformed(ActionEvent e) {

243 // 画像の描画モード"img"と"img2"をきりかえ 244 if (imgType.equals(IMG)) { 245 imgType = IMG2; 246 } else { 247 imgType = IMG; 248 } 249 // 描画 250 repaint(); 251 } 252

(6)

-6- /** 254 * 動物の種類 setter 255 * @param aimalType 256 */ 257

public void setAnimalType(int animalType) {

258 this.animalType = animalType; 259 } 260 } 261

参照

関連したドキュメント

私たちの行動には 5W1H

断面が変化する個所には伸縮継目を設けるとともに、斜面部においては、継目部受け台とすべり止め

対象期間を越えて行われる同一事業についても申請することができます。た

・本計画は都市計画に関する基本的な方 針を定めるもので、各事業の具体的な

 映画「Time Sick」は主人公の高校生ら が、子どものころに比べ、時間があっという間

モノづくり,特に機械を設計して製作するためには時

 今日のセミナーは、人生の最終ステージまで芸術の力 でイキイキと生き抜くことができる社会をどのようにつ

 筆記試験は与えられた課題に対して、時間 内に回答 しなければなりません。時間内に答 え を出すことは働 くことと 同様です。 だから分からな い問題は後回しでもいいので