プロが教える店舗&オフィスのセキュリティ対策術

Canvas等で描画された図形を十字キー操作で移動する時,プログラムの処理(負担)を減らすために,Canvas等に描かれている全図形を再描画するのではなく,移動するその図形"だけ"を再描画しつつ,移動させたいのです.
そのためには,どのような事をしなければならないのでしょうか?
アドバイスを宜しくお願いします.

例:
Canvas上のある所に○を描くとします.これをキーボードの↑↓←→キーに合わせて,移動させたいのです.
しかし,私のプログラムでは,上記のプログラムは大体出来ているのですが,以下の不満があります.
Canvas上には,上記の○以外にも,△や□等が散らばって描画されていますので,○の移動毎に,Canvas上の全図形を再描画しています。これで,Canvas上で変更点がない図形も再描画され,処理的に無駄を感じていますので,○だけについて,移動を表現する描画をしつつ,移動前の○図形を削除したいのです.
また,GraphicsのclearRect(x,y,width,height)メソッドで,移動直前の○を消せばよいと思ったのですが,これを使用した場合,図形○に図形△が少しでも重なっていた場合,○だけでなく△の図形も一部消されてしまい上手くいきません.

○をCanvas上に描いたGraphicsインスタンスを記憶しておく事は出来るのでしょうか? 出来るのであれば,そのインスタンスから自分が描画した図形○を消す事で,○だけを削除できる...かな....と思っています....

上記の私の要望が満たされるのであれば,CanvasやGraphicsの範囲外の手法で全くかまいませんので,是非アドバイスを宜しくお願いします。
参考URLもご提示いただければ,なお有難いです.

A 回答 (3件)

私も、基本として、背景用画像とオフスクリーンバッファの2つを保持するところは、N02のご回答と同じです。


さらに加えると、移動用図形データは、どのように保持していますか?この保持方法によって、重なり判定が簡単になったり、面倒になったりします。
図形ごとにjava.awt.Shape実装クラス(GeneralPath,Line2D,Polygon,Rectangle,Ellipse2Dなど)のインスタンスを作り、さらにそれらを、ArrayList<Shape>に保持すると、かなり操作しやすくなるかと思います。jdk のversionは5.0以上ですよね?genericsも使うと記述が楽ですよ。
Shapeのメソッドを駆使すれば、以下のように判定できるかと。
extends MouseAdapter としたクラスをinner class で作成すると、canvasに保持しているArrayList<Shape>にもアクセスしやすいです。
mousePressed(MouseEvent ev)のとき、マウスのポイント位置が図形内かの判定は、Shapeのcontains(double x, double y)というメソッドで
ポイント位置に重なってる図形をみな動かすなら、クラスfieldにint[] を保持し、ArrayListにおける格納番号を保持するなどの工夫もいるでしょう。
mouseReleased(MouseEvent ev)のときは、ShapeのgetBounds() で Shape を完全に囲む領域Rectangle を返すので、これで移動対象図形の元位置を得ておいて、図形データを編集(移動方法は、Polygon,Rectangle,java.awt.geom.Ellipse2Dそれぞれ違うので注意)
オフスクリーンバッファ上の元位置を背景画像で初期化。
次に、ArrayList<Shape>の全ての図形においてShapeのintersects()で、元位置領域と重なっているかをチェックして、重なっている図形があれば、オフスクリーンバッファにその図形を再描画します。Graphics2Dのdraw(Shape s)で描画できるので、これも楽です。
移動後図形が元位置から、はずれてることもあるので、これも再描画。
移動後位置も得て、両方を含む領域を算出してrepaint。
    • good
    • 0

 #1です。



 私も経験者というわけじゃないのですが、おもしろそうなので、一緒に考えさせてください。

 まず、考えたのが、

1.もう一つ背景用の BufferedImage を作っておき、動かないものは、背景としてあらかじめそこに書いておき、適時、オフスクリーンバッファに背景の塗りつぶしとして、 drawImage する。

2.update メソッドでは、オフスクリーンバッファへの書き込みだけにして、paintメソッドでは、オフスクリーンバッファの表示に専念させる。

3.update メソッドでは、引数の Graphics から取得したクリップを、オフスクリーンバッファにも設定して、再描画を最小限に抑える。

4.なんなら、update メソッド中で、クリップに引っかからないオブジェクトは、もう描画しない。

5.キャラクターの移動後、キャラの元位置と移動先を含む最小限の範囲の repaint(int x, int y, int width, int height) をかける。
 これで、2.の時に最小限の範囲のクリップが設定された update メソッド、および、 paint メソッドが走る。

 これで、パフォーマンスが上がるのか、よくわからないのですが、思いついただけでも、こんな感じでしょうか。
    • good
    • 0

 こんにちは。



 動くのは、一つの丸だけですか?
 あと、ダブルバッファリングには、していますか?

この回答への補足

動く事が出来る図形は,Canvas上に描画する図形の多数で○,△,□等です.
一部,動かす事が出来ない図形も考えております.
また,一時に同時に動きうる図形は、1つだけです.

ダブルバッファリングはしております。

補足日時:2009/07/18 21:22
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!