
Canvas等で描画された図形を十字キー操作で移動する時,プログラムの処理(負担)を減らすために,Canvas等に描かれている全図形を再描画するのではなく,移動するその図形"だけ"を再描画しつつ,移動させたいのです.
そのためには,どのような事をしなければならないのでしょうか?
アドバイスを宜しくお願いします.
例:
Canvas上のある所に○を描くとします.これをキーボードの↑↓←→キーに合わせて,移動させたいのです.
しかし,私のプログラムでは,上記のプログラムは大体出来ているのですが,以下の不満があります.
Canvas上には,上記の○以外にも,△や□等が散らばって描画されていますので,○の移動毎に,Canvas上の全図形を再描画しています。これで,Canvas上で変更点がない図形も再描画され,処理的に無駄を感じていますので,○だけについて,移動を表現する描画をしつつ,移動前の○図形を削除したいのです.
また,GraphicsのclearRect(x,y,width,height)メソッドで,移動直前の○を消せばよいと思ったのですが,これを使用した場合,図形○に図形△が少しでも重なっていた場合,○だけでなく△の図形も一部消されてしまい上手くいきません.
○をCanvas上に描いたGraphicsインスタンスを記憶しておく事は出来るのでしょうか? 出来るのであれば,そのインスタンスから自分が描画した図形○を消す事で,○だけを削除できる...かな....と思っています....
上記の私の要望が満たされるのであれば,CanvasやGraphicsの範囲外の手法で全くかまいませんので,是非アドバイスを宜しくお願いします。
参考URLもご提示いただければ,なお有難いです.

No.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。
No.2
- 回答日時:
#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 メソッドが走る。
これで、パフォーマンスが上がるのか、よくわからないのですが、思いついただけでも、こんな感じでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画面のちらつきの原因が知りた...
-
VB.NET フォーム上に描いたグ...
-
JAVAでの背景画像表示
-
Androidで画像の中で指定した範...
-
Java、jPanelに描画する
-
ドラッグして矩形を描くには
-
private static という変数の修飾
-
「タイプ初期化子が例外をスロ...
-
変数名の付け方
-
エクセルVBAで、条件に一致する...
-
パワーポイントのVBAでテキスト...
-
Java初級 引数に適用できません
-
Excelで =EMBED("Acrobat Docu...
-
複数の変数を宣言する時、同時...
-
レコード件数の表示
-
【Java】入力した西暦→和暦に変...
-
onClickで関数呼出し後に、結果...
-
VB.NETでフォーム上にExcelのよ...
-
C#において、同じインスタンス...
-
EclipseでJSPのコンパイルエラー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NET フォーム上に描いたグ...
-
Java、jPanelに描画する
-
VB.NETのSendMessageを教えてく...
-
SwingとEDT(イベントディスパッ...
-
C# DataGridView のCellPaintin...
-
Javaで文字の角度を変えて表示...
-
JAVAでの背景画像表示
-
複数画像表示切り替え Visual c++
-
イベントディスパッチングスレ...
-
C# リストビューの特定のセルの...
-
iアプリ作成 画像を描画できない
-
BMP画像を画像処理して連続に表...
-
SwingWorkerに関して
-
canvasで表示されてる画像を1...
-
アクセスで他アプリから復帰し...
-
GDI+で描画した画像を消去する...
-
重なった要素上でのイベントで...
-
ドラッグして矩形を描くには
-
Androidで画像の中で指定した範...
-
requestanimationframeを一斉に...
おすすめ情報