0

I want to move an image on the screen and I am able to do that, but not properly. The image goes downward fine and I want it to start going upward in another direction once it has moved to the bottom of the screen.

Here is what I have tried. In the code below, margenMaXX is the width of screen and margenmaxy is height of screen

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
Thread myThread = new Thread(new UpdateThread());
        myThread.start();

public class UpdateThread implements Runnable {

            @Override
            public void run() {
                //... code to manipulate position
                while (i<margenMaxX){
                    if(j<margenmaxy) {
                    try {
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                /*mDrawable.setBounds(i, j ,i+ width, i+ height);
                                 mDrawable.draw(cc);
                                 invalidate();*/
                            }
                        });
                       Thread.sleep(200);
                        i=i+10;
                        j=j+10;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else if(j>=margenmaxy-height){
                    try {
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                /*mDrawable.setBounds(i, j ,i+ width, i+ height);
                                 mDrawable.draw(cc);
                                 invalidate();*/
                            }
                        });
                       Thread.sleep(200);
                        i=i-10;
                        j=j-10;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                }               
                }
            }

public class AnimatedView extends ImageView {



        public AnimatedView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub


            mDrawable =  new ShapeDrawable(new OvalShape());
            mDrawable.getPaint().setColor(0xffffAC23);


        }
         protected void onDraw(final Canvas cc) {
            final Context context = null;

            mDrawable.setBounds(i, j ,i+ width, i+ height);
            mDrawable.draw(cc);
            invalidate();
                    }
    }

Update 1:

Using this code, the ball is going upwards and to another side after it hits the ground. Now, I want the ball to come back when it hits the right boundary. I did coding for that but it is not coming back. My final goal is to develop a game in which the ball must come from either left or right. It must hit the ground and go in the opposite direction, hit the wall and come back. The ball must do this work as long as the game is going on.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.activity_main);
    Thread myThread = new Thread(new UpdateThread());
        myThread.start();

    public class UpdateThread implements Runnable {
    boolean mMoveDown=false;
    boolean mMoveUp = false;
        @Override
        public void run() {
            while(!mMoveUp) {
                // Move the image down and right.
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {

                        }
                    });
                   Thread.sleep(200);
                    i=i+10;
                    j=j+10;

                // Try posting a runnable to the UI thread to update the view.


                } catch (InterruptedException e) {
                    e.printStackTrace();
                }if(j >= margenmaxy)
                {
                    // Change to moving up phase.
                    mMoveUp = true;
              }

            }

            while(mMoveUp){
                try {

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                    }
                });
                Thread.sleep(200);
                i=i + 10;
                j=j - 10;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } if(i >= margenMaxX)
                {
                    // Change to moving up phase.
                    mMoveDown = true;
              } 
        }while(mMoveDown){
            try {

                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {

                    }
                });
                Thread.sleep(200);
                i=i - 10;
                j=j + 10;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        }
}

public class AnimatedView extends ImageView {



        public AnimatedView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub


            mDrawable =  new ShapeDrawable(new OvalShape());
            mDrawable.getPaint().setColor(0xffffAC23);


        }
         protected void onDraw(final Canvas cc) {
            final Context context = null;

            mDrawable.setBounds(i, j ,i+ width, j+ height);
            mDrawable.draw(cc);
            invalidate();
        }
}
nawaab saab
  • 1,892
  • 2
  • 20
  • 36
  • Hi, it seems like the view may be moving off the screen in the x direction before the y direction reverse needs to happen. Also, (j >= margenmaxy - height) includes positions in (j < margenmaxy), since margenmaxy and height are both positives. That should help you debug, if not, do post more details on what behaviour you are observing. – batbrat Mar 24 '14 at 11:58
  • @batbrat hi, the ball is not going off screen it is going good from top to down but i want when it reaches to down position it must go upward in another direction – nawaab saab Mar 24 '14 at 12:03
  • so it keeps moving down till it goes off the screen? Stops moving when the bottom of the image touches the bottom of the screen...? – batbrat Mar 24 '14 at 12:05
  • if(j=margenmaxy-height) – nawaab saab Mar 24 '14 at 12:08
  • it doesnot go out of screen as it reaches to bottom it start coming back one step and then downward, then one step upward back and then downward and it continues – nawaab saab Mar 24 '14 at 12:09
  • Ah! That is because of what I said about the conditions overlapping. The moment it hits the bottom, and moves 10 up, (j < margenmaxy) holds and (j >= margenmaxy - height) is not checked. So it gives you this "bouncing" behavior. – batbrat Mar 24 '14 at 12:11
  • yes you are right so what must i do so that the ball moves in upward opposite direction... – nawaab saab Mar 24 '14 at 12:12
  • Great, I'll post an answer. – batbrat Mar 24 '14 at 12:13
  • This isn't what I meant with my suggested edit. Please restore your original, and add this as a secondary edit, say, under the heading "EDIT 1". That said, you don't need a separate mMoveUp and mMoveDown variable. Second, this isn't what I intended. If you use what I typed, or the equivalent, you said it doesn't work. Give me exact details so I can help. Have you analysed this new code of yours? You should be able to tell why it doesn't work. – batbrat Mar 26 '14 at 06:38
  • @batbrat you saw my code the ball is going to the another direction using your code but i want it must come back when it hits the right boundary – nawaab saab Mar 26 '14 at 10:24
  • Abhi, I've edited the question for clarity's sake. I've also understood your question better. The second version of the code does not include checks for left and right movement. I really recommend against hard coding the movement of the ball in your code. Second, the logic you are using will not work for moving the ball in yet another direction. Have you looked into property animation? Another important question, what exactly is the problem that happens when you use my version of the code for up and down movement alone? – batbrat Mar 26 '14 at 11:35
  • @batbrat in your code it was if(!mMoveUp) { // Move the image down and right. i += 10; j += 10; I have just changed this to while while(!mMoveUp) { // Move the image down and right. i += 10; j += 10; – nawaab saab Mar 26 '14 at 13:12
  • yes i have studied some part of that, not completely and i will study that tonight also – nawaab saab Mar 26 '14 at 13:14
  • I'm aware of that. my if statements were wrapped by while( i < margenmaxx), so it should have worked fine. What was the cause of the ball not moving? I don't have your code in full, so I can't tell... – batbrat Mar 26 '14 at 14:04
  • @batbrat this is the complete code and the ball is moving from left side to bottom and from bottom to right....now i want that the ball must come back as it hits the right corner in the same way it has gone... – nawaab saab Mar 26 '14 at 16:05
  • Then just flip the move flag when it hits the top again. Toggle the flag at the top, and the bottom, and it will move towards the bottom, then the top, and then the bottom again. Hopefully, this is what you want. Once again, I'm requesting you to answer my question about the problem you get when using while(i < margenmaxx) { if(mMoveUp){} else {} if(j >= margenmaxy - height) {/* change flag */}} Note that this is separate from your issue of moving around again! – batbrat Mar 27 '14 at 06:49
  • @batbrat sorry but i did not understand your question and also the way you told to move the ball in your last comment... – nawaab saab Mar 27 '14 at 07:09
  • Okay, never mind that. The ball moves downwards and to the right. Then, when it hits the bottom, it moves upwards and to the left. Now, you want it to move downwards and to the right again as soon as it hits the top? Right? – batbrat Mar 27 '14 at 07:27
  • @batbrat Thanks brother with your help alot of problem of mine has been solved... i am sharing my whole updated code with you and than i discuss what i want to do further... – nawaab saab Mar 27 '14 at 07:29
  • I have updated that.... check this code the ball is going fine from left to right and coming back in the way i want but here is a very small problem that when it comes back it stops at its starting position... could you please look over this problem?? – nawaab saab Mar 27 '14 at 07:33
  • oks.. and thanks for giving your precious time... – nawaab saab Mar 27 '14 at 07:35
  • please learn to format and indent your code correctly before posting it here. Stackoverflow makes it easy, and it saves others a lot of time. I've spent way too much time formatting your code so I can read it better. I'm not seeing the image move when I run it on my end. Will analyse and reply... – batbrat Mar 27 '14 at 08:19
  • have you taken other two images in place of these....??? – nawaab saab Mar 27 '14 at 08:25
  • ok ad i am waiting of your positive reply – nawaab saab Mar 27 '14 at 08:26
  • Using the default launcher icon for the drawables, lol! *please -> Please – batbrat Mar 27 '14 at 08:26
  • You should only accept my answer after I fix the problem, and no one else has done so. :) – batbrat Mar 27 '14 at 08:28
  • ok and i didn't get "no one else has done so.." – nawaab saab Mar 27 '14 at 08:36
  • Your calculations for margenMaxX and margenmaxy contain overlapping conditions. This is a really bad idea. I don't mean to be rude, but are you completely new to programming as well as the Android platform? Secondly, getInches() gets the width in pixels. Using absolute widths and heights can get you into trouble, so you need to be careful with that. Next, You have several while statements inside one big while loop. Those should be converted to if-else statements. The outermost while loop condition should be suitably altered as well. (contd. below) – batbrat Mar 27 '14 at 09:22
  • Furthermore, it is really confusing to understand your use of mMoveUp and mMoveDown. It seems one of them really serves as an mMoveRight flag, correct? So your name should reflect that. You also need to add more comments to your code. I can't work on this right now, I'll try to get back to you when I next have time. – batbrat Mar 27 '14 at 09:23
  • @batbrat yes you are right i am new to android... i have been studying and doing work over android for a month....:) – nawaab saab Mar 27 '14 at 09:57
  • @batbrat may i know when you will be free next time...?? – nawaab saab Mar 28 '14 at 07:38

1 Answers1

0

This code has two conditional statements that overlap. However, the second one is checked only if the first fails. The second condition is:

(j >= margenmaxy - height)

This automatically implies (j < margenmaxy) Because margenmaxy, and height are both positive. When you check the condition like this:

if(j<margenmaxy) {
    // Do downward animation.

} else if(j>=margenmaxy-height){
    // Do upward animation.
}

What happens is that what you expect will happen for the phase where the image moves down. But as soon as you try move the image up, the (j < margenmaxy) condition is satisfied again, and the code tries to move the image down. The moment you move it down, the first condition is no longer valid. Since you have this construct inside a loop, it results in a "bouncing" behaviour.

To sort this problem out, you need to change the logic. One simple way to do this is to have a boolean hold the state of the animation. This state variable is changed depending on whether the image has hit the screen's bottom or not.

public class UpdateThread implements Runnable {

    // Variable to store the animation state.
    boolean mMoveUp = false;
    @Override
    public void run() {

        //... code to manipulate position
        while (i<margenMaxX) {
            // IF the animation is in the moving down phase
            if(!mMoveUp) {
                // Move the image down and right.
                i += 10;
                j += 10;

                // Try posting a runnable to the UI thread to update the view.
                try {
                    runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                            /*mDrawable.setBounds(i, j ,i+ width, i+ height);
                             mDrawable.draw(cc);
                             invalidate();*/
                    }
                    });
                    Thread.sleep(200);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } 
            // We're moving upwards.
            else {
                // Move up and left
                i -= 10;
                j -= 10;

                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            /*mDrawable.setBounds(i, j ,i+ width, i+ height);
                             mDrawable.draw(cc);
                             invalidate();*/
                        }
                    });
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } // Catch!
            } // Else! 

            // Check to see if we've hit the bottom of the screen
            if(j >= margenmaxy - height)
            {
                  // Change to moving up phase.
                  mMoveUp = true;
            }
            // Note, you can use an altered form of this to switch back and forth
            // between moving up and down.
        } // while(i < margenmaxx)!               
    } // run()!
} // UpdateThread!

As an added note, since you are moving the ball left and right, you might end up hitting those boundaries as well. You really should implement better checking for that. As a second note, this is probably not the best way to accomplish a moving image in Android. And finally, a more general solution is to use Android Property Animation with the interpolator you want. If you just want to do this once, View Animation may also suffice.

batbrat
  • 5,155
  • 3
  • 32
  • 38
  • You really should look at Property Animation... :) – batbrat Mar 24 '14 at 12:45
  • thanks for giving this code but the ball is not moving – nawaab saab Mar 24 '14 at 12:55
  • Weird, it should...Can you tell me if either condition is entered? – batbrat Mar 24 '14 at 13:13
  • its working i used while in plce of if...thanks batbrat...may i know what must i do so that the ball go in opposite direction – nawaab saab Mar 25 '14 at 06:17
  • I've created a chat room so that we don't pollute the comments section - http://chat.stackoverflow.com/rooms/50257/question-22608643-discussion-to-help-user-abhi I'd be happy to help once you join the conversation there. – batbrat Mar 25 '14 at 06:55
  • sorry i couldnot chat with you there because i must have 20 reputations to chat there that i am not having this time... – nawaab saab Mar 25 '14 at 13:13
  • D'oh! My bad. I hadn't noticed your rep. I don't understand which if you replaced with while. Kindly update your question with what you tried (keep it brief), and I'll try to help. – batbrat Mar 25 '14 at 14:16
  • i have made changes in the question above could you please solve this problem of mine... – nawaab saab Mar 26 '14 at 06:08