让图像进入用户点击的位置

时间:2016-11-25 05:36:17

标签: java android android-studio motionevent

对于一个Android应用程序即时编码,我试图这样做,当用户点击屏幕时,"播放器"这是一个图像滑过,直到达到x值

当玩家在MotionEvent中触摸屏幕时,我尝试调用此方法

    public void movementUpdate(int x){
    if(goalX < x){
        goalX -= width;
    }
    if(goalX > x){
       goalX += width;
    }
    goalX = x;
}

然后在我调用的更新方法中

public  void update(){
    if(goalX > x)
        x += 4;
    if(goalX < x)
        x -= 4;
}

但是图像总是超过它或者不够远

此外,当您点击图像的前面时,图像是从左上角用java绘制的,你必须减去1/2的宽度,使它停在中间而不是边缘,如果你点击后面减去1 / 2呢?

2 个答案:

答案 0 :(得分:2)

我为你做了一个基本的结构。如果粘贴代码,则可能需要添加包名称,更改活动名称,更改布局名称以及将名为grey_star的png图像添加到drawable文件夹。

import android.os.CountDownTimer;
import android.provider.ContactsContract;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

//the vars that contains the users touch coords, I set some place holders the disapear as soon
//as the user touches the screen
private float touchX = 100;
private float touchY = 100;

//number of pixels to be moved every tick you should
//calculate them based on the screen size in a setup method
private int xSpeed = 10;
private int ySpeed = 10;

//bounds of the screen
private int leftBound;
private int rightBound;
private int topBound;
private int bottomBound;

//screen dimensions
private float pxScreenWidth;
private float pxScreenHeight;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    //make the scree go fullscreen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    //remove action bar, and set content view
    setContentView(R.layout.activity_main);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

    //obtain the width and height of the screen in pixels
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
    pxScreenHeight = displayMetrics.heightPixels;
    pxScreenWidth = displayMetrics.widthPixels;

    //set bounds
    leftBound = 0;
    rightBound = (int) pxScreenWidth;
    topBound = 0;
    bottomBound = (int) pxScreenHeight;


    mainGame();
}

private void mainGame() {


    //some kind of timer I am lazy and used the countdown for this example
    //it does something every millisecond
    //first value is number of ticks second is the size 1 = 1ms 1000=1s
    new CountDownTimer(1000000, 1) {

        public void onTick(long millisUntilFinished) {

            //get the image view
            ImageView thing = (ImageView) findViewById(R.id.thing);
            int x = (int) thing.getX();
            int y = (int) thing.getY();


            moveThing(x, y, (int) touchX, (int) touchY);


        }

        public void onFinish() {

        }
    }.start();

}

private void moveThing(int xCoord, int yCoord, int targetX, int targetY) {

    //adjust these values to center
    ImageView thing = (ImageView) findViewById(R.id.thing);
    targetX = targetX - thing.getWidth() / 2;
    targetY = targetY - thing.getHeight() / 2;

    int width = thing.getWidth();
    int height = thing.getHeight();

    //for recording intended position
    int tempX = 0;
    int tempY = 0;

    //check so don't run if don't have to.
    if (xCoord != targetX) {
        boolean lessX = false;

        //set value to move forward
        int x = xCoord + xSpeed;

        //but if has to move backwards set the value to move backwards
        if (targetX < xCoord) {
            x = xCoord - xSpeed;
            lessX = true;

        }

        //if the amount of pixes goes over the target set it to the target
        if (lessX == false && x > targetX) {
            x = targetX;

        } else if (lessX == true && x < targetX) {
            x = targetX;

        }

        //check x bounds
        int temp = checkXBounds(x, width, leftBound, rightBound);
        if(temp != -1){
            x = temp;

        }

        //draw the thing in the new location
        if (xCoord < targetX || (xCoord > targetX && lessX == true)) {
            thing.setX(x);

        }
        tempX = (int) x;


    }

    //check so don't run if don't have to.
    if (yCoord != targetY) {

        //set value to move forward
        int y = yCoord + ySpeed;
        boolean lessY = false;

        //but if has to move backwards set the value to move backwards
        if (targetY < yCoord) {
            y = yCoord - ySpeed;
            lessY = true;

        }

        //if the amount of pixes goes over the target set it to the target
        if (y > targetY && lessY == false) {
            y = targetY;

        } else if (y < targetY && lessY == true) {
            y = targetY;

        }

        //check y bounds
        int temp = checkYBounds(y, topBound, bottomBound, height);
        if(temp != -1){
            y = temp;

        }

        //draw the thing in the new location
        if (yCoord < targetY || (yCoord > targetY && lessY == true)) {
            thing.setY(y);

        }

        tempY = (int) y;
    }


    TextView textView = (TextView) findViewById(R.id.coords);
    textView.setText("x: " + tempX + " " + "y: " + tempY);

}

private int checkXBounds(int xCoord, int width, int leftBound, int rightBound){

    if(checkLeftBound(xCoord, leftBound) == false){
        return leftBound;

    }
    if(checkRightBound(xCoord, rightBound, width) == false){
        return rightBound - width;

    }

    return -1;
}

private int checkYBounds(int yCoord, int topBound, int bottomBound, int height){

    if(checkTopBound(yCoord, topBound) == false){
        return topBound;

    }

    if(checkBottomBound(yCoord, bottomBound, height) == false){
        return bottomBound - height;

    }

    return -1;
}

private boolean checkLeftBound(int xCoord, int leftBound) {
    if(xCoord < leftBound){
        return false;

    }

    return true;
}

private boolean checkRightBound(int xCoord, int rightBound, int width){
    if(xCoord + width > rightBound){
        return false;

    }

    return true;
}

private boolean checkTopBound(int yCoord, int topBound){
    if(yCoord < topBound){
        return false;

    }

    return true;
}

private boolean checkBottomBound(int yCoord, int bottomBound, int height){
    if(yCoord + height > bottomBound){
        return false;

    }

    return true;
}


//gets touch coordinates and handles moving the ship
@Override
public boolean onTouchEvent(MotionEvent event) {

    //get the touch coordinates
    touchX = event.getX();
    touchY = event.getY();


    return super.onTouchEvent(event);

}

}

这是XML文件。在真正的游戏中,我不会这样做船。您需要更改一些XML才能使其正常工作。此外,您将需要以不同的方式设置图像视图的大小,因为硬编码像我这样的值是不好的。我是为了速度而做的。

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.honeymanappdev.bradleyhoneyman.moveaimageviewbasedonusertouch.MainActivity">

<ImageView
    android:id="@+id/thing"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:src="@drawable/grey_star"/>

<TextView
    android:id="@+id/coords"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"/>

我建议使用其他内容来加载您的位图。

答案 1 :(得分:1)

我读过这篇文章,并建议使用Picasso加载你的位图。这是一项了不起的服务。它也是开源的。