3D-kreativ
3D-kreativ

Reputation: 9299

How to keep the same speed of object when number of object increase?

Im doing a game and I'm using SurfaceView. In the game I have 25 small dots that are moving around. The goal is to make a game where the player draw a circle around some of the dots with the same color. My problem is that while I draw this circle and after I have lift my finger from the screen, all the dots are moving very, very slow! I guess the reason for this is all the line segmets that are being drawn constantly together with all the dots.

Is it possible to have the same moving speed of the dots all the time? I tested with SystemClock.Sleep(1) but it didn't helped much.

// Method to draw objects
private void drawObjects(Canvas canvas) {
    SystemClock.sleep(1);
    synchronized (this) {

    // Clear screen with black color
    canvas.drawRGB(0, 0, 0);

    // Draw line
    if(startDrawLine) {
        // Set properties to Paint object
        paint.setColor(Color.WHITE);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        // Draw path
        path.moveTo(touchDownX, touchDownY);
        for(Point point: points) {
            path.lineTo(point.x, point.y);
            canvas.drawPath(path, paint);
        }   
        path.reset();
    }
}
    // Call method draw() in CircleManager to draw all circles in list
    circleManager.drawCirclesInList(canvas);
}

Upvotes: 1

Views: 158

Answers (1)

Dusan
Dusan

Reputation: 5144

Slow drawing is caused by to many points in your path. If you are handling Touch event, you can expect hundreds and thousands of touches (your points) in short period of time.

  1. You need to interpolate your points somehow - take averages, ignore same and close points or something else.
  2. When you animate the "dots" your ANIMATION MUST BE BASED ON TIME, and not on the actual speed of the drawing on hardware.

To base your animation on time, you should calculate time passed since previous frame and use this time in function which calculates new position of the dot. Here is a great article on the subject: http://www.koonsolo.com/news/dewitters-gameloop/

EDIT - Response to a comment:

Suppose that your "dot" (I will call it a ball) needs to move horizontally (by X) from left to right at a constant speed of 100 units per second.

If you are doing your calculation WITH ASSUMPTION that your game will be running at 25 FPS, you simply add 4 to X on each frame.

The problem with this approach is that getting constant FPS is very hard to achieve. On the fast hardware you will be sacrificing smoothness by limiting FPS, on slow hardware you will be forced to skip drawing (drop) some frames (which can be jumpy with constant FPS).

Timer in Android is not very precise and also thread sleep functions are inaccurate. In your case, instead of trying to force the constant FPS or calculate current FPS, try to wrap your head around and rethink of your problem in a context of time.

When you think about time, it does not matter how fast is the game running (how many FPS) and what happened before.

You just need to ask a question "Where the ball should be in this moment, right now?"

If you, for example, know that ball movement stared at origin position X0 at origin time T0 then at the current moment TC ball position should be X = (TC - T0) * 100

Second approach is to measure time passed TD since last ball position update. Then the ball position should be updated like this: X = X + TD * 100

Once you get used to this approach, you will see that vast majority of animations is really trivial to implement with a great level of accuracy.

Upvotes: 1

Related Questions