代码有bug,检查代码并生成完整代码
#include <graphics.h> // EasyX图形库
#include <conio.h> // 控制台输入输出
#include <string> // 字符串处理
#include <ctime> // 时间函数
#include <cmath> // 数学函数
#include <mmsystem.h> // 多媒体支持
#include <list> // 链表容器
#include <Windows.h> // Windows API
#pragma comment(lib, "winmm.lib") // 多媒体库链接
using namespace std;
// 游戏常量定义
const int PASS_COUNT = 8; // 总关卡数
const int WINDOW_WIDTH = 953; // 窗口宽度
const int WINDOW_HEIGHT = 453; // 窗口高度
const int PUZZLE_WIDTH = 600; // 拼图区域宽度
const int PUZZLE_HEIGHT = 450; // 拼图区域高度
const COLORREF BG_COLOR = LIGHTGREEN; // 背景颜色
// 拼图块结构体
struct PuzzlePiece {
IMAGE image; // 图像对象
int gridX; // 网格X坐标
int gridY; // 网格Y坐标
int correctX; // 正确位置X坐标
int correctY; // 正确位置Y坐标
};
// 游戏框架类
class GameFramework {
public:
GameFramework(); // 构造函数
void DrawBackground(); // 绘制背景
void ShowStartMenu(); // 显示开始菜单
};
// 拼图游戏类
class PuzzleGame {
private:
IMAGE fullImage; // 完整图像
list<PuzzlePiece> puzzlePieces; // 拼图块链表
int gameState; // 游戏状态 (0:选择难度, 1:设置拼图, 2:显示拼图, 3:游戏进行中)
int difficulty; // 难度级别 (3:3x3, 4:4x4, 5:5x5)
int currentLevel; // 当前关卡 (0-7)
int pieceWidth; // 拼图块宽度
极 pieceHeight; // 拼图块高度
string imagePath; // 图片路径
int emptyX, emptyY; // 空白块位置
// 难度选择区域
RECT rectEasy = { 300, 210, 500, 240 };
RECT rectMedium = { 300, 270, 500, 300 };
RECT rectHard = { 300, 330, 500, 360 };
// 查找特定位置的拼图块
list<PuzzlePiece>::iterator FindPieceAtPosition(int x, int y) {
for (auto it = puzzlePieces.begin(); it != puzzlePieces.end(); ++it) {
if (it->gridX == x && it->gridY == y) {
return it;
}
}
return puzzlePieces.end(); // 未找到
}
public:
PuzzleGame(); // 构造函数
void Run(); // 游戏主循环
void SetDifficulty(); // 设置难度
void SetupPuzzle(); // 设置拼图
void DrawPuzzle(); // 绘制拼图
void HandleMouse(); // 处理鼠标事件
void MovePiece(int gridX, int gridY); // 移动拼图块
void CheckCompletion(); // 检查是否完成
void ShufflePuzzle(); // 打乱拼图
};
// 游戏框架构造函数
GameFramework::GameFramework() {
initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); // 初始化图形窗口
setbkcolor(BG_COLOR); // 设置背景颜色
cleardevice(); // 清屏
}
// 绘制背景
void GameFramework::DrawBackground() {
// 加载背景图片
IMAGE bgImg;
// 修复1: 确保正确加载背景图片
if (loadimage(&bgImg, _T("Res\\123.jpg"), WINDOW_WIDTH, WINDOW_HEIGHT) == 0) {
// 如果加载失败,使用纯色背景
setbkcolor(LIGHTGREEN);
cleardevice();
} else {
putimage(0, 0, &bgImg);
}
}
// 显示开始菜单
void GameFramework::ShowStartMenu() {
setbkmode(TRANSPARENT); // 设置透明背景
settextcolor(BLUE); // 设置文本颜色
// 显示游戏标题
settextstyle(30, 0, _T("华文行楷"));
outtextxy(230, 85, _T("欢迎来到拼图游戏"));
// 显示难度选择提示
settextstyle(23, 0, _T("华文行楷"));
outtextxy(300, 170, _T("选择游戏难度:"));
outtextxy(300, 210, _T("<A> 简单 (3x3)"));
outtextxy(300, 270, _T("<B> 中等 (4x4)"));
outtextxy(300, 330, _T("<C> 困难 (5x5)"));
// 绘制菜单边框
setlinestyle(PS_SOLID, 5, NULL);
setlinecolor(BLUE);
rectangle(200, 50, 600, 400);
line(200, 150, 600, 150);
}
// 拼图游戏构造函数
PuzzleGame::PuzzleGame() {
gameState = 0; // 初始状态:选择难度
difficulty = 0; // 未选择难度
currentLevel = 0; // 初始关卡
imagePath = "Res\\00.jpg"; // 初始图片路径
pieceWidth = 0; // 初始拼图块宽度
pieceHeight = 0; // 初始拼图块高度
emptyX = 0; // 空白块X位置
emptyY = 0; // 空白块Y位置
}
// 游戏主循环
void PuzzleGame::Run() {
switch (game极State) {
case 0: // 选择难度
SetDifficulty();
break;
case 1: // 设置拼图
SetupPuzzle();
break;
case 2: // 显示拼图
DrawPuzzle();
break;
case 3: // 游戏进行中
HandleMouse();
CheckCompletion();
break;
default:
break;
}
}
// 设置游戏难度
void PuzzleGame::SetDifficulty() {
// 检测键盘输入
if (_kbhit()) {
char input = _getch(); // 获取按键
mciSendString(_T("play Res\\key.wav"), NULL, 0, NULL); // 播放按键音效
switch (input) {
case 'a': case 'A': difficulty = 3; break; // 简单难度
case 'b': case 'B': difficulty = 4; break; // 中等难度
case 'c': case 'C': difficulty = 5; break; // 困难难度
default: return; // 无效输入
}
gameState = 1; // 进入设置拼图状态
return;
}
// 检测鼠标点击
if (MouseHit()) {
MOUSEMSG mouseMsg = GetMouseMsg();
if (mouseMsg.uMsg == WM_LBUTTONDOWN) {
POINT pt = { mouseMsg.x, mouseMsg.y };
// 检查是否点击在难度选择区域
if (PtInRect(&rectEasy, pt)) {
difficulty = 3;
mciSendString(_T("play Res\\key.wav"), NULL, 0, NULL);
gameState = 1;
}
else if (PtInRect(&rectMedium, pt)) {
difficulty = 4;
mciSendString(_T("play Res\\key.wav"), NULL, 0, NULL);
gameState = 1;
}
else if (PtInRect(&rectHard, pt)) {
difficulty = 5;
mciSendString(_T("play Res\\key.wav"), NULL, 0, NULL);
gameState = 1;
}
}
}
}
// 设置拼图
void PuzzleGame::SetupPuzzle() {
// 清空链表
puzzlePieces.clear();
// 加载完整图像 - 修复2: 使用正确的路径转换
TCHAR imgPath[MAX_PATH];
// 将std::string转换为宽字符串
MultiByteToWideChar(CP_ACP, 0, imagePath.c_str(), -1, imgPath, MAX_PATH);
// 尝试加载图像
if (loadimage(&fullImage, imgPath, PUZZLE_WIDTH, PUZZLE_HEIGHT) == 0) {
// 如果加载失败,创建默认图像
fullImage.Resize(PUZZLE_WIDTH, PUZZLE_HEIGHT);
SetWorkingImage(&fullImage);
setfillcolor(WHITE);
solidrectangle(0, 0, PUZZLE_WIDTH, PUZZLE_HEIGHT);
settextcolor(BLACK);
settextstyle(30, 0, _T("宋体"));
outtextxy(150, 200, _T("图片加载失败"));
SetWorkingImage();
}
// 计算拼图块尺寸
pieceWidth = PUZZLE_WIDTH / difficulty;
pieceHeight = PUZZLE_HEIGHT / difficulty;
// 设置工作图像为完整图像
SetWorkingImage(&fullImage);
// 分割图像为拼图块并添加到链表
for (int i = 0; i < difficulty; i++) {
for (int j = 0; j < difficulty; j++) {
// 跳过右下角最后一块(空白块)
if (i == difficulty - 1 && j == difficulty - 1) {
continue;
}
PuzzlePiece piece;
// 获取拼图块图像
getimage(&piece.image,
j * pieceWidth,
i * pieceHeight,
pieceWidth,
pieceHeight);
// 设置初始位置和正确位置
piece.gridX = j;
piece.gridY = i;
piece.correctX = j;
piece.correctY = i;
puzzlePieces.push_back(piece);
}
}
// 设置空白块位置
emptyX = difficulty - 1;
emptyY = difficulty - 1;
// 恢复默认工作图像
SetWorkingImage();
// 打乱拼图
ShufflePuzzle();
gameState = 2; // 进入显示拼图状态
}
// 绘制拼图
void PuzzleGame::DrawPuzzle() {
// 清空拼图区域
setfillcolor(BG_COLOR);
solidrectangle(0, 0, PUZZLE_WIDTH, PUZZLE_HEIGHT);
// 绘制所有拼图块
for (const auto& piece : puzzlePieces) {
putimage(piece.gridX * pieceWidth,
piece.gridY * pieceHeight,
&piece.image);
}
// 绘制完整图像预览
IMAGE preview;
TCHAR imgPath[MAX_PATH];
// 将std::string转换为宽字符串
MultiByteToWideChar(CP_ACP, 0, imagePath.c_str(), -1, imgPath, MAX_PATH);
// 尝试加载预览图
if (loadimage(&preview, imgPath, 300, 225) == 0) {
// 如果加载失败,创建默认预览图
preview.Resize(300, 225);
SetWorkingImage(&preview);
setfillcolor(WHITE);
solidrectangle(0, 0, 300, 225);
settextcolor(BLACK);
settextstyle(20, 0, _T("宋体"));
outtextxy(50, 100, _T("预览图加载失败"));
SetWorkingImage();
}
setbkmode(TRANSPARENT);
settextstyle(23, 0, _T("华文行楷"));
settextcolor(BLUE);
outtextxy(740, 70, _T("完整图像"));
putimage(630, 100, &preview);
// 显示当前关卡信息
TCHAR levelInfo[256];
_stprintf_s(levelInfo, _T("第 %d / %d 关"), currentLevel + 1, PASS_COUNT);
outtextxy(730, 400, levelInfo);
// 显示游戏状态
outtextxy(700, 350, _T("当前状态: 游戏中"));
gameState = 3; // 进入游戏进行中状态
}
// 处理鼠标事件
void PuzzleGame::HandleMouse() {
if (MouseHit()) { // 检测鼠标事件
MOUSEMSG mouseMsg = GetMouseMsg(); // 获取鼠标消息
if (mouseMsg.uMsg == WM_LBUTTONDOWN) { // 左键点击
mciSendString(_T("play Res\\key.wav"), NULL, 0, NULL); // 播放按键音效
// 计算点击的网格坐标
int gridX = mouseMsg.x / pieceWidth;
int gridY = mouseMsg.y / pieceHeight;
// 检查点击位置是否有效
if (gridX < 0 || gridX >= difficulty || gridY < 0 || gridY >= difficulty) {
return;
}
// 检查是否可以移动(与空白块相邻)
bool canMove = false;
if (gridX == emptyX) {
if (abs(gridY - emptyY) == 1) canMove = true;
}
else if (gridY == emptyY) {
if (abs(gridX - emptyX) == 1) canMove = true;
}
if (canMove) {
MovePiece(gridX, gridY); // 移动拼图块
}
}
}
}
// 移动拼图块
void PuzzleGame::MovePiece(int gridX, int gridY) {
// 查找点击位置的拼图块
auto it = FindPieceAtPosition(gridX, gridY);
if (it == puzzlePieces.end()) {
return; // 未找到拼图块
}
// 更新拼图块位置
int oldX = it->gridX;
int oldY = it->gridY;
it->gridX = emptyX;
it->gridY = emptyY;
// 更新空白块位置
emptyX = oldX;
emptyY = oldY;
// 重绘拼图
DrawPuzzle();
}
// 检查是否完成拼图
void PuzzleGame::CheckCompletion() {
bool completed = true;
// 检查所有拼图块是否在正确位置
for (const auto& piece : puzzlePieces) {
if (piece.gridX != piece.correctX || piece.gridY != piece.correctY) {
completed = false;
break;
}
}
// 检查空白块位置
if (emptyX != difficulty - 1 || emptyY != difficulty - 1) {
completed = false;
}
// 如果完成当前关卡
if (completed) {
// 显示完整图像
putimage(0, 0, &fullImage);
// 显示完成信息
settextstyle(30, 0, _T("华文行楷"));
settextcolor(GREEN);
outtextxy(700, 350, _T("恭喜过关!"));
FlushBatchDraw(); // 刷新屏幕
// 播放胜利音效
mciSendString(_T("play Res\\胜利.mp3"), NULL, 0, NULL);
Sleep(3000); // 暂停3秒
// 进入下一关
currentLevel++;
if (currentLevel < PASS_COUNT) {
// 更新图片路径 - 修复3: 确保正确的文件命名
char levelStr[3];
sprintf_s(levelStr, "%02d", currentLevel); // 确保两位数格式
imagePath = "Res\\" + string(levelStr) + ".jpg";
// 重置游戏状态
gameState = 1;
}
else {
// 所有关卡完成
cleardevice();
settextstyle(50, 0, _T("华文行楷"));
outtextxy(220, 200, _T("恭喜你完成所有关卡!"));
outtextxy(300, 300, _T("游戏结束"));
FlushBatchDraw();
Sleep(5000);
gameState = 4; // 游戏结束状态
}
}
}
// 打乱拼图
void PuzzleGame::ShufflePuzzle() {
// 方向数组 (上, 左, 下, 右)
const int dx[4] = { 0, -1, 0, 1 };
const int dy[4] = { -1, 0, 1, 0 };
srand(static_cast<unsigned int>(time(NULL))); // 随机种子
// 第一阶段:螺旋移动
int steps = difficulty * 2; // 移动步数
int direction = 0; // 初始方向
for (int i = 0; i < steps; i++) {
int newX = emptyX + dx[direction];
int newY = emptyY + dy[direction];
// 检查新位置是否有效
if (newX >= 0 && newX < difficulty && newY >= 0 && newY < difficulty) {
// 查找该位置的拼图块
auto it = FindPieceAtPosition(newX, newY);
if (it != puzzlePieces.end()) {
// 交换拼图块和空白块位置
int tempX = it->gridX;
int tempY = it->gridY;
it->gridX = emptyX;
it->gridY = emptyY;
emptyX = tempX;
emptyY = tempY;
}
}
// 改变方向
direction = (direction + 1) % 4;
}
// 第二阶段:随机移动
int shuffleCount = difficulty * 30; // 随机移动次数
for (int i = 0; i < shuffleCount; i++) {
int dir = rand() % 4; // 随机方向
int newX = emptyX + dx[dir];
int newY = emptyY + dy[dir];
// 检查新位置是否有效
if (newX >= 0 && newX < difficulty && newY >= 0 && newY < difficulty) {
// 查找该位置的拼图块
auto it = FindPieceAtPosition(newX, newY);
if (it != puzzlePieces.end()) {
// 交换拼图块和空白块位置
int tempX = it->gridX;
int tempY = it->gridY;
it->gridX = emptyX;
it->gridY = emptyY;
emptyX = tempX;
emptyY = tempY;
}
}
}
}
// 主函数
int main() {
// 初始化游戏框架
GameFramework gameFramework;
gameFramework.DrawBackground();
gameFramework.ShowStartMenu();
// 初始化拼图游戏
PuzzleGame puzzleGame;
// 开启批量绘制
BeginBatchDraw();
// 游戏主循环
while (true) {
puzzleGame.Run(); // 运行游戏逻辑
// 检测ESC键退出
if (_kbhit() && _getch() == 27) {
break;
}
FlushBatchDraw(); // 刷新屏幕
Sleep(10); // 降低CPU占用
}
// 结束批量绘制
EndBatchDraw();
// 关闭图形窗口
closegraph();
return 0;
}
最新发布