使用C与raylib实现康威生命游戏时,大于30x30的网格显示异常
康威生命游戏网格渲染异常问题
我用C语言+raylib实现康威生命游戏,30x30网格运行正常,但调整到40x40、100x100等更大尺寸时,屏幕只显示一半网格,另一半空白,程序运行异常。
核心问题分析
- 渲染顺序错误:raylib的所有
DrawXXX渲染函数必须放在BeginDrawing()和EndDrawing()之间才能正确输出到屏幕,原代码把绘制逻辑放在了这对函数之外,小尺寸时偶然能显示,大尺寸下渲染缓冲区的问题彻底暴露。 - 整数除法精度丢失:当屏幕宽高无法被网格行列数整除时,
screenWidth / ROWS的整数除法会导致单元格尺寸偏小,总渲染宽度/高度不足屏幕大小,出现空白区域。 - 鼠标交互逻辑冗余:原代码用
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
相关产品推荐
相关产品推荐

