2017-06-25 23 views
9

Tôi có chế độ xem CustomView và Chế độ xem hình ảnh. CustomView là một quả bóng di chuyển xung quanh màn hình và bị trả lại khỏi tường. Hình ảnh là một vòng tròn quý mà bạn có thể xoay vòng tròn khi chạm vào. Tôi đang cố gắng tạo ra trò chơi của mình để khi các pixel được lấp đầy từ các đường chéo của CustomView với các điểm ảnh được lấp đầy từ ImageView một xung đột được phát hiện. Vấn đề mà tôi đang gặp là tôi không biết cách truy xuất vị trí các pixel được lấp đầy trên mỗi khung nhìn.Phát hiện Va chạm hoàn hảo pixel giữa chế độ xem tùy chỉnh và ImageView

Đây là mã XML của tôi

<com.leytontaylor.bouncyballz.AnimatedView 
    android:id="@+id/anim_view" 
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent" 
    /> 

<ImageView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/quartCircle" 
    android:layout_gravity="center_horizontal" 
    android:src="@drawable/quartercircle" 
    android:scaleType="matrix"/> 

MainActivity My

public class MainActivity extends AppCompatActivity { 

private static Bitmap imageOriginal, imageScaled; 
private static Matrix matrix; 

private ImageView dialer; 
private int dialerHeight, dialerWidth; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // load the image only once 
    if (imageOriginal == null) { 
     imageOriginal = BitmapFactory.decodeResource(getResources(), R.drawable.quartercircle); 
    } 

    // initialize the matrix only once 
    if (matrix == null) { 
     matrix = new Matrix(); 
    } else { 
     // not needed, you can also post the matrix immediately to restore the old state 
     matrix.reset(); 
    } 

    dialer = (ImageView) findViewById(R.id.quartCircle); 
    dialer.setOnTouchListener(new MyOnTouchListener()); 
    dialer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      // method called more than once, but the values only need to be initialized one time 
      if (dialerHeight == 0 || dialerWidth == 0) { 
       dialerHeight = dialer.getHeight(); 
       dialerWidth = dialer.getWidth(); 

       // resize 
       Matrix resize = new Matrix(); 
       resize.postScale((float) Math.min(dialerWidth, dialerHeight)/(float) imageOriginal.getWidth(), (float) Math.min(dialerWidth, dialerHeight)/(float) imageOriginal.getHeight()); 
       imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false); 

       // translate to the image view's center 
       float translateX = dialerWidth/2 - imageScaled.getWidth()/2; 
       float translateY = dialerHeight/2 - imageScaled.getHeight()/2; 
       matrix.postTranslate(translateX, translateY); 

       dialer.setImageBitmap(imageScaled); 
       dialer.setImageMatrix(matrix); 

      } 
     } 
    }); 
} 

lớp MyOnTouchListener:

private class MyOnTouchListener implements View.OnTouchListener { 

    private double startAngle; 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 

     switch (event.getAction()) { 

      case MotionEvent.ACTION_DOWN: 
       startAngle = getAngle(event.getX(), event.getY()); 
       break; 

      case MotionEvent.ACTION_MOVE: 
       double currentAngle = getAngle(event.getX(), event.getY()); 
       rotateDialer((float) (startAngle - currentAngle)); 
       startAngle = currentAngle; 
       break; 

      case MotionEvent.ACTION_UP: 
       break; 
     } 
     return true; 
    } 
} 

private double getAngle(double xTouch, double yTouch) { 
    double x = xTouch - (dialerWidth/2d); 
    double y = dialerHeight - yTouch - (dialerHeight/2d); 

    switch (getQuadrant(x, y)) { 
     case 1: 
      return Math.asin(y/Math.hypot(x, y)) * 180/Math.PI; 
     case 2: 
      return 180 - Math.asin(y/Math.hypot(x, y)) * 180/Math.PI; 
     case 3: 
      return 180 + (-1 * Math.asin(y/Math.hypot(x, y)) * 180/Math.PI); 
     case 4: 
      return 360 + Math.asin(y/Math.hypot(x, y)) * 180/Math.PI; 
     default: 
      return 0; 
    } 
} 

/** 
* @return The selected quadrant. 
*/ 
private static int getQuadrant(double x, double y) { 
    if (x >= 0) { 
     return y >= 0 ? 1 : 4; 
    } else { 
     return y >= 0 ? 2 : 3; 
    } 
} 

/** 
* Rotate the dialer. 
* 
* @param degrees The degrees, the dialer should get rotated. 
*/ 
private void rotateDialer(float degrees) { 
    matrix.postRotate(degrees, dialerWidth/2, dialerHeight/2); 

    dialer.setImageMatrix(matrix); 
} 

Và AnimatedView tôi

public class AnimatedView extends ImageView { 

private Context mContext; 
int x = -1; 
int y = -1; 
private int xVelocity = 10; 
private int yVelocity = 5; 
private Handler h; 
private final int FRAME_RATE = 60; 

public AnimatedView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mContext = context; 
    h = new Handler(); 
} 

private Runnable r = new Runnable() { 
    @Override 
    public void run() { 
     invalidate(); 
    } 
}; 

protected void onDraw(Canvas c) { 
    BitmapDrawable ball = (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.smallerball); 

    if (x<0 && y <0) { 
     x = this.getWidth()/2; 
     y = this.getHeight()/2; 
    } else { 
     x += xVelocity; 
     y += yVelocity; 
     if ((x > this.getWidth() - ball.getBitmap().getWidth()) || (x < 0)) { 
      xVelocity = xVelocity*-1; 
     } 
     if ((y > this.getHeight() - ball.getBitmap().getHeight()) || (y < 0)) { 
      yVelocity = yVelocity*-1; 
     } 
    } 

    c.drawBitmap(ball.getBitmap(), x, y, null); 
    h.postDelayed(r, FRAME_RATE); 
} 

public float getX() { 
    return x; 
} 

public float getY() { 
    return y; 
} 

} 

Câu hỏi của tôi là: Làm cách nào tôi có thể truy xuất các pixel đã điền từ cả hai chế độ xem này và chuyển chúng qua một hàm phát hiện xung đột.

Cảm ơn trước sự giúp đỡ! :)

+4

'Pixel-perfect' và' Android' chưa bao giờ là bạn tốt. –

+0

@Rotwang bạn sẽ đề xuất gì về phát hiện va chạm của các đối tượng động? – Leyton

+0

Tôi không biết. Tôi không chơi game. Tôi cho rằng một số loại hệ tọa độ tỷ lệ thuận với mật độ màn hình. –

Trả lời

1

Bạn thực sự cần xác định "pixel đã điền". Tôi giả sử bạn có nghĩa là các điểm ảnh không trong suốt. Cách dễ nhất để tìm những thứ đó là chuyển đổi toàn bộ khung nhìn thành bitmap và lặp qua các pixel của nó. Bạn có thể chuyển đổi một View thành một Bitmap như thế này:

private Bitmap getBitmapFromView(View view) { 
    view.buildDrawingCache(); 
    Bitmap returnedBitmap = Bitmap.createBitmap(view.measuredWidth, 
      view.measuredHeight, 
      Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(returnedBitmap); 
    canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN); 
    Drawable drawable = view.background; 
    drawable.draw(canvas); 
    view.draw(canvas); 
    return returnedBitmap; 
} 

Bạn cũng sẽ cần phải có được vị trí tuyệt đối của các quan điểm:

Point getViewLocationOnScreen(View v) { 
    int[] coor = new int[]{0, 0}; 
    v.getLocationOnScreen(coor); 
    return new Point(coor[0], coor[1]); 
} 

Sau đó, bạn chỉ phải lặp qua các điểm ảnh của mỗi Bitmap, kiểm tra màu sắc của chúng để biết liệu chúng có được "lấp đầy" hay không và cũng kiểm tra xem chúng có chồng chéo dựa trên sự phối hợp của chúng bên trong bitmap và vị trí tuyệt đối của các chế độ xem trên màn hình hay không.

Iterating thông qua một bitmap được thực hiện như thế này:

for (int x = 0; x < myBitmap.getWidth(); x++) { 
    for (int y = 0; y < myBitmap.getHeight(); y++) { 
     int color = myBitmap.getPixel(x, y); 
    } 
} 

Nhưng tôi phải nói rằng, tôi không nghĩ rằng thực hiện loại này tính toán nặng trên thread UI thực sự là một ý tưởng tốt. Có hàng chục cách tốt hơn để phát hiện va chạm hơn kiểm tra pixel hoàn hảo. Điều này có thể sẽ cực kỳ chậm chạp.

1

Bạn có thể gói gọn hình ảnh của bạn với mảng các điểm đánh dấu tọa độ biên giới của bạn (và cập nhật chúng vào di chuyển/tính toán cho họ dựa trên nguồn gốc) sau đó bạn sẽ có thể quyết định xem đối tượng oposing có đang liên lạc hay không (nếu bất kỳ mảng oposing nào chia sẻ cùng một điểm)

Các vấn đề liên quan