You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:30:43