下载小熊猫DEV-C++&c++图形扫雷
2026-10-24 20:31:33
发布于:湖北
rt,我来教大家如何下载下载小熊猫DEV-C++,
之所以为了下小熊猫c原因如下:
小熊猫 C(小熊猫 Dev-C++)的好处 & 理由
适合你的场景:刷 C++ 竞赛题(GESP、ACGO、洛谷) + 写 EGE/Raylib 小游戏,对比老 Dev-C++、VS、其他 IDE,优势很贴合需求:
- ✅ 自带新版编译器,刷题兼容性强
内置 MinGW64 11.5.0,支持 C17,比几十年前原版 Dev-C 的老旧编译器强很多。GESP、普及组竞赛的语法、新特性都能正常编译,不会出现 “OJ 能过、本地报错” 的情况,断点调试、语法提示、代码补全都有,查 bug 比老 Dev 舒服。 - ✅ 内置图形库 EGE、Raylib,写小游戏零配置(最大亮点)
这是最吸引你的一点。新建项目直接选 EGE/Raylib 模板,不用手动下载、配置图形库,写贪吃蛇、五子棋、打砖块这类小游戏直接写代码就能运行。
所以我让大家下载,是因为这回的扫雷游戏需要用了 Raylib 动态库
(如果你觉得下载没必要,就当乐子看,但代码是要用到 Raylib 动态库,小熊猫自带,DEV-C++没有)
官网:主站http://royqh.net/redpandacpp/
下载页:下载页http://royqh.net/redpandacpp/download/
点到下载页后点

分享码:f0tp

点第二个:小熊猫C++-3.4.win64.MinGW64_11.5.0.绿色版.7z
然后点普通下载

下载好后:

打开文件
将它拖到D盘
然后双击运行
它会弹出:

语言可自选
点了ok然后就会

可自己选择
点下一步
然后会出现这个

安装路径随你,但是作者推荐是 D 盘。
想改成 D 盘了,把路径改成:D:\RedPandaCPP
然后静静等待即可
代码区:
#include "raylib.h"
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cmath>
#include <string>
#include <vector>
// ==================== Config ====================
const int WIN_W = 1000; // 窗口宽
const int WIN_H = 760; // 窗口高
const int N = 9; // 棋盘边长 9x9
const int CS = 60; // 每格像素
const int BW = N * CS; // 棋盘总宽
const int BH = N * CS; // 棋盘总高
const int BX = (WIN_W - BW) / 2; // 棋盘左上角 X(居中)
const int BY = 140; // 棋盘左上角 Y(顶部留 140px)
// 每格状态
enum CS_State {
S_HID = 0, // 隐藏
S_OPEN = 1, // 已翻开
S_FLAG = 2, // 已标记
S_MINE = 3 // 显示为雷
};
// 单格数据
struct Cell {
bool mine; // 是否有雷
int num; // 周围雷数
int st; // 状态
bool boom; // 是否被踩爆
};
// 游戏整体状态
enum GS {
G_MENU = 0,
G_RULES,
G_SET,
G_ONE,
G_TWO,
G_OVER,
G_WIN,
G_LOG // 棋谱界面
};
// 棋谱条目
struct LogEntry {
int player; // 操作者:1 / 2(单人模式固定为 1)
int r, c; // 坐标(0~8)
int action; // 0=reveal, 1=flag, 2=unflag
int result; // 0=none, 1=empty, 2=number, 3=mine
};
// ==================== Globals ====================
// 提示消息
static std::string g_msg = "";
static float g_msgT = 0.0f;
// 棋盘和状态
static Cell bd[N][N];
static int g_state = G_MENU; // 当前界面
static int g_prevState = G_MENU; // 进入棋谱前的界面(用于返回)
static bool g_chain = false; // 连锁开关
static int g_mines = 0; // 本局总雷数
static int g_flags = 0; // 已标记数
static int g_turn = 1; // 双人模式当前回合(1/2)
static int g_winner = -1; // -1 未定;单人=0 输;双人=1/2 赢
static time_t g_t0 = 0; // 开始时间
static int g_secs = 0; // 已用秒数
static int g_mineIn = 10; // 设置里雷数
static bool g_twoP = false; // 是否双人
// 棋谱
static std::vector<LogEntry> g_log;
static int g_logScroll = 0; // 棋谱滚动位置(第一行索引)
// ==================== Utils ====================
// 显示底部提示条
static void Say(const char* s, float d = 1.5f) {
g_msg = s;
g_msgT = d;
}
// 初始化棋盘:清空 + 埋雷 + 计算周围雷数
static void NewBoard(int m) {
// 1) 清空
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
bd[i][j] = (Cell){ false, 0, S_HID, false };
// 2) 埋雷:洗牌取前 m 个(Fisher-Yates)
int total = N * N;
int* idx = new int[total];
for (int k = 0; k < total; k++) idx[k] = k;
for (int k = total - 1; k > 0; k--) {
int r = rand() % (k + 1);
int t = idx[k]; idx[k] = idx[r]; idx[r] = t;
}
for (int k = 0; k < m; k++) {
int r = idx[k] / N;
int c = idx[k] % N;
bd[r][c].mine = true;
}
delete[] idx;
// 3) 计算每个非雷格周围雷数
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (bd[i][j].mine) continue;
int c = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue;
int a = i + dx, b = j + dy;
if (a < 0 || a >= N || b < 0 || b >= N) continue;
if (bd[a][b].mine) c++;
}
}
bd[i][j].num = c;
}
}
g_mines = m;
g_flags = 0;
g_turn = 1;
g_winner = -1;
g_secs = 0;
g_t0 = time(NULL);
// 清空棋谱
g_log.clear();
g_logScroll = 0;
}
// 递归连锁翻开
static void Chain(int x, int y) {
if (x < 0 || x >= N || y < 0 || y >= N) return;
if (bd[x][y].st != S_HID) return;
if (bd[x][y].mine) return;
bd[x][y].st = S_OPEN;
if (bd[x][y].num == 0) {
for (int dx = -1; dx <= 1; dx++)
for (int dy = -1; dy <= 1; dy++)
if (dx || dy) Chain(x + dx, y + dy);
}
}
// 翻开一格,返回 true 表示踩雷
static bool Open(int x, int y) {
if (bd[x][y].st == S_FLAG || bd[x][y].st == S_OPEN) return false;
if (bd[x][y].mine) {
bd[x][y].st = S_MINE;
bd[x][y].boom = true;
return true;
}
if (bd[x][y].num == 0 && g_chain) Chain(x, y);
else bd[x][y].st = S_OPEN;
return false;
}
// 切换旗子
static void Flag(int x, int y) {
if (bd[x][y].st == S_HID) {
bd[x][y].st = S_FLAG; g_flags++;
} else if (bd[x][y].st == S_FLAG) {
bd[x][y].st = S_HID; g_flags--;
}
}
// 所有非雷格翻开 → 胜利
static bool AllOpen() {
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (!bd[i][j].mine && bd[i][j].st != S_OPEN) return false;
return true;
}
// 游戏结束:显示所有未揭开的雷
static void ShowAll() {
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (bd[i][j].mine && bd[i][j].st == S_HID)
bd[i][j].st = S_MINE;
}
// ==================== Drawing ====================
// 经典扫雷数字配色
static Color NumColor(int n) {
switch (n) {
case 1: return BLUE;
case 2: return GREEN;
case 3: return RED;
case 4: return DARKBLUE;
case 5: return MAROON;
case 6: return DARKGREEN;
case 7: return BLACK;
case 8: return DARKGRAY;
}
return BLACK;
}
// 画地雷图标
static void DrawMine(int cx, int cy, int r, Color c) {
DrawCircle(cx, cy, r * 0.55f, c);
for (int i = 0; i < 8; i++) {
float a = i * (PI / 4.0f);
DrawLine(cx + (int)(cosf(a) * r * 0.40f), cy + (int)(sinf(a) * r * 0.40f),
cx + (int)(cosf(a) * r * 0.85f), cy + (int)(sinf(a) * r * 0.85f), c);
}
DrawCircle(cx - r/5, cy - r/5, r/5, WHITE);
}
// 画旗子
static void DrawFlag(int cx, int cy, int r) {
DrawLine(cx, cy - r*0.7f, cx, cy + r*0.7f, BLACK);
DrawTriangle((Vector2){ (float)cx, (float)cy - r*0.7f },
(Vector2){ (float)cx + r*0.7f, (float)cy - r*0.4f },
(Vector2){ (float)cx, (float)cy - r*0.1f }, RED);
DrawRectangle(cx - r*0.5f, cy + r*0.55f, r, r*0.25f, DARKGRAY);
}
// 绘制整个棋盘
static void DrawBoard() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int x = BX + j * CS;
int y = BY + i * CS;
Rectangle rc = { (float)x, (float)y, (float)CS, (float)CS };
Cell& c = bd[i][j];
Color bg;
switch (c.st) {
case S_HID:
case S_FLAG: bg = (Color){ 170, 170, 170, 255 }; break;
case S_OPEN: bg = (Color){ 220, 220, 220, 255 }; break;
case S_MINE: bg = c.boom
? (Color){ 255, 100, 100, 255 }
: (Color){ 200, 200, 200, 255 }; break;
default: bg = LIGHTGRAY; break;
}
DrawRectangleRec(rc, bg);
DrawRectangleLinesEx(rc, 1.0f, DARKGRAY);
int cx = x + CS / 2;
int cy = y + CS / 2;
switch (c.st) {
case S_HID:
DrawRectangle(x + 2, y + 2, CS - 4, 4, (Color){ 210, 210, 210, 255 });
DrawRectangle(x + 2, y + 2, 4, CS - 4, (Color){ 210, 210, 210, 255 });
DrawRectangle(x + 2, y + CS - 6, CS - 4, 4, (Color){ 130, 130, 130, 255 });
DrawRectangle(x + CS - 6, y + 2, 4, CS - 4, (Color){ 130, 130, 130, 255 });
break;
case S_FLAG:
DrawFlag(cx, cy, CS / 3);
break;
case S_MINE:
DrawMine(cx, cy, CS / 3, BLACK);
break;
case S_OPEN:
if (c.num > 0) {
const char* s = TextFormat("%d", c.num);
int fs = CS / 2;
int tw = MeasureText(s, fs);
DrawText(s, cx - tw/2, cy - fs/2, fs, NumColor(c.num));
}
break;
}
}
}
}
// 通用按钮
static bool Btn(Rectangle rc, const char* s, Color base = BLUE) {
Vector2 m = GetMousePosition();
bool hov = CheckCollisionPointRec(m, rc);
Color c = hov
? (Color){ (unsigned char)(base.r + 30), (unsigned char)(base.g + 30), (unsigned char)(base.b + 30), 255 }
: base;
DrawRectangleRec(rc, c);
DrawRectangleLinesEx(rc, 2.0f, DARKBLUE);
int fs = 24;
int tw = MeasureText(s, fs);
DrawText(s, (int)(rc.x + (rc.width - tw) / 2),
(int)(rc.y + (rc.height - fs) / 2), fs, WHITE);
return hov && IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
}
// 屏幕坐标 → 格子坐标
static bool PickCell(int& r, int& c) {
Vector2 m = GetMousePosition();
c = (int)((m.x - BX) / CS);
r = (int)((m.y - BY) / CS);
return r >= 0 && r < N && c >= 0 && c < N;
}
// ==================== Menu ====================
static void Menu() {
ClearBackground((Color){ 220, 230, 245, 255 });
const char* t = "MINESWEEPER";
int fs = 60;
int tw = MeasureText(t, fs);
DrawText(t, (WIN_W - tw)/2, 80, fs, (Color){ 40, 60, 120, 255 });
Rectangle b1 = { (float)(WIN_W/2 - 150), 240, 300, 60 };
Rectangle b2 = { (float)(WIN_W/2 - 150), 320, 300, 60 };
Rectangle b3 = { (float)(WIN_W/2 - 150), 400, 300, 60 };
Rectangle b4 = { (float)(WIN_W/2 - 150), 480, 300, 60 };
Rectangle b5 = { (float)(WIN_W/2 - 150), 560, 300, 60 };
if (Btn(b1, "Single Player")) { g_twoP = false; g_state = G_ONE; NewBoard(g_mineIn); }
if (Btn(b2, "Two Players")) { g_twoP = true; g_state = G_TWO; NewBoard(g_mineIn); }
if (Btn(b3, "Rules")) g_state = G_RULES;
if (Btn(b4, "Settings")) g_state = G_SET;
if (Btn(b5, "Quit")) { CloseWindow(); exit(0); }
DrawText("Left click: reveal | Right click: flag", 20, WIN_H - 40, 20, DARKGRAY);
DrawText(TextFormat("Chain mode: %s", g_chain ? "ON" : "OFF"), WIN_W - 260, WIN_H - 40, 20, DARKGRAY);
}
// ==================== Rules ====================
static void Rules() {
ClearBackground((Color){ 245, 240, 230, 255 });
DrawText("RULES", 40, 30, 40, (Color){ 40, 60, 120, 255 });
static const char* L[] = {
"1. Left click: reveal a cell.",
"2. Right click: place/remove a flag.",
"3. Revealing an empty cell auto-opens neighbors (if chain mode is ON).",
"4. A number n means there are n mines in the 8 surrounding cells.",
"5. Revealing a mine ends the game.",
"6. Single player: reveal all non-mine cells to win.",
"7. Two players: alternate turns. Whoever reveals a mine loses.",
"8. Flagging does NOT switch turn. Revealing DOES switch turn.",
"9. If all non-mine cells are revealed without hitting a mine: draw.",
"10. After the game ends, click View Log to see all your moves."
};
for (int i = 0; i < 10; i++)
DrawText(L[i], 60, 100 + i * 38, 22, DARKGRAY);
Rectangle b = { 40, (float)(WIN_H - 80), 160, 50 };
if (Btn(b, "Back")) g_state = G_MENU;
}
// ==================== Settings ====================
static void Settings() {
ClearBackground((Color){ 230, 240, 230, 255 });
DrawText("SETTINGS", 40, 30, 40, (Color){ 40, 60, 120, 255 });
DrawText("Chain reveal:", 60, 130, 28, DARKGRAY);
Rectangle on = { 260, 125, 100, 50 };
Rectangle off = { 380, 125, 100, 50 };
if (Btn(on, "ON", g_chain ? (Color){ 60, 160, 60, 255 } : (Color){ 120, 120, 120, 255 }))
g_chain = true;
if (Btn(off, "OFF", !g_chain ? (Color){ 60, 160, 60, 255 } : (Color){ 120, 120, 120, 255 }))
g_chain = false;
DrawText("Mine count (1-80):", 60, 230, 28, DARKGRAY);
Rectangle mi = { 340, 225, 50, 50 };
Rectangle pl = { 480, 225, 50, 50 };
if (Btn(mi, "-")) g_mineIn = (g_mineIn > 1) ? g_mineIn - 1 : 1;
if (Btn(pl, "+")) g_mineIn = (g_mineIn < 80) ? g_mineIn + 1 : 80;
DrawText(TextFormat("%d", g_mineIn), 410, 230, 36, (Color){ 40, 60, 120, 255 });
Rectangle b = { 40, (float)(WIN_H - 80), 160, 50 };
if (Btn(b, "Back")) g_state = G_MENU;
}
// ==================== Game ====================
static void HUD() {
DrawRectangle(0, 0, WIN_W, 130, (Color){ 50, 70, 110, 255 });
DrawText(g_twoP ? "TWO PLAYERS" : "SINGLE PLAYER", 20, 15, 28, WHITE);
if (g_twoP) {
Color tc = (g_turn == 1) ? (Color){ 255, 200, 100, 255 }
: (Color){ 100, 200, 255, 255 };
DrawText(TextFormat("Current turn: Player %d", g_turn), 20, 55, 28, tc);
} else {
DrawText(TextFormat("Time: %d s", g_secs), 20, 55, 28, WHITE);
}
DrawText(TextFormat("Mines left: %d", g_mines - g_flags), WIN_W - 250, 15, 28, WHITE);
DrawText(TextFormat("Total mines: %d", g_mines), WIN_W - 250, 55, 28, WHITE);
Rectangle b = { (float)(WIN_W - 130), 90, 110, 30 };
if (Btn(b, "Menu", (Color){ 160, 60, 60, 255 })) g_state = G_MENU;
}
static void Input() {
int r, c;
// 左键:翻开 / 取消标记
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (PickCell(r, c)) {
Cell& p = bd[r][c];
int player = g_twoP ? g_turn : 1; // 记日志前先抓当前玩家
if (p.st == S_FLAG) {
// 取消标记
LogEntry e;
e.player = player; e.r = r; e.c = c;
e.action = 2; e.result = 0;
g_log.push_back(e);
p.st = S_HID; g_flags--;
} else if (p.st == S_HID) {
bool hit = Open(r, c);
LogEntry e;
e.player = player; e.r = r; e.c = c;
e.action = 0;
if (hit) {
e.result = 3; // 踩雷
g_log.push_back(e);
ShowAll();
g_state = G_OVER;
g_winner = g_twoP ? (g_turn == 1 ? 2 : 1) : 0;
} else {
// 判断翻开的是什么
if (bd[r][c].num == 0) e.result = 1; // 空格
else e.result = 2; // 数字
g_log.push_back(e);
if (g_twoP) g_turn = 3 - g_turn;
if (AllOpen()) g_state = G_WIN;
}
}
}
}
// 右键:标记 / 取消标记
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) {
if (PickCell(r, c)) {
Cell& p = bd[r][c];
if (p.st == S_HID || p.st == S_FLAG) {
LogEntry e;
e.player = g_twoP ? g_turn : 1;
e.r = r; e.c = c;
e.action = (p.st == S_HID) ? 1 : 2; // 标记 / 取消
e.result = 0;
g_log.push_back(e);
Flag(r, c);
}
}
}
}
static void Game() {
ClearBackground((Color){ 200, 215, 235, 255 });
g_secs = (int)(time(NULL) - g_t0);
HUD();
DrawBoard();
Input();
}
// ==================== End Screens ====================
// 结束界面共用的三个按钮:再来 / 看棋谱 / 返回菜单
static void EndButtons() {
Rectangle a = { 40, (float)(WIN_H - 200), 200, 60 };
Rectangle b = { 260, (float)(WIN_H - 200), 200, 60 };
Rectangle c = { 480, (float)(WIN_H - 200), 200, 60 };
if (Btn(a, "Play again", (Color){ 60, 140, 60, 255 })) {
NewBoard(g_mineIn);
g_state = g_twoP ? G_TWO : G_ONE;
}
if (Btn(b, "View Log", (Color){ 200, 150, 60, 255 })) {
g_prevState = g_state; // 记住从哪来的
g_logScroll = 0;
g_state = G_LOG;
}
if (Btn(c, "Main menu", (Color){ 80, 80, 160, 255 })) {
g_state = G_MENU;
}
}
static void Over() {
ClearBackground((Color){ 240, 220, 220, 255 });
DrawText("GAME OVER", 60, 40, 60, (Color){ 160, 40, 40, 255 });
if (g_twoP) {
DrawText(g_winner == 1 ? "Player 1 wins!" : "Player 2 wins!",
60, 140, 40, (Color){ 40, 120, 40, 255 });
} else {
DrawText("You hit a mine!", 60, 140, 40, (Color){ 160, 40, 40, 255 });
}
DrawText(TextFormat("Time: %d s", g_secs), 60, 200, 28, DARKGRAY);
EndButtons();
}
static void WinScreen() {
ClearBackground((Color){ 220, 240, 220, 255 });
DrawText("YOU WIN!", 60, 40, 60, (Color){ 40, 140, 40, 255 });
if (g_twoP) {
DrawText("Draw!", 60, 140, 40, (Color){ 40, 100, 200, 255 });
DrawText("All safe cells revealed, no one hit a mine.", 60, 190, 22, DARKGRAY);
} else {
DrawText("All safe cells revealed!", 60, 140, 40, (Color){ 40, 140, 40, 255 });
}
DrawText(TextFormat("Time: %d s", g_secs), 60, 250, 28, DARKGRAY);
EndButtons();
}
// ==================== Log Screen ====================
// 棋谱界面:滚动列表显示所有操作
// 原理:
// 1. 用 BeginScissorMode 把绘制区域限制在列表矩形内
// 2. g_logScroll 表示"从第几条开始画"
// 3. 每行 30px,鼠标滚轮修改 g_logScroll
static void LogScreen() {
ClearBackground((Color){ 245, 245, 235, 255 });
DrawText("GAME LOG", 40, 25, 40, (Color){ 40, 60, 120, 255 });
// 结果摘要
const char* sum = "";
Color sc = DARKGRAY;
if (g_twoP) {
sum = (g_winner == 1) ? "Winner: Player 1" : "Winner: Player 2";
sc = (Color){ 40, 120, 40, 255 };
} else {
sum = (g_winner == 0) ? "Result: You lost" : "Result: You won";
sc = (g_winner == 0) ? (Color){ 160, 40, 40, 255 } : (Color){ 40, 120, 40, 255 };
}
DrawText(sum, 40, 75, 26, sc);
DrawText(TextFormat("Total moves: %d", (int)g_log.size()), 500, 78, 22, DARKGRAY);
// 列表外框
Rectangle listRc = { 40, 115, (float)(WIN_W - 80), (float)(WIN_H - 220) };
DrawRectangleRec(listRc, (Color){ 255, 255, 255, 255 });
DrawRectangleLinesEx(listRc, 2.0f, GRAY);
// 表头
DrawRectangle((int)listRc.x, (int)listRc.y, (int)listRc.width, 34, (Color){ 60, 80, 120, 255 });
DrawText("Step", (int)listRc.x + 15, (int)listRc.y + 6, 22, WHITE);
DrawText("Player", (int)listRc.x + 110, (int)listRc.y + 6, 22, WHITE);
DrawText("Cell", (int)listRc.x + 230, (int)listRc.y + 6, 22, WHITE);
DrawText("Action", (int)listRc.x + 360, (int)listRc.y + 6, 22, WHITE);
DrawText("Result", (int)listRc.x + 540, (int)listRc.y + 6, 22, WHITE);
// 鼠标滚轮
float wheel = GetMouseWheelMove();
if (wheel != 0) g_logScroll -= (int)(wheel * 3); // 一次滚 3 行
int totalRows = (int)g_log.size();
int visibleRows = ((int)listRc.height - 34) / 30;
int maxScroll = totalRows - visibleRows;
if (maxScroll < 0) maxScroll = 0;
if (g_logScroll < 0) g_logScroll = 0;
if (g_logScroll > maxScroll) g_logScroll = maxScroll;
// 用 Scissor 限制绘制区域
BeginScissorMode((int)listRc.x, (int)(listRc.y + 34), (int)listRc.width, (int)(listRc.height - 34));
int rowH = 30;
for (int k = 0; k < totalRows; k++) {
int row = k - g_logScroll;
int y = (int)(listRc.y + 34 + row * rowH + 4);
// 可视范围外跳过
if (row < 0 || row >= visibleRows) continue;
LogEntry& e = g_log[k];
// 隔行浅底
if (k % 2 == 1) {
DrawRectangle((int)listRc.x + 2, y - 2, (int)listRc.width - 4, rowH - 2,
(Color){ 245, 245, 245, 255 });
}
// 动作/结果字符串
const char* aStr = (e.action == 0) ? "Reveal"
: (e.action == 1) ? "Flag"
: "Unflag";
const char* rStr = (e.result == 1) ? "empty"
: (e.result == 2) ? "number"
: (e.result == 3) ? "MINE!"
: "-";
Color rCol = (e.result == 3) ? RED : DARKGRAY;
// 玩家颜色:双人模式区分,单人固定灰
Color pCol = DARKGRAY;
if (g_twoP) pCol = (e.player == 1) ? (Color){ 200, 100, 0, 255 }
: (Color){ 0, 100, 200, 255 };
DrawText(TextFormat("%d", k + 1), (int)listRc.x + 15, y, 20, DARKGRAY);
DrawText(TextFormat("P%d", e.player), (int)listRc.x + 110, y, 20, pCol);
DrawText(TextFormat("(%d, %d)", e.r + 1, e.c + 1),
(int)listRc.x + 230, y, 20, BLACK);
DrawText(aStr, (int)listRc.x + 360, y, 20, BLACK);
DrawText(rStr, (int)listRc.x + 540, y, 20, rCol);
}
EndScissorMode();
// 滚动条
if (totalRows > visibleRows) {
float barW = 8;
float barX = listRc.x + listRc.width - barW - 4;
float barY = listRc.y + 34;
float barH = listRc.height - 34;
DrawRectangle((int)barX, (int)barY, (int)barW, (int)barH, (Color){ 220, 220, 220, 255 });
float thumbH = barH * (float)visibleRows / (float)totalRows;
float thumbY = barY + (barH - thumbH) * ((float)g_logScroll / (float)maxScroll);
DrawRectangle((int)barX, (int)thumbY, (int)barW, (int)thumbH, GRAY);
}
// 底部按钮
Rectangle back = { 40, (float)(WIN_H - 80), 160, 50 };
if (Btn(back, "Back")) g_state = g_prevState; // 回到之前的结束界面
Rectangle menu = { 220, (float)(WIN_H - 80), 160, 50 };
if (Btn(menu, "Main menu", (Color){ 80, 80, 160, 255 })) g_state = G_MENU;
DrawText("Scroll with mouse wheel", WIN_W - 320, WIN_H - 60, 20, DARKGRAY);
}
// ==================== Main ====================
int main() {
srand((unsigned)time(NULL));
InitWindow(WIN_W, WIN_H, "Minesweeper - raylib");
SetTargetFPS(60);
NewBoard(g_mineIn);
while (!WindowShouldClose()) {
if (g_msgT > 0) g_msgT -= GetFrameTime();
BeginDrawing();
switch (g_state) {
case G_MENU: Menu(); break;
case G_RULES: Rules(); break;
case G_SET: Settings(); break;
case G_ONE:
case G_TWO: Game(); break;
case G_OVER: Over(); break;
case G_WIN: WinScreen(); break;
case G_LOG: LogScreen(); break;
}
if (g_msgT > 0 && !g_msg.empty()) {
DrawRectangle(0, WIN_H - 40, WIN_W, 40, (Color){ 0, 0, 0, 180 });
int tw = MeasureText(g_msg.c_str(), 22);
DrawText(g_msg.c_str(), (WIN_W - tw)/2, WIN_H - 34, 22, WHITE);
}
EndDrawing();
}
CloseWindow();
return 0;
}
注:AI 辅助
全部评论 7
-
顶部菜单点:工具 → 选项
-
左边选择:编译器 → 编译器配置
-
点【自动检测】(第一个是放大镜图标的那个就是)
1周前 来自 湖北
1-
dddd
昨天 来自 湖北
0dd
昨天 来自 湖北
0d
昨天 来自 湖北
0dd
5天前 来自 湖北
0d
1周前 来自 湖北
0
1周前 来自 广东
0sorry
1. 顶部菜单点:工具 → 选项2. 左边选择:编译器 → 编译器配置
3. 点【自动检测】
第一个是放大镜图标的那个就是
1周前 来自 湖北
0搞完后点应用点确定,然后我们然后就可以试一下了

1周前 来自 湖北
0
是啥代码?
1周前 来自 新疆
0扫雷
1周前 来自 湖北
0哦
1周前 来自 新疆
0有兴趣吗?
1周前 来自 湖北
0



























有帮助,赞一个