add a raylib template: lifegame (#176)

This commit is contained in:
Yi Jianlong 2024-01-18 10:44:05 +08:00 committed by GitHub
parent 8d056116d3
commit 4c58ebf0ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 148 additions and 0 deletions

View File

@ -0,0 +1,20 @@
[Template]
ver=2
Name=snake
Name[zh_CN]=生命游戏
Icon=raylib-lifegame.ico
Description=snake game using raylib ( https://raylib.com )
Description[zh_CN]=基于raylib的生命游戏( https://raylib.com )
Category=Game
Category[zh_CN]=游戏
[Unit0]
CName=main.cpp
C=raylib_lifegame_cpp.txt
[Project]
UnitCount=1
Type=1
IsCpp=0
linker=-lraylib -lopengl32 -lgdi32 -lwinmm
ExecEncoding=UTF-8

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,128 @@
/**
* Raylib实现的生命游戏
* 使用鼠标设置初始状态回车开始演化S单步演化 R:复位
* 生命游戏又称康威生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机
*/
#include <raylib.h>
#include <string>
class LifeGame {
public:
LifeGame(int fps = 10, std::string title = "Life Game") {
InitWindow(width, height, title.c_str());
SetTargetFPS(fps);
}
~LifeGame() { CloseWindow(); }
void run() {
while (!WindowShouldClose()) {
processKeyEvt(); // 处理键盘
processMouseEvt(); // 处理鼠标
BeginDrawing();
drawFrame(); // 绘制当前帧
EndDrawing();
updateCellStates(); // 更新细胞状态
}
}
private:
//
// @brief 处理键盘事件
//
void processKeyEvt() {
if (IsKeyPressed(KEY_ENTER)) { // 回车-运行
running = true;
}
if (IsKeyPressed(KEY_R)) { // R - 复位
running = false;
clearStates();
}
if (IsKeyPressed(KEY_S)) { // S - 单步执行
updateCellStates(true);
}
}
//
// @brief 处理鼠标事件:单击改变颜色
//
void processMouseEvt() {
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (!running) {
Vector2 vec = GetMousePosition();
int x = vec.x / cell;
int y = vec.y / cell;
state[state_index][x + 1][y + 1] = (state[state_index][x + 1][y + 1] == 1) ? 0 : 1;
}
}
}
//
// @brief 绘制当前帧
//
void drawFrame() {
for (int i = 0; i < 60; i++) {
for (int j = 0; j < 40; j++) {
Color c = state[state_index][i + 1][j + 1] ? ORANGE : DARKGRAY;
DrawRectangle(cell * i, cell * j, cell, cell, c);
DrawRectangleLines(cell * i, cell * j, cell, cell, GREEN);
}
}
}
//
// @brief 更新细胞存活状态
//
void updateCellStates(bool force = false) {
if (!force) {
if (!running) return; // 没有运行,直接返回
}
int last = state_index;
state_index = last == 1 ? 0 : 1;
for (int i = 1; i <= cell_col; i++) {
for (int j = 1; j <= cell_row; j++) {
int sum = state[last][i - 1][j - 1] + state[last][i - 1][j] + state[last][i - 1][j + 1] +
state[last][i][j - 1] + state[last][i][j + 1] + state[last][i + 1][j - 1] + state[last][i + 1][j] +
state[last][i + 1][j + 1];
if (state[last][i][j]) {
state[state_index][i][j] = (sum < 2 || sum > 3) ? 0 : 1;
} else {
state[state_index][i][j] = (sum == 3) ? 1 : 0;
}
}
}
}
//
// @brief 清除状态
//
void clearStates() {
state_index = 0;
for (int i = 1; i <= cell_col; i++) {
for (int j = 1; j <= cell_row; j++) {
state[state_index][i][j] = 0;
}
}
}
private:
static constexpr float width = 1200;
static constexpr float height = 800;
static constexpr float cell = 25;
static constexpr int cell_col = width / cell;
static constexpr int cell_row = height / cell;
char state[2][cell_col + 2][cell_row + 2] = {0};
int state_index = 0;
bool running = false;
};
int main(void) {
LifeGame game;
game.run();
return 0;
}