-3

For an android app im coding i am trying to make it so when the users taps the screen the "player" which is an image slides over until it reaches that x value

I tried calling this method when the player touches the screen in a MotionEvent

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

then in an update method i call

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

but the image always goes past it or not far enough

Also since the image is drawn in java from the left corner when you tap infront of the image do you have to minus 1/2 the width so it stops in the middle and not the edge, and if you click behind minus 1/2 too?

  • Simple. Set onTouchListener or in view override onTouchEvent, Set layoutparams of imageview with x as touchX - imageWidth / 2 and same for the Y. – Muhammad Babar Nov 25 '16 at 05:38
  • @MuhammadBabar It seems to go over where i tap – Kingbluesapphire Nov 25 '16 at 05:50
  • The coordinates on the screen 0, 0 in top left. Then on the bottom right is the largest coord. when you pick the end destination you should subtract 1/2 the width and 1/2 the height of the image view you are moving so it centers on teh touch point. –  Nov 25 '16 at 05:52
  • if you don't want the image to go off the screen you need to do bounds checking. For example, if the x coord goes below 0, set it to 0, or if the x coord + the width of the image goes over the max x coord set the x coord to max x coord - image width. Same thing for the y coord –  Nov 25 '16 at 05:56
  • @holycatcrusher i tried this and it doesnt seem to work still, http://pastebin.com/2gtrLDpD – Kingbluesapphire Nov 25 '16 at 05:58
  • it has to do with the way the move methods are written. If you like I'll post a sample –  Nov 25 '16 at 06:00
  • @holycatcrusher that would help a lot, if you could – Kingbluesapphire Nov 25 '16 at 06:01
  • I realized my code I was going to just copy and paste is quite large. I'll post a much shorter version in a bit –  Nov 25 '16 at 06:40
  • @holycatcrusher ok then, thanks – Kingbluesapphire Nov 25 '16 at 07:17
  • try touchY + imageHeight / 2 – Muhammad Babar Nov 25 '16 at 07:21
  • @holycatcrusher For some reason its still off, it is because the way i update it? – Kingbluesapphire Nov 25 '16 at 08:15
  • I am super close to showing an example, the description you gave doesn't show how you update the position. You just show how you modify a few values that may or may not do anything –  Nov 25 '16 at 08:29
  • @Kingbluesapphire did it work? It should I tested it, but wondering if you got it working –  Nov 25 '16 at 09:45
  • @holycatcrusher I'm implementing it right now! :D – Kingbluesapphire Nov 25 '16 at 09:48

2 Answers2

2

I made a basic structure for you to use also. If you paste the code you may have to add the package name, change the activity name, change the layout name, and add a png image named grey_star to the drawable folder.

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);

}

}

This is the XML file. In a real game I would not make the ship this way. You will need to change a bit of the XML to make it work. Also, you will want to set the size of the image view a different way, because hard coding a value like I did is bad. I did it for speed.

    <?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"/>

I'd recommend using something else to load your bitmaps.

  • you could write in the image view using java, which would require you to modify the code I wrote a little bit. First I'd use the XML. Then modify –  Nov 25 '16 at 09:48
  • The thing is im not using the XML im just using java... so ill try to modify to java with the best of my knowledge – Kingbluesapphire Nov 25 '16 at 09:50
  • hmm, ok. The code works. Also in the comments I made some suggestions you should follow –  Nov 25 '16 at 09:56
  • I don't know if i messed something up but it seems to always go left, also i removed the Y stuff because i only want it to move along the X axis, sorry for bothering you http://pastebin.com/6KPwNshb – Kingbluesapphire Nov 25 '16 at 10:07
  • if it always moves left then targetX < xCoord is always. If it moves left then stops it has to do with the bounds checking, or there is a problem with the user input. –  Nov 25 '16 at 10:11
  • The user input is just from MotionEvent using event.getX – Kingbluesapphire Nov 25 '16 at 10:40
  • yup. I doubt it is the problem unless you changed it. I'll be honest though it is quite a guessing game to figure out. The best way to change code you haven't written is to copy it. Then get it working the way it was written. Once this is done make changes one at a time testing for problems after each change –  Nov 25 '16 at 10:45
0

I read this, and would recommend using Picasso to load your bitmaps. It is an amazing service. Also it is open source.