1

Can anyone help me with this simple code? Why doesn't the circle move smoothly? What's wrong with it?

package chaseme;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
public class ChaseMe extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 setContentView(new SampleView(this));
}
private class SampleView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
 private Point point;
 private Thread thread;
 private SurfaceHolder holder;
 private Paint _rect;
 private Paint _circle;
 private boolean running;
 private int WIDTH;
 private int HEIGHT;
 private float radius = 20;
 public SampleView(Context context) {
 super(context);
 point = new Point(20, 20);
 _rect = new Paint();
 _rect.setColor(Color.BLACK);
 _circle = new Paint();
 _circle.setColor(Color.BLUE);
 holder = this.getHolder();
 holder.addCallback(this);
 thread = new Thread(this);
 }
 private void updateModel() {
 if(point.x > WIDTH - radius) {
 point.x = 20;
 }
 if(point.y > HEIGHT - radius) {
 point.y = 20;
 }
 point.x++;
 point.y++;
 }
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
 WIDTH = getWidth();
 HEIGHT = getHeight();
 this.setRunning(true);
 thread.start();
 }
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 boolean retry = true;
 this.setRunning(false);
 while (retry) {
 try {
 thread.join();
 retry = false;
 } 
 catch (InterruptedException e) {}
 }
 }
 private void setRunning(boolean b) {
 running = b;
 }
 @Override
 public void run() {
 while(running) {
 Canvas c = null;
 updateModel();
 try {
 c = holder.lockCanvas(null);
 // synchronized (holder) { 
 render(c);
 // }
 }
 catch(Exception e) {
 Log.e("main", e.getMessage());
 }
 finally {
 if(c!=null) {
 holder.unlockCanvasAndPost(c);
 } 
 } 
 }
 }
 private void render(Canvas c) { 
 c.drawRect(0, 0, WIDTH, HEIGHT, _rect); 
 c.drawCircle(point.x, point.y, radius , _circle);
 //c.save();
 //c.restore();
 }
}
}
Andrew Thompson
169k42 gold badges224 silver badges441 bronze badges
asked Jul 2, 2011 at 8:27
3
  • if you print some stuff in the console in render, is the frame rate good ? I wonder if your app is not running too fast as you never ask your thread to sleep between animation frames. Commented Jul 2, 2011 at 9:29
  • Well, I know what is the problem, it is the emulator runs very slow, I ran a test to see the fps, and it drops from about 20 to 10. Commented Jul 2, 2011 at 9:32
  • A device is only real world test on android. It's really the fastest way to debug an app also. I use the emulator only to test what my devices can't test (resolution, versions of sdk...). But usually I test my code on a device. Commented Jul 3, 2011 at 1:20

3 Answers 3

1

You can't just call point.x++ as you currently do. You need to calculate movement relative to elapsed time and screen size.

Step 1: At every frame, calculate how much time has passed since last frame by doing

long now = System.currentTimeMillis();
elapsed = (now - mLastTime);
totalTimeElapsed += elapsed;

and then at the end of your main loop you do

mLastTime = now;

Step 2. Get screen ratio:

screenWidth = MyClass.this.getWidth();
screenHeight = MyClass.this.getHeight();
float a = screenWidth;
float b = screenHeight;
screenRatioX = a/WIDTH_OF_YOUR_PHONE;
screenRatioY = b/HEIGTH_OF_YOUR_PHONE;

Step 3. Now you can start doing animations, for instance, if you want to move your circle from right to left:

spriteX1 = (int) ((spriteX1 + (VELOCITY*screenRatioX*elapsed))+0.5);
spriteX2 = spriteX1 + spriteWidth;

Start with a velocity of 2.0 or something and tweak from there.

Good luck!

answered Jul 2, 2011 at 10:25
Sign up to request clarification or add additional context in comments.

Comments

1

I think for smooth moving of object you should use gesture listener functionality of on touch event .

Below link may help you.

1.http://mobile.tutsplus.com/tutorials/android/android-gesture/ 2.http://stackoverflow.com/questions/937313/android-basic-gesture-detection

answered Jul 2, 2011 at 10:39

Comments

0

Have tested the code on my desire and it runs very smooth.

I suggest to test this kind of projects on real devices, the emulator can be very unpredictable and slow depending also on your cpu.

Not a big deal but you can clear your canvas with

canvas.drawColor(Color.BLACK);

instead of drawing a rectangle.

answered Jul 2, 2011 at 11:12

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.