Android SurfaceView отображается пустым, когда заблокированный холст не является нулевым - PullRequest
0 голосов
/ 07 августа 2011

Я создаю простую игру, используя вид, который расширяет SurfaceView, и использую поток для рисования изображений в SurfaceView.В игре будет свой собственный поток (игровой движок) для рисования и обновления рисунков.

У меня есть 3 класса для достижения этой цели, а именно BattleActivity, BattleView и BattleThread.BattleActivity вызывается из другого действия.BattleThread вызовет BattleView.update () и BattleView.render () для выполнения этой работы.Но я не вижу ничего работающего.Я знаю, что все это достижимо путем регистрации и отладки (что я пробовал), но я все еще не могу понять, что является неправильным.Кто-нибудь хочет мне помочь?


public class BattleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // Making it full screen
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    //... shortened

    // Create the battle view
    battleView = new BattleView(this);
    battleView.setBackground(battleBackground);
    setContentView(battleView);
}}

BattleView:

public class BattleView  extends SurfaceView implements SurfaceHolder.Callback{
//... shortened

public BattleView(Context context) 
{
    super(context);
    getHolder().addCallback(this);
    // Surface has been created
    battleThread = new BattleThread(getHolder(), this); 
    setFocusable(true);
}

public synchronized void render(Canvas canvas) 
{
    // this function is called when I do debugging, but no image is shown
    // canvas and background is not null
    canvas.drawBitmap(background, 0, 0, null);
}

public synchronized void update()
{
    monsterState = leftMonster.update();
    //... shortened
    rightMonster.update();
}

@Override
public void surfaceCreated(SurfaceHolder holder) 
{
    // Start the thread
    battleThread.setRunning(true);
    battleThread.start();
}}

BattleThread:

public class BattleThread extends Thread {
public BattleThread(SurfaceHolder surfaceHolder, BattleView battleView)
{
    super();
    this.surfaceHolder = surfaceHolder;
    this.battleView = battleView;
}

@Override
public void run() 
{
    Canvas canvas;
    //... shortened

    while (running) 
    {
        canvas = null;
        // try locking the canvas for exclusive pixel editing
        // in the surface
        try 
        {
            canvas = this.surfaceHolder.lockCanvas();
            synchronized (surfaceHolder) 
            {
                beginTime = System.currentTimeMillis();
                framesSkipped = 0;  // resetting the frames skipped
                // update game state 
                this.battleView.update();

                beginTime = System.currentTimeMillis();
                // render it
                this.battleView.render(canvas);             

                //... shortened
            }
        }
        finally 
        {
            if (canvas != null) 
            {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }   // end finally
    }
}

}

Ответы [ 2 ]

1 голос
/ 10 июня 2014

Я знаю, что это старый пост, но на всякий случай он кому-нибудь поможет.

У меня была такая же проблема, почти идентичный вашему коду, и я обнаружил, что все, что мне нужно было сделать, это позвонить postInvalidate() из моего переопределенного onDraw(Canvas canvas) метода в моем SurfaceView.

Это мой код:

@Override
protected void onDraw(Canvas canvas)
{
   mPaperPlaneImage.draw(canvas);
   postInvalidate();
}
0 голосов
/ 07 августа 2011

Вам необходимо вызвать onDraw (Canvas canvas) для рендеринга вместо вашего render (), потому что onDraw работает с аппаратными экранными буферами. Проверьте второй пример Как я могу использовать анимационную структуру внутри холста?

...