使用Canvas时出现黑屏问题——三消游戏开发求助
解决三消游戏黑屏问题
嘿,我帮你揪出黑屏的问题啦!你的三消游戏之所以一直黑屏,主要是SurfaceView的使用姿势不对,还有Activity里的窗口设置顺序搞反了,下面给你一步步修正:
问题1:MainActivity窗口设置顺序错误
你原来的代码里先设置了全屏flag,再调用requestWindowFeature(Window.FEATURE_NO_TITLE),但这个方法必须在super.onCreate()和任何窗口设置之前调用,否则会失效(甚至可能引发异常)。先修正这部分代码:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // 必须先调用这个方法,再做其他窗口操作 this.requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); // 设置全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); GameView gameview = new GameView(this); setContentView(gameview); } }
问题2:SurfaceView绘制逻辑错误
SurfaceView和普通的View不一样,它的onDraw方法不会自动触发——因为它是在独立于UI线程的Surface上绘制的,直接重写onDraw根本不会生效。正确的做法是通过SurfaceHolder来管理Surface的生命周期,在Surface就绪时获取画布进行绘制。
修正后的GameView代码:
public class GameView extends SurfaceView implements SurfaceHolder.Callback { private int numCol, numRow; private int bWid, bHeight; private Bitmap purpleBit; private Bitmap rainbowBitmp; private Bitmap redBitmp; private SurfaceHolder holder; private Paint paint; public GameView(Context context){ super(context); // 获取SurfaceHolder并注册回调 holder = getHolder(); holder.addCallback(this); // 初始化画笔(提前初始化避免重复创建) paint = new Paint(); paint.setColor(Color.rgb(250, 0, 0)); // 设置可聚焦,方便后续处理触摸事件 setFocusable(true); } @Override public void surfaceCreated(SurfaceHolder holder) { // Surface创建完成,开始绘制内容 drawGameContent(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 屏幕尺寸变化时,重新绘制适配 drawGameContent(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // Surface销毁时,可以在这里清理线程或资源 } private void drawGameContent() { Canvas canvas = null; try { // 锁定Surface获取画布 canvas = holder.lockCanvas(); if (canvas != null) { // 先绘制白色背景 canvas.drawColor(Color.WHITE); // 绘制红色矩形测试 canvas.drawRect(100, 100, 200, 200, paint); } } finally { // 必须解锁并提交画布,否则内容不会显示 if (canvas != null) { holder.unlockCanvasAndPost(canvas); } } } }
为什么原来的代码不行?
- SurfaceView的
onDraw只有在你主动调用invalidate()时才会触发,但即使调用了,它的绘制上下文和普通View不一样,直接重写无法在Surface上显示内容。必须通过SurfaceHolder获取画布,绘制完成后提交才能显示。 - 窗口设置顺序错误会导致标题栏无法隐藏,虽然不是黑屏的直接原因,但会影响游戏的全屏体验。
现在运行修正后的代码,你应该能看到白色背景上的红色矩形啦!
内容的提问来源于stack exchange,提问作者k-lib
相关产品推荐
相关产品推荐

