- ベストアンサー
Canvas等の図形を移動する時,直前のその図形のみを削除する方法
Canvas等で描画された図形を十字キー操作で移動する時,プログラムの処理(負担)を減らすために,Canvas等に描かれている全図形を再描画するのではなく,移動するその図形"だけ"を再描画しつつ,移動させたいのです. そのためには,どのような事をしなければならないのでしょうか? アドバイスを宜しくお願いします. 例: Canvas上のある所に○を描くとします.これをキーボードの↑↓←→キーに合わせて,移動させたいのです. しかし,私のプログラムでは,上記のプログラムは大体出来ているのですが,以下の不満があります. Canvas上には,上記の○以外にも,△や□等が散らばって描画されていますので,○の移動毎に,Canvas上の全図形を再描画しています。これで,Canvas上で変更点がない図形も再描画され,処理的に無駄を感じていますので,○だけについて,移動を表現する描画をしつつ,移動前の○図形を削除したいのです. また,GraphicsのclearRect(x,y,width,height)メソッドで,移動直前の○を消せばよいと思ったのですが,これを使用した場合,図形○に図形△が少しでも重なっていた場合,○だけでなく△の図形も一部消されてしまい上手くいきません. ○をCanvas上に描いたGraphicsインスタンスを記憶しておく事は出来るのでしょうか? 出来るのであれば,そのインスタンスから自分が描画した図形○を消す事で,○だけを削除できる...かな....と思っています.... 上記の私の要望が満たされるのであれば,CanvasやGraphicsの範囲外の手法で全くかまいませんので,是非アドバイスを宜しくお願いします。 参考URLもご提示いただければ,なお有難いです.
- みんなの回答 (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。
その他の回答 (2)
- PecoPlus
- ベストアンサー率76% (144/188)
#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 メソッドが走る。 これで、パフォーマンスが上がるのか、よくわからないのですが、思いついただけでも、こんな感じでしょうか。
- PecoPlus
- ベストアンサー率76% (144/188)
こんにちは。 動くのは、一つの丸だけですか? あと、ダブルバッファリングには、していますか?
補足
動く事が出来る図形は,Canvas上に描画する図形の多数で○,△,□等です. 一部,動かす事が出来ない図形も考えております. また,一時に同時に動きうる図形は、1つだけです. ダブルバッファリングはしております。