mmarie4
mmarie4

Reputation: 56

game rendering is very slow

I have almost finished my first game on Android. I just have a problem I cannot understand by myself. I use a basic game loop thread which update and call the draw method of the game engine I created. I noticed that the FPS were very low, so I measured the rendering time, and I saw that the drawing took 50ms (so I have approximately 20 FPS which is uncomfortable for the eyes). However, I draw only few bitmaps, it shouldn't be so long... Here is my draw method:

    public void Draw(Canvas canvas){
    width = canvas.getWidth();
    height = canvas.getHeight();
    character_rect.set(character.x, (int)(height*80.0/100), character.x+bmp_character.getWidth(), (int)(height*80.0/100)+bmp_character.getHeight());
    background_rect.set(0, 0, width, height);

    canvas.drawBitmap(bmp_background, null, background_rect, _paint);
    drawCops(canvas);
    drawGangsters(canvas);
    drawTrees(canvas);
    drawButtons(canvas);
    drawCharacter(canvas);
    _paint.setTextSize(45);
    _paint.setColor(Color.WHITE);
    canvas.drawText("Score: "+score, (float)(width*3.0/100), (float)(height*3.0/100), _paint);
    canvas.drawText("Money: "+money, (float)(width*3.0/100), (float)(height*6.0/100), _paint);
    _paint.setColor(Color.RED);
    canvas.drawRect((float)(width*3.0/100),(float)(height*8.0/100), (float)(width*3.0/100 + (current_hp*width*1.0/100)), (float)(height*10.0/100), _paint);
    if(game_over){
        gameover_rect = new Rect(0, 0, width, height);
        canvas.drawBitmap(gameover_background, null, gameover_rect, _paint);
        _paint.setColor(Color.WHITE);
        _paint.setTextSize(60);
        canvas.drawText("GAME OVER!", (int)(width*20.0/100), (int)(height*45.0/100), _paint);
        canvas.drawText("Score: "+score, (int)(width*20.0/100), (int)(height*50.0/100), _paint);
        canvas.drawText("Best score: "+character.bestScore, (int)(width*20.0/100), (int)(height*55.0/100), _paint);
        canvas.drawText("Money earned: "+money+" $", (int)(width*20.0/100), (int)(height*60.0/100), _paint);
        canvas.drawBitmap(replay_button_image, null, replay_button_rect, _paint);
    }
}

The different draw methods are very simple, for example drawCops():

    public void drawCops(Canvas canvas) {
    for(int i=0; i<cops.length; i++) {
        if(cops[i].active) {
            canvas.drawBitmap(cops[i].image, null, cops[i].box, _paint);
        }
    }
}

And here is my game loop, which is basically the same as others that I found on the net:

@Override
public void run() {
    long FPS = 40;
    long ticksPS = (long) (1000.0 / FPS);
    long startTime;
    long sleepTime;
    while (_isOnRun) {
        Canvas c = null;
        startTime = System.currentTimeMillis();
        engine.Update();
        try {
            c = _surfaceHolder.lockCanvas();
            synchronized (_surfaceHolder) {
                engine.Draw(c);
            }
        } finally {
            if (c != null) {
                _surfaceHolder.unlockCanvasAndPost(c);
            }
        }
        sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
        Log.e("tag", "render time: " + (ticksPS-sleepTime));
        try {
            if (sleepTime > 0) {
                sleep(sleepTime);
            }
            else{
                sleep(4);
            }
        } catch (Exception e) {}
    }
}

Sorry for the poor English this is not my first language.

Upvotes: 1

Views: 126

Answers (1)

mmarie4
mmarie4

Reputation: 56

Sorry, I finally found the problem by measuring how much time each line took, we can close the thread.

If someone see this thread and want to know the answer, my problem was this line:

canvas.drawBitmap(bmp_background, null, background_rect, _paint);

bmp_background and background_rect do not have the same size, so there was a bitmap scaling each time we called Draw(). I solved this by calling Bitmap.createScaledBitmap(...) to create a scaled bitmap when width or height change, and then I draw the scaled bitmap.

Upvotes: 1

Related Questions