1

Yesterday I asked a question pertaining to Android graphics, and now that I have the basis up and running, I've made a rendering loop inside of my custom view class.

protected void render() {
    long startTime = System.nanoTime();
    long elapsedTime;
    while (Main.running) {
        Bitmap image = Bitmap.createBitmap(Main.WIDTH, Main.HEIGHT, null); //creates new Bitmap to draw onto
        Canvas canvas = new Canvas(image); //new Canvas with the attached blank Bitmap
        long newTime = System.nanoTime();
        elapsedTime = newTime - startTime;
        if (elapsedTime >= 1000000000/60) { //if enough time has passed for it to update
            startTime = newTime;
            Main.player.render(canvas); //this renders a test object, see below
        }
        display = Bitmap.createBitmap(image); //this writes to the display Bitmap that is drawn in onDraw, see below
        invalidate(); //invoke onDraw()
    }
}

Here is the code for drawing my player image (which DOES work if I draw it once rather than in a loop.)

public void render(Canvas c) {
        int xp = (int) x;
        int yp = (int) y;
        c.drawBitmap(Images.box, xp, yp, null);
    }

And inside onDraw:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(display, 0, 0, null);
    }

If I just render the player and call invalidate() once, rather than looping it multiple times, it displays fine (and dandy). However, when I put it in the loop block it does not render.

According to my logging, the loop is functional and calls invalidate(), but it never actually enters the onDraw method during the loop.

If anybody could explain why this is happening that would be very grand, and if you need more information please let me know and I will provide.

EDIT: In my main Activity class, I have a thread for game logic and then enter the render loop with the main thread after starting the logic thread.

Thread update = new Thread() { //game logic thread
            public void run() {
                loop(); //game logic loop
            }
        };
        update.start(); //start logic thread
        surface.render(); //start render loop (surface is the name of my custom view)

I have tried making a separate thread for rendering and entering the game loop with my main thread, however that still did not work.

jamlab
  • 78
  • 6
  • 1
    What thread invokes your render method? – Michael Krause Jul 10 '17 at 19:15
  • Edited the post to include the thread. – jamlab Jul 10 '17 at 19:23
  • 1
    Calling invalidate() will not cause onDraw to be invoked right away. Also calling render() from your main thread will starve the main thread therefore making it unable to draw any updates for your UI. In looking at your code, it seems like SurfaceView might be what you want. It still allows you to draw on a Canvas, but enables you to do it from a secondary thread. – Michael Krause Jul 10 '17 at 19:45
  • Changed my class's superclass to SurfaceView, however that didn't fix anything. How should I go about using SurfaceView? – jamlab Jul 10 '17 at 21:32

0 Answers0