1

I have created a Tetris game on android and I don't think the animation is as good as it could be. When blocks are moving fast (100ms between the ticks), it's a pretty obvious flicker in the animation, as if there's a very short moment where you can see traces of the previous position of the moving block.

Here is the animation loop, implemented in a separate thread as an extension of SurfaceView:

public void run() 
{       
    while(running)
    {
        if(surfaceHolder.getSurface().isValid()) 
        {
            sleep(1);
            canvas = surfaceHolder.lockCanvas();

            canvas.drawColor(Color.BLACK); //reset canvas


            int width = canvas.getWidth();
            int squareSpaceW = (width/4)*3;
            int squareSize = squareSpaceW/10;
            squareSpaceW = squareSize*10;
            int squareSpaceH = squareSpaceW*2;


            //Draw lines on the play field
            canvas.drawLine(squareSpaceW, 0, squareSpaceW, squareSpaceH, whitePaint);
            canvas.drawLine(0, squareSpaceH, squareSpaceW, squareSpaceH, whitePaint);

            //draw next piece
            int nxtPieceSize = board.getNextPiece().getBlocks().size() -1;
            while(nxtPieceSize >= 0) 
            {
                rectPaint.setColor(Color.parseColor(board.getNextPiece().getBlocks().get(nxtPieceSize).getColor()));
                int x = board.getNextPiece().getCoordList().get(nxtPieceSize).getX();
                int y = board.getNextPiece().getCoordList().get(nxtPieceSize).getY();
                nxtPieceSize--;
                rect.set(x*(squareSize/2) + (squareSpaceW/17)*16, y*(squareSize/2) + (squareSize/2), x*(squareSize/2) + (squareSize/2) + (squareSpaceW/17)*16, y*(squareSize/2)+ (squareSize/2) + (squareSize/2));
                canvas.drawRect(rect, rectPaint);
            }

            //draw text
            canvas.drawText("Score: " + Integer.toString(board.getScore()), width - (width/8), (width/8) + (squareSize), whitePaint);
            canvas.drawText("Level: " + Integer.toString(board.getLevel()), width - (width/8), (width/8) + (squareSize*2), whitePaint);

            //draw the blocks
            for(int x = 0; x < board.getWidth(); x++) 
            {
                for(int y = 0; y < board.getHeight(); y++)
                {
                    tempBlock = board.getBlock(x, y);
                    if(tempBlock != null)
                    {
                        rectPaint.setColor(Color.parseColor(tempBlock.getColor()));
                        rect.set(x*squareSize, y*squareSize, x*squareSize + squareSize, y*squareSize+ squareSize);
                        canvas.drawRect(rect, rectPaint);

                    }
                }
            }

            //draw pause icon
            rect.set(squareSize/2,squareSize/2, (squareSize/4)*3, squareSize + squareSize/2);
            canvas.drawRect(rect, whitePaint);  
            rect.set(squareSize ,squareSize/2, squareSize + squareSize/4, squareSize + squareSize/2);
            canvas.drawRect(rect, whitePaint);


            surfaceHolder.unlockCanvasAndPost(canvas);
        }
    }
}

Hope I have given the information you need. Sorry if the code is a bit messy...

user3357751
  • 101
  • 1
  • 10
  • Get the new calls out of your drawing method, create one rect as class variable and use rect.set() with the new values. – ElDuderino Mar 25 '14 at 15:17
  • Tried it now, didn't solve it. – user3357751 Mar 25 '14 at 15:26
  • get the sleep(1) out, and any other sleep call in your program? – ElDuderino Mar 25 '14 at 15:46
  • I tried that now, didn't do it either. Other sleep calls? In the whole program or just in the thread? I use it in other parts of the program but not in this thread. I need it in other parts so that I can time the moves correctly. – user3357751 Mar 25 '14 at 15:51
  • Nope, you don't need sleep(), and by no means for control flow. Better think of another approach. I don't know how much time methods like getNextPiece().getCoordList() and getBlock() take, maybe these take too long. Did you measure the time needed for a drawing call? – ElDuderino Mar 25 '14 at 16:03
  • What I mean is that I use it so that the pieces move down with the right time interval, e.g. 100ms if it's moving down fast. How am I supposed to wait 100ms if not through sleep? In either case, I don't see how my problem has anything to do with the code presented here take too long since that alone shouldn't create traces in the moving piece. If it would take too long, to me it seems like the problem rather would be that the animation would appear unsynchronized and/or laggy, which it doesn't at all. – user3357751 Mar 25 '14 at 17:39
  • Another thing I suspected was that the animation thread would use the the board with the blocks during the time the game mechanism edited the board, so that the blocks wouldn't be correctly represented at some very small time intervals. This doesn't seem to be a problem either, since I've fixed so that the animation thread never use anything but a correct representation of the board. This is why I wonder if there's something I haven't understood about the way SurfaceView works. – user3357751 Mar 25 '14 at 17:43
  • http://stackoverflow.com/questions/21838523/annoying-lags-stutters-in-an-android-game#22387533 – fadden Mar 25 '14 at 19:24
  • @fadden maybe I didn't get everything you were trying to say, but I don't think that my problem is that the frames are unsynchronized. There isn't any delay at all, what I find strange is that I can see traces of the previous block even though I in every frame reset the canvas with a black background. I don't know... maybe this is natural since the piece is moving fast with such big steps over the screen, not a continuous gliding object. I have followed the advice to take away the sleep function though, it's fairly obvious to me now how slow it is anyway. – user3357751 Mar 26 '14 at 00:58
  • If you can run it on a device with Android 4.4, record it with "screenrecord". If you see weird artifacts in the recording, you can examine them frame-by-frame. – fadden Mar 26 '14 at 01:02

0 Answers0