将代码数组部分修改为链表
#include <graphics.h> // EasyX图形库
#include <conio.h> // 控制台输入输出
#include <string> // 字符串处理
#include <ctime> // 时间函数
#include <cmath> // 数学函数
#include <mmsystem.h> // 多媒体支持
#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坐标
};
// 游戏框架类
class GameFramework {
public:
GameFramework(); // 构造函数
void DrawBackground(); // 绘制背景
void ShowStartMenu(); // 显示开始菜单
};
// 拼图游戏类
class PuzzleGame {
private:
IMAGE fullImage; // 完整图像
PuzzlePiece** puzzlePieces; // 拼图块数组
int gameState; // 游戏状态 (0:选择难度, 1:设置拼图, 2:显示拼图, 3:游戏进行中)
int difficulty; // 难度级别 (3:3x3, 4:4x4, 5:5x5)
int currentLevel; // 当前关卡 (0-7)
int pieceWidth; // 拼图块宽度
int pieceHeight; // 拼图块高度
string imagePath; // 图片路径
int emptyX, emptyY; // 空白块位置
int** positionMap; // 位置映射表
public:
PuzzleGame(); // 构造函数
~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() {
float hue = 70.0f; // 色调
float saturation = -2.2555f; // 饱和度
float lightness = 0.525617f; // 亮度
BeginBatchDraw(); // 开始批量绘制
for (int y = 0; y < WINDOW_HEIGHT; y++) {
lightness += 0.000000085f; // 亮度渐变
saturation -= 0.0013f; // 饱和度渐变
setlinecolor(HSLtoRGB(hue, saturation, lightness)); // 设置线条颜色
line(0, y, WINDOW_WIDTH, y); // 绘制水平线
}
EndBatchDraw(); // 结束批量绘制
}
// 显示开始菜单
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位置
puzzlePieces = nullptr; // 拼图块数组
positionMap = nullptr; // 位置映射表
}
// 拼图游戏析构函数
PuzzleGame::~PuzzleGame() {
// 释放拼图块数组内存
if (puzzlePieces && difficulty > 0) {
for (int i = 0; i < difficulty; i++) {
delete[] puzzlePieces[i];
}
delete[] puzzlePieces;
}
// 释放位置映射表内存
if (positionMap && difficulty > 0) {
for (int i = 0; i < difficulty; i++) {
delete[] positionMap[i];
}
delete[] positionMap;
}
}
// 游戏主循环
void PuzzleGame::Run() {
switch (gameState) {
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; // 进入设置拼图状态
}
}
// 设置拼图
void PuzzleGame::SetupPuzzle() {
// 加载完整图像
TCHAR imgPath[256];
_stprintf_s(imgPath, _T("%S"), imagePath.c_str());
loadimage(&fullImage, imgPath, PUZZLE_WIDTH, PUZZLE_HEIGHT);
// 计算拼图块尺寸
pieceWidth = PUZZLE_WIDTH / difficulty;
pieceHeight = PUZZLE_HEIGHT / difficulty;
// 创建拼图块数组
puzzlePieces = new PuzzlePiece * [difficulty];
for (int i = 0; i < difficulty; i++) {
puzzlePieces[i] = new PuzzlePiece[difficulty];
}
// 创建位置映射表
positionMap = new int* [difficulty];
for (int i = 0; i < difficulty; i++) {
positionMap[i] = new int[difficulty];
for (int j = 0; j < difficulty; j++) {
positionMap[i][j] = i * difficulty + j;
}
}
// 设置工作图像为完整图像
SetWorkingImage(&fullImage);
// 分割图像为拼图块
for (int i = 0; i < difficulty; i++) {
for (int j = 0; j < difficulty; j++) {
// 跳过右下角最后一块(空白块)
if (i == difficulty - 1 && j == difficulty - 1) {
continue;
}
// 获取拼图块图像
getimage(&puzzlePieces[i][j].image,
j * pieceWidth,
i * pieceHeight,
pieceWidth - 3,
pieceHeight - 3);
// 设置初始位置
puzzlePieces[i][j].gridX = j;
puzzlePieces[i][j].gridY = i;
}
}
// 创建空白拼图块
puzzlePieces[difficulty - 1][difficulty - 1].image.Resize(pieceWidth - 3, pieceHeight - 3);
SetWorkingImage(&puzzlePieces[difficulty - 1][difficulty - 1].image);
// 绘制空白块的渐变背景
float hue = 50.0f;
float saturation = -3.2555f;
float lightness = 0.525617f;
for (int y = 0; y < pieceHeight; y++) {
lightness += 0.000000085f;
saturation -= 0.0015f;
setlinecolor(HSLtoRGB(hue, saturation, lightness));
line(0, y, pieceWidth, y);
}
// 设置空白块位置
puzzlePieces[difficulty - 1][difficulty - 1].gridX = difficulty - 1;
puzzlePieces[difficulty - 1][difficulty - 1].gridY = difficulty - 1;
emptyX = difficulty - 1;
emptyY = difficulty - 1;
// 恢复默认工作图像
SetWorkingImage();
// 打乱拼图
ShufflePuzzle();
gameState = 2; // 进入显示拼图状态
}
// 绘制拼图
void PuzzleGame::DrawPuzzle() {
// 清空拼图区域
setfillcolor(BG_COLOR);
solidrectangle(0, 0, PUZZLE_WIDTH, PUZZLE_HEIGHT);
// 绘制所有拼图块
for (int i = 0; i < difficulty; i++) {
for (int j = 0; j < difficulty; j++) {
// 跳过空白块
if (i == emptyY && j == emptyX) {
continue;
}
// 获取拼图块的实际位置
int actualX = puzzlePieces[i][j].gridX;
int actualY = puzzlePieces[i][j].gridY;
// 绘制拼图块
putimage(actualX * pieceWidth + 3,
actualY * pieceHeight + 3,
&puzzlePieces[i][j].image);
}
}
// 绘制完整图像预览
IMAGE preview;
TCHAR imgPath[256];
_stprintf_s(imgPath, _T("%S"), imagePath.c_str());
loadimage(&preview, imgPath, 300, 225);
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) {
// 找出点击的拼图块在数组中的位置
int pieceIndex = positionMap[gridY][gridX];
int pieceRow = pieceIndex / difficulty;
int pieceCol = pieceIndex % difficulty;
// 更新位置映射表
positionMap[emptyY][emptyX] = pieceIndex;
positionMap[gridY][gridX] = difficulty * difficulty - 1;
// 交换拼图块位置
puzzlePieces[pieceRow][pieceCol].gridX = emptyX;
puzzlePieces[pieceRow][pieceCol].gridY = emptyY;
// 更新空白块位置
emptyX = gridX;
emptyY = gridY;
// 重绘拼图
DrawPuzzle();
}
// 检查是否完成拼图
void PuzzleGame::CheckCompletion() {
bool completed = true;
// 检查所有拼图块是否在正确位置
for (int i = 0; i < difficulty; i++) {
for (int j = 0; j < difficulty; j++) {
if (puzzlePieces[i][j].gridX != j || puzzlePieces[i][j].gridY != i) {
completed = false;
break;
}
}
if (!completed) break;
}
// 如果完成当前关卡
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) {
// 更新图片路径
char levelDigit1 = '0' + (currentLevel / 10);
char levelDigit2 = '0' + (currentLevel % 10);
imagePath[4] = levelDigit1;
imagePath[5] = levelDigit2;
// 重置游戏状态
gameState = 1;
// 释放当前拼图资源
for (int i = 0; i < difficulty; i++) {
delete[] puzzlePieces[i];
delete[] positionMap[i];
}
delete[] puzzlePieces;
delete[] positionMap;
puzzlePieces = nullptr;
positionMap = nullptr;
}
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) {
// 移动拼图块
int pieceIndex = positionMap[newY][newX];
int pieceRow = pieceIndex / difficulty;
int pieceCol = pieceIndex % difficulty;
// 更新位置映射表
positionMap[emptyY][emptyX] = pieceIndex;
positionMap[newY][newX] = difficulty * difficulty - 1;
// 交换拼图块位置
puzzlePieces[pieceRow][pieceCol].gridX = emptyX;
puzzlePieces[pieceRow][pieceCol].gridY = emptyY;
// 更新空白块位置
emptyX = newX;
emptyY = newY;
}
// 改变方向
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) {
// 移动拼图块
int pieceIndex = positionMap[newY][newX];
int pieceRow = pieceIndex / difficulty;
int pieceCol = pieceIndex % difficulty;
// 更新位置映射表
positionMap[emptyY][emptyX] = pieceIndex;
positionMap[newY][newX] = difficulty * difficulty - 1;
// 交换拼图块位置
puzzlePieces[pieceRow][pieceCol].gridX = emptyX;
puzzlePieces[pieceRow][pieceCol].gridY = emptyY;
// 更新空白块位置
emptyX = newX;
emptyY = newY;
}
}
}
// 主函数
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;
}
最新发布