0

私の問題はかなり単純だと思います。

キャンバスに触れたらすぐにドットを描きたいです。タッチした位置にドットが描画されます。次に、画面に別のドットを描画しますが、最初のドットの位置には描画しません。別の画像の上に画像を描画したくないことを意味します。

次のコードでそれをアーカイブしようとしました:

活動クラス

    public class Draw extends Activity {
    DrawView drawView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set full screen view
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                         WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        drawView = new DrawView(this);
        setContentView(drawView);
        drawView.requestFocus();
    }
}

キャンバス クラス

    public class DrawView extends View implements OnTouchListener {
    private static final String TAG = "DrawView";

    List<Point> points = new ArrayList<Point>();
    Vector<Bitmap> bitmaps = new Vector<Bitmap>();
    Paint paint = new Paint();


    public DrawView(Context context) {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true);

        this.setOnTouchListener(this);
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.WHITE);
        for (Point point : points) {
            canvas.drawBitmap(bitmaps.get(point.i), point.x, point.y, paint);
        }
    }

    public boolean onTouch(View view, MotionEvent event) {
        Log.d("Touch","Touch");
        Log.d("Points", "" + points.size());
        Log.d("Bitmaps", "" + bitmaps.size());

        int i = 0;
        for (Point point : points) {
            int height = bitmaps.get(i).getHeight();
            int width = bitmaps.get(i).getWidth();
            //Log.d("dimensions", height + ", " + width);

            for (int x = 0; x <= width; x++) {
                if (Math.floor(point.x + x) == Math.floor(event.getX())) {
                    points.get(i).isTaken = true;
                    Log.d("isTakenX", "" + point.isTaken);
                    break;
                }
                for (int y = 0; y <= height; y++) {
                    if (Math.floor(point.y + y) == Math.floor(event.getY())) {
                        points.get(i).isTaken = true;
                        Log.d("isTakenY", "" + point.isTaken);
                        break;
                    }
                }
            }
            i++;
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.d("EventDown","DOWN");
            boolean isTaken = false;
            for (Point point : points) {
                if (point.isTaken) {
                    isTaken = true;
                }
            }
            if (!isTaken) {
                bitmaps.add(BitmapFactory.decodeResource(getResources(), R.drawable.greenstar));
                Point point = new Point();
                point.x = event.getX();
                point.y = event.getY();
                point.i = bitmaps.size() - 1;
                points.add(point);
                //Log.d("pointClick",point.toString());
                invalidate();
                return true;
            }
        }
        return false ;
    }
}

    class Point {
        float x, y;
        int i;
        boolean isTaken = false;

        @Override
        public String toString() {
            return i + ": " + x + ", " + y;
        }
    }

onTouch メソッドでは、オーバードローしたくない画像の位置をどのように把握しているかがわかります。描画したすべての画像とそのポイントをリストに保存して、それらを変更できるようにしています。次に、画像が画面上で占めるスペースの量と、そのスペースをクリックしただけかどうかを確認します。

ただし、最初の画像がキャンバスに描画された後、別の画像を描画できません。プログラムが「isTaken」で止まっているようです。おそらく、スペースが使用されているかどうかを確認する方法に関する私の対数が間違っています。しかし、何が間違っているのか理解できません。

アイデアはありますか?

前もって感謝します

4

1 に答える 1

1

何点かOK。1 つの論理エラーといくつかの機能強化。(コードとアイデア)

最初に:foreach構成を使用するときは、ループからの変数 (ポイントなど) を使用して、ループしているリストからインスタンスにアクセスします。だからあなたpoints.get(i)を簡単に変えてくださいpoint

2番目:円があるので、ポイントが長方形内にあるかどうかを確認する必要はありません(それがあなたが達成したいことだと思います)。2 つのポイント (既に描画されたものとこれから描画されるもの) の中心の距離が十分に大きいかどうかを確認します。これにはピタゴラス方程式を使用します (c^2 = a^2 * b^2)。

3 番目 (実際のエラー): 2 つの for ループのロジックが間違っています。x と y を別々に扱っていますが、一緒にチェックする必要があります。目的を達成するために for ループは必要ありません。

for ループを次のように変更します。

if(Math.pow(radius*2,2) > Math.pow(event.getX-point.x,2)+Math.pow(event.getY-point.Y, 2))
        point.isTaken = true;

半径は描かれた円の半径です。それを試してみて、さらに問題がある場合は報告してください。

于 2012-08-09T19:06:10.583 に答える