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

使用C与raylib实现康威生命游戏时,大于30x30的网格显示异常

康威生命游戏网格渲染异常问题

我用C语言+raylib实现康威生命游戏,30x30网格运行正常,但调整到40x40、100x100等更大尺寸时,屏幕只显示一半网格,另一半空白,程序运行异常。

核心问题分析

  1. 渲染顺序错误:raylib的所有DrawXXX渲染函数必须放在BeginDrawing()和EndDrawing()之间才能正确输出到屏幕,原代码把绘制逻辑放在了这对函数之外,小尺寸时偶然能显示,大尺寸下渲染缓冲区的问题彻底暴露。
  2. 整数除法精度丢失:当屏幕宽高无法被网格行列数整除时,screenWidth / ROWS的整数除法会导致单元格尺寸偏小,总渲染宽度/高度不足屏幕大小,出现空白区域。
  3. 鼠标交互逻辑冗余:原代码用mouseC变量控制状态切换,容易出现逻辑混乱,且点击位置的映射虽然数值上没问题,但逻辑可以更简洁。

修复后的完整代码

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include "raylib.h"
#include "raymath.h"

int main()
{   
    int up, down, left, right;
    int life;
    int k, i, j;
    int COLS = 100;  // 可随意调整更大尺寸
    int ROWS = 100;
    int spaceC = 0;
    int screenWidth = 600;
    int screenHeight = 600;
    // 向上取整计算单元格尺寸,避免总尺寸不足屏幕
    int cellWidth = (screenWidth + ROWS - 1) / ROWS;
    int cellHeight = (screenHeight + COLS - 1) / COLS;
    int mat[ROWS][COLS];
    int buffer[ROWS][COLS];

    SetTargetFPS(60);
    InitWindow(screenWidth, screenHeight, "Conway's Game of Life");
    
    // 初始化全死细胞
    for (i = 0; i < ROWS; i++)
    {
        for (j = 0; j < COLS; j++)
        {
            mat[i][j] = 0;
        }
    }

    while (!WindowShouldClose())
    {
        BeginDrawing();
        ClearBackground(RAYWHITE);

        // 绘制网格与细胞
        for (i = 0; i < ROWS; i++)
        {
            for (j = 0; j < COLS; j++)
            {
                if (mat[i][j] == 1)
                {
                    DrawRectangle(i * cellWidth, j * cellHeight, cellWidth, cellHeight, BLACK);
                }
                DrawRectangleLines(i * cellWidth, j * cellHeight, cellWidth, cellHeight, GRAY);
            }
        }

        // 鼠标点击切换细胞状态
        if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
        {
            Vector2 mPos = GetMousePosition();
            int x = mPos.x / cellWidth;
            int y = mPos.y / cellHeight;
            if (x >= 0 && x < ROWS && y >= 0 && y < COLS)
            {
                mat[x][y] = !mat[x][y];
            }
        }

        // 空格键启停游戏
        if (IsKeyPressed(KEY_SPACE))
        {
            spaceC++;
            SetTargetFPS(spaceC % 2 != 0 ? 4 : 60);
        }

        // 生命游戏迭代逻辑
        if (spaceC % 2 != 0)
        {
            for (i = 0; i < ROWS; i++)
            {
                for (j = 0; j < COLS; j++)
                {
                    right = (j + 1) % COLS;
                    left = ((j - 1) + COLS) % COLS;
                    up = ((i - 1) + ROWS) % ROWS;
                    down = (i + 1) % ROWS;

                    life = mat[down][j] + mat[i][left] + mat[up][left] + mat[up][j] + 
                           mat[up][right] + mat[i][right] + mat[down][right] + mat[down][left];

                    if (mat[i][j] == 1)
                    {
                        buffer[i][j] = (life == 2 || life == 3) ? 1 : 0;
                    }
                    else
                    {
                        buffer[i][j] = (life == 3) ? 1 : 0;
                    }
                }
            }

            // 更新当前网格状态
            for (i = 0; i < ROWS; i++)
            {
                for (j = 0; j < COLS; j++)
                {
                    mat[i][j] = buffer[i][j];
                }
            }
        }

        EndDrawing();
    }

    CloseWindow();
    return 0;
}

关键修复说明

  • 渲染逻辑修正:将所有绘制操作移到BeginDrawing()和EndDrawing()之间,符合raylib的渲染流程要求。
  • 单元格尺寸优化:用(屏幕尺寸 + 网格数量 - 1) / 网格数量实现向上取整,确保单元格总尺寸完全覆盖屏幕,消除空白。
  • 交互逻辑简化:直接用取反操作切换细胞状态,去掉冗余的mouseC变量,避免逻辑混乱。
  • 帧率控制优化:启停游戏时同步调整帧率,逻辑更清晰。

内容的提问来源于stack exchange,提问作者IllTime00qw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:37:49