スレッドとアニメーション (9/9)
作成:2010-01-14 21:18
更新:2010-01-14 21:18
更新:2010-01-14 21:18
■オフスクリーンバッファ処理の流れ
ここでは、まずMyCanvasのほうを先に見ましょう。まず、updateメソッドが用意されていますね。
public void update(Graphics g){
paint(g);
}
このように、updateが呼び出されたら何もしないでpaintするようにしておきます。これで、よけいな描画処理はされなくなり、ちらつきもおさえられます。そして肝心のpaintメソッドはこうなっています。
public void paint(Graphics g){
if (offImg == null){
offImg = createImage(250,150);
}
g.drawImage(offImg,0,0,this);
}
このように、まずオフスクリーン用のoffImgというImageインスタンスがnullかどうかをチェックします。そしてnullだった場合にはcreateImageというメソッドを使ってImageインスタンスを作成します。これはパラメータに作成するイメージの縦横の大きさを指定します。そしてその後で、drawImageを使って、オフスクリーンのoffImgを描画しています。
○Imageインスタンス作成のタイミング○
なんでこんなところでImageインスタンスを作るんだ? 普通、汎用的なインスタンスはコンストラクタの中で作るんじゃないのか? …と思った人もいるでしょう。実は、このcreateImageは、コンストラクタの中ではうまく動かないのです。理由はちょっとややこしくなるので省略しますが、「createImageは、コンストラクタで作成してはいけない」ということだけ覚えておいて下さい。
このようにpaintメソッドは、単にオフスクリーンバッファを表示するだけの働きしかしていません。オフスクリーンバッファに、必要に応じて描画を行なっているのはrunメソッドです。(下リスト参照)
○runメソッドの流れ○
まず最初に、getGraphicsでGraphicsインスタンスを取り出してから、繰り返し処理へと入っていきます。そして移動方向や描画場所などの変数を処理した後、drawImageで背景を描き、それから重ね合わせるイメージを描いています。そして終わったところでrepaintを呼び出して画面を更新します。
ここではImageインスタンスがnullかどうかチェックしていませんが、これはactionPerformedメソッドのほうで、既にチェックしてからスレッドをスタートするからです。
――スレッドを使ってイメージを動かすのは、意外に注意しないといけないポイントが多いので大変なのです。createImageの問題、updateの修正、描画するImageがnullでないかどうかの確認、オフスクリーンへの描画と、オフスクリーンから画面への描画の分離、ざっと考えただけでもこれだけ注意しないといけません。ちょっとややこしくなってきたので、それぞれでよくコードを読んで、メソッドの役割分担についてよく考えてみるとよいでしょう。
public void update(Graphics g){
paint(g);
}
このように、updateが呼び出されたら何もしないでpaintするようにしておきます。これで、よけいな描画処理はされなくなり、ちらつきもおさえられます。そして肝心のpaintメソッドはこうなっています。
public void paint(Graphics g){
if (offImg == null){
offImg = createImage(250,150);
}
g.drawImage(offImg,0,0,this);
}
このように、まずオフスクリーン用のoffImgというImageインスタンスがnullかどうかをチェックします。そしてnullだった場合にはcreateImageというメソッドを使ってImageインスタンスを作成します。これはパラメータに作成するイメージの縦横の大きさを指定します。そしてその後で、drawImageを使って、オフスクリーンのoffImgを描画しています。
○Imageインスタンス作成のタイミング○
なんでこんなところでImageインスタンスを作るんだ? 普通、汎用的なインスタンスはコンストラクタの中で作るんじゃないのか? …と思った人もいるでしょう。実は、このcreateImageは、コンストラクタの中ではうまく動かないのです。理由はちょっとややこしくなるので省略しますが、「createImageは、コンストラクタで作成してはいけない」ということだけ覚えておいて下さい。
このようにpaintメソッドは、単にオフスクリーンバッファを表示するだけの働きしかしていません。オフスクリーンバッファに、必要に応じて描画を行なっているのはrunメソッドです。(下リスト参照)
○runメソッドの流れ○
まず最初に、getGraphicsでGraphicsインスタンスを取り出してから、繰り返し処理へと入っていきます。そして移動方向や描画場所などの変数を処理した後、drawImageで背景を描き、それから重ね合わせるイメージを描いています。そして終わったところでrepaintを呼び出して画面を更新します。
ここではImageインスタンスがnullかどうかチェックしていませんが、これはactionPerformedメソッドのほうで、既にチェックしてからスレッドをスタートするからです。
――スレッドを使ってイメージを動かすのは、意外に注意しないといけないポイントが多いので大変なのです。createImageの問題、updateの修正、描画するImageがnullでないかどうかの確認、オフスクリーンへの描画と、オフスクリーンから画面への描画の分離、ざっと考えただけでもこれだけ注意しないといけません。ちょっとややこしくなってきたので、それぞれでよくコードを読んで、メソッドの役割分担についてよく考えてみるとよいでしょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
※オフスクリーンバッファ処理を行うrunメソッド public void run(){ Graphics g = offImg.getGraphics(); try { while(KissOfDeath){ if (lastX + moveX < 0 || (lastX + moveX) > (c1.getWidth() - 50)){ moveX *= -1; } if (lastY + moveY < 0 || (lastY + moveY) > (c1.getHeight() - 50)){ moveY *= -1; } lastX += moveX; lastY += moveY; g.drawImage(img1,0,0,this); g.drawImage(img2,lastX,lastY,this); c1.repaint(); t1.sleep(100); } } catch(Exception e){ System.out.println(e); } g.dispose(); }
※関連コンテンツ