グラフィックスを扱う |
このページでは、1 つのイメージ (現在のところはピザの一切れのように見える宇宙 船) を背景イメージ (星空) の手前で移動させるアプレット例を示す。 このページではアプレットのコードだけを示す。 アプリケーションのコードはこれと似ているが、 イメージをロードするで説明したように、イメー ジをロードするコードが異なっている。
以下に、このアプレットが使用する 2 つのイメージを示す。
rocketship.gif :
starfield.gif :
注: 宇宙船のイメージの背景は透明である。 背景が透明なため、宇宙船のイメージが描かれる背景(星空)の色にかかわらず、宇宙船のイメージは 宇宙船の形状のまま現れる。 宇宙船の背景が透明でなければ、宇宙船が宇宙空間を移動するように見える代わりに、空間を移動する矩形の上に宇宙船があるように見えてしまう。
ここで、アプレットが動作する様子を示す。 アプレットをクリックすることによって、動画の停止と開始が行える。
使用中のブラウザは 1.0 Java アプレットを実行することができない。したがってここでは実行中のスナップショットを示す。
この動画を実行するコードは複雑ではない。 基本的には、アプレットの動画テンプレートに、前のページで説明したダブルバッフ ァリングのコードと、若干のコードを加えただけである。 追加のコードはイメージをロードし、背景イメージを描いた後、単純なアルゴリズム を用いて、移動するイメージを描く位置を決めている。 追加のコード部分を以下に示す。
...//インスタンス変数を宣言する。 Image stars; Image rocket; ...//init() メソッドで: stars = getImage(getCodeBase(), "../images/starfield.gif"); rocket = getImage(getCodeBase(), "../images/rocketship.gif"); ...//update() メソッドで: //フレームをイメージにペイントする。 paintFrame(offGraphics); ...//新規のメソッド: void paintFrame(Graphics g) { Dimension d = size(); int w; int h; //背景イメージの有効な幅と高さがわかっていれば //それを描画する。 w = stars.getWidth(this); h = stars.getHeight(this); if ((w > 0) && (h > 0)) { g.drawImage(stars, (d.width - w)/2, (d.height - h)/2, this); } //宇宙船イメージの有効な幅と高さがわかっていれば //それを描画する。 w = rocket.getWidth(this); h = rocket.getHeight(this); if ((w > 0) && (h > 0)) { g.drawImage(rocket, ((frameNumber*5) % (w + d.width)) - w, (d.height - h)/2, this); } }このプログラムには背景イメージがあるため背景のクリアは必要ないと感じるかもし れないが、 やはり背景のクリアは必要なのである。 理由の 1 つは、アプレットは通常、イメージが完全にロードされる前に描画を開始 するからである。 宇宙船イメージが背景イメージより先にロードされると、背景イメージがロードされ るまで、複数の宇宙船の部分が見えてしまう。 もう 1 つの理由は、アプレットの描画領域が何らかの理由で背景イメージより大きければ、背景イメージのどちらかの端に複数の宇宙船が見えてしまうことになるからである。
最初の問題は、両方のイメージが完全にロードされるまですべての描画を延期するこ とによって解決できる。 2 番目の問題は、背景イメージがアプレット領域全体にフィットするようスケールす ることによって解決できる。イメージが完全にロードされるまで待機する方法については、このレッスンの後の方にある イメージ動画の外観とパフォーマンスを向上させ るで学習する。 スケーリングについては、 イメージを表示するで説明されている。
グラフィックスを扱う |