如何使MotionEvent的坐标与缩放画布的坐标相匹配? [英] How do I make the coordinates of MotionEvent match the ones of a scaled canvas?

查看:313
本文介绍了如何使MotionEvent的坐标与缩放画布的坐标相匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个画布,它经过缩放,因此所有内容都更合适:

I have a Canvas that is scaled so everything fits better:

@Override
public void draw(Canvas c){
    super.draw(c);
    final float scaleFactorX = getWidth()/(WIDTH*1.f);
    final float scaleFactorY = getHeight()/(HEIGHT*1.f);

    if(c!=null) {
        final int savedState = c.save();

        c.scale(scaleFactorX, scaleFactorY);

        (rendering)

        c.restoreToCount(savedState);
    }

}

它基于以下两个方面进行缩放:

It scales based on these two:

public  static final int WIDTH = 856;
public  static final int HEIGHT = 1050;

这会导致以下问题:处理触摸事件的MotionEvent的坐标与使用Canvas创建的坐标不相等.当我尝试检查MotionEvent Rect和基于渲染比例的类的Rect之间的冲突时,这会导致问题.这将导致SuperCoin类的X坐标不等于MotionEvent X坐标. 通常,MotionEvent的坐标X和Y都比屏幕的最大尺寸大得多(由WIDTHHEIGHT定义)

Which causes the problem that the coordinates of the MotionEvent that handles touch events is not equal to the coordinates that is created with the Canvas. This causes problems when I try to check collision between the MotionEvent Rect and the Rect of a class that is based on the rendering scale. This causes the class SuperCoin's X coordinate to not be equal to MotionEvent X coordinates. Usually, MotionEvent's coordinates, both X and Y is way bigger than the screen's max size(defined by WIDTH and HEIGHT)

 @Override
public boolean onTouchEvent(MotionEvent e) {
    super.onTouchEvent(e);

    switch (MotionEventCompat.getActionMasked(e)) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            (...)
            Rect r = new Rect((int)e.getX(), (int)e.getY(), (int)e.getX() + 3, (int)e.getY() + 3);
            if(superCoins.size() != 0) {
                for (SuperCoin sc : superCoins) {
                    if (sc.checkCollision(r)) {
                        progress++;
                        superCoins.remove(sc);
                    }
                }
            }

            break;

    }

    return true;

}

还有超级硬币:

public class SuperCoin {
    private Bitmap bm;
    public int x, y, orgY;
    Clicker cl;
    private Long startTime;
    Random r = new Random();
    public SuperCoin(Bitmap bm, int x, int y, Clicker c){
        this.x = x;
        this.y = y;
        this.orgY = y;
        this.bm = bm;
        this.cl = c;
        startTime = System.nanoTime();
        bounds = new Rect(x, y, x + bm.getWidth(), y + bm.getHeight());

    }

    private Rect bounds;

    public boolean checkCollision(Rect second){
        if(second.intersect(bounds)){
            return true;
        }
        return false;
    }


    private int velX = 0, velY = 0;


    public void render(Canvas c){

        long elapsed = (System.nanoTime()-startTime)/1000000;
        if(elapsed>50) {


            int cx;
            cx = r.nextInt(2);
            if(cx == 0){
                velX = r.nextInt(4);
            }else if(cx == 1){
                velX = -r.nextInt(4);
            }

            velY = r.nextInt(10) + 1;

            startTime = System.nanoTime();
        }

        if(x < 0) velX = +2;
        if(x > Clicker.WIDTH) velX = -2;

        x += velX;
        y -= velY;


        c.drawBitmap(bm, x, y, null);
    }
}

当MotionEvent X坐标大于屏幕缩放的最大坐标时,如何检查两个不同对象之间的碰撞?

How can I check collision between the two different when the MotionEvent X coordinate is bigger than the screen's scaled max coordinates?

老实说,我不能完全确定为什么SuperCoin类中定义的Rect与onTouchEvent方法中定义的Rect不同.我猜是因为MotionEvent定义的X和Y与缩放画布定义的X和Y永久不同. SuperCoin类中的Rect按已传递的位图的宽度进行移动.它使用位图的宽度和高度对其进行缩放.

Honestly, I am not completly sure why the Rect defined in the SuperCoin class is different from the one defined in the onTouchEvent method. I'm guessing because the X and Y is permanently different between the one defined by MotionEvent and the ones defined by the scaled canvas. The Rect in the SuperCoin class goes by the width of the Bitmap it has been passed. It scales it with the width and height of the Bitmap.

推荐答案

在过去2天中,我仔细研究了StackOverflow和Google,寻找接近解决方案的东西之后,我遇到了这个问题:放大/后获取Canvas坐标/向下或拖动android解决了该问题.真的很难找到,因为标题有点误导了(另一个问题)

After looking through StackOverflow and Google for the past 2 days looking for something that comes close to a solution, I came over this: Get Canvas coordinates after scaling up/down or dragging in android Which solved the problem. It was really hard to find because the title was slightly misleading(of the other question)

float px = e.getX() / mScaleFactorX;
float py = e.getY() / mScaleFactorY;
int ipy = (int) py;
int ipx = (int) px;
Rect r = new Rect(ipx, ipy, ipx+2, ipy+2);

我将其添加为答案并接受了它,因此它在解决后将不再是一个悬而未决的问题.上面的代码将坐标转换为整数,因此它们可用于检查手指与我正在检查的对象之间的碰撞

I added this as an answer and accepting it so it no longer will be an unanswered question as it is solved. The code above converts the coordinates to integers so they can be used for checking collision between the finger and the object I'm checking with

这篇关于如何使MotionEvent的坐标与缩放画布的坐标相匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆