#include <graphics.h> #include <conio.h> #include<stdlib.h>无法打开源文件解决方案

在学习链表时遇到编程错误,原因是SDK工具包路径被移动和EasyX图形库未正确安装。解决办法是恢复SDK到安装目录顶层并更新EasyX至最新版本以适应新编译环境。

一、问题描述

学习数据结构链表的过程中,在编写漫天星星闪烁的代码时,遇到了如下图所示的报错,#include <graphics.h>#include <conio.h> 等无法打开源文件。报错提示
并且主程序中initgraph(初始化画布)、setfillcolor(颜色填充)loadimage(加载图片)等都出现报错,在网上查找资料后最终解决方案如下:
在这里插入图片描述

二、问题解决

可能原因1:SDK工具包的位置被移动了

就是下面这个文件夹,这个文件夹默认会在你安装目录的最上面一级,但我当时为了管理文件方便,就自行将其移动到自建文件夹Visual Studio中,导致程序在运行时,出现大量的错误。
Windows kits
解决方法:将这个工具包文件夹剪切到你的安装目录最上面那一级。再关闭软件,重新打开,运行。

可能原因2:EasyX图形库没有安装

注意!在换了编译环境后一定要重装一遍EasyX图形库,我之前使用的是VS2010,最近在用VS2022,在2010版本装了EasyX,后面大脑短路,忘记在2022版本上装,这里要注意EasyX图形库一定要装最新版的,如果安装的是旧版的会识别不到VS2022。
在这里插入图片描述
在这里插入图片描述
解决问题后,程序报错提示消失,程序能够正常运行。
在这里插入图片描述
在这里插入图片描述

#include<stdio.h> #include<conio.h> #include<windows.h> #include<stdlib.h> #include<graphics.h> #define blocksize 20 #define high 30 #define width 40 void settextstyle(int fontheight, int fontwidth, const char* fontname); int score = 0; int moved; int canvas[high][width] = { 0 }; int food_x, food_y; void gotoxy(int x, int y) { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(handle, pos); } void moves() { for (int i = 1; i < high - 1; i++) { for (int j = 1; j < width - 1; j++) { if (canvas[i][j] > 0) canvas[i][j]++; } } int max = 0, oldhi, oldhj, oldti, oldtj; for (int i = 1; i < high - 1; i++) { for (int j = 1; j < width - 1; j++) { if (canvas[i][j] > 0) { if (max < canvas[i][j]) { max = canvas[i][j]; oldti = i; oldtj = j; } if (canvas[i][j] == 2) { oldhi = i; oldhj = j; } } } } canvas[oldti][oldtj] = 0; int newhi, newhj; if (moved == 5) { newhi = oldhi - 1; newhj = oldhj; } if (moved == 2) { newhi = oldhi + 1; newhj = oldhj; } if (moved == 1) { newhi = oldhi; newhj = oldhj - 1; } if (moved == 3) { newhi = oldhi; newhj = oldhj + 1; } if (canvas[newhi][newhj] == -2)//如果吃到食物 { canvas[food_x][food_y] = 0; food_x = rand() % (high - 5) + 2; food_y = rand() % (width - 5) + 2; canvas[food_x][food_y] = -2; canvas[oldti][oldtj] = max + 1; score++; } else { canvas[oldti][oldtj] = 0; } if (canvas[newhi][newhj] > 0 || canvas[newhi][newhj] == -1) { settextstyle(40, 40, "宋体"); settextcolor(RED); outtextxy(200, 660, _T("game over")); _getch(); exit(0); } else canvas[newhi][newhj] = 1; } void startup() { for (int i = 0; i < high; i++) { canvas[i][width - 1] = -1; canvas[i][0] = -1; } for (int j = 0; j < width; j++) { canvas[high - 1][j] = -1; canvas[0][j] = -1; } canvas[high / 2][width / 2] = 1; for (int i = 1; i <= 4; i++) { canvas[high / 2][width / 2 - i] = i + 1; } moved = 3; food_x = 5; food_y = 10; canvas[food_x][food_y] = -2; } void show() { gotoxy(0, 0); for (int i = 0; i < high; i++) { for (int j = 0; j < width; j++) { if (canvas[i][j] == 0) { setlinecolor(BLACK); setfillcolor(WHITE); fillrectangle(j * blocksize, i * blocksize, (j + 1) * blocksize, (i + 1) * blocksize); } //printf(" "); if (canvas[i][j] == 1) { setlinecolor(RED); setfillcolor(RED); fillrectangle(j * blocksize, i * blocksize, (j + 1) * blocksize, (i + 1) * blocksize); } if (canvas[i][j] == -1) { setlinecolor(BLACK); setfillcolor(WHITE); fillrectangle(j * blocksize, i * blocksize, (j + 1) * blocksize, (i + 1) * blocksize); } if (canvas[i][j] > 1) { setlinecolor(RED); setfillcolor(RED); fillrectangle(j * blocksize, i * blocksize, (j + 1) * blocksize, (i + 1) * blocksize); } if (canvas[i][j] == -2) { setlinecolor(GREEN); setfillcolor(GREEN); fillrectangle(j * blocksize, i * blocksize, (j + 1) * blocksize, (i + 1) * blocksize); } } printf("\n"); } Sleep(100); } void without() { moves(); } void with() { char input; if (_kbhit()) { input = _getch(); if (input == 'a') { moved = 1; moves(); } else if (input == 'd') { moved = 3; moves(); } else if (input == 'w') { moved = 5; moves(); } else if (input == 's') { moved = 2; moves(); } } } int main() { initgraph(width * blocksize, high * blocksize + 200); startup(); while (1) { show(); without(); with(); } return 0; } 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 LNK2019 无法解析的外部符号 main,函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中引用了该符号 tcs D:\代码放置\贪吃蛇\tcs\tcs\MSVCRTD.lib(exe_main.obj) 1 严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 LNK1120 1 个无法解析的外部命令 tcs D:\代码放置\贪吃蛇\tcs\x64\Debug\tcs.exe 1
06-16
#include <graphics.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define MAX_STUDENTS 100 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 #define TITLE_HEIGHT 50 #define NAVIGATION_WIDTH 150 #define CONTENT_X NAVIGATION_WIDTH #define CONTENT_Y TITLE_HEIGHT #define CONTENT_WIDTH (WINDOW_WIDTH - NAVIGATION_WIDTH) #define CONTENT_HEIGHT (WINDOW_HEIGHT - TITLE_HEIGHT) // 学生结构体 typedef struct { char id[20]; char name[50]; int score; int deleted; // 标记是否删除 } Student; Student students[MAX_STUDENTS]; int studentCount = 0; // 函数声明 void initSystem(); void drawTitle(); void drawNavigation(); void drawContent(int page); void addStudent(); void displayStudents(); void modifyStudent(); void deleteStudent(); void queryStudent(); void saveToFile(); void loadFromFile(); void drawButton(int x, int y, int width, int height, const char* text); int isButtonClicked(int x, int y, int width, int height, MOUSEMSG msg); void inputBox(int x, int y, int width, int height, char* text, int maxLength); // 主函数 int main() { // 初始化图形窗口 initgraph(WINDOW_WIDTH, WINDOW_HEIGHT); initSystem(); // 加载数据 loadFromFile(); int currentPage = 1; // 默认显示主菜单 MOUSEMSG msg; // 主循环 while (1) { // 绘制界面 drawTitle(); drawNavigation(); drawContent(currentPage); // 处理鼠标消息 if (kbhit()) { if (getch() == 27) // ESC键退出 break; } if (mousemsg()) { msg = getmouse(); // 导航按钮检测 if (msg.uMsg == WM_LBUTTONDOWN) { if (isButtonClicked(10, 70, 130, 30, msg)) currentPage = 1; // 主菜单 if (isButtonClicked(10, 110, 130, 30, msg)) currentPage = 2; // 添加学生 if (isButtonClicked(10, 150, 130, 30, msg)) currentPage = 3; // 显示学生 if (isButtonClicked(10, 190, 130, 30, msg)) currentPage = 4; // 修改学生 if (isButtonClicked(10, 230, 130, 30, msg)) currentPage = 5; // 删除学生 if (isButtonClicked(10, 270, 130, 30, msg)) currentPage = 6; // 查询学生 // 内容区域按钮检测 if (currentPage == 2 && isButtonClicked(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, msg)) addStudent(); if (currentPage == 3 && isButtonClicked(CONTENT_X + 100, CONTENT_Y + CONTENT_HEIGHT - 50, 100, 30, msg)) saveToFile(); if (currentPage == 4 && isButtonClicked(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, msg)) modifyStudent(); if (currentPage == 5 && isButtonClicked(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, msg)) deleteStudent(); if (currentPage == 6 && isButtonClicked(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, msg)) queryStudent(); } } } // 保存数据并关闭窗口 saveToFile(); closegraph(); return 0; } // 初始化系统 void initSystem() { setbkcolor(WHITE); cleardevice(); settextstyle(20, 0, _T("宋体")); } // 绘制标题 void drawTitle() { setfillcolor(LIGHTBLUE); bar(0, 0, WINDOW_WIDTH, TITLE_HEIGHT); settextcolor(BLACK); settextstyle(24, 0, _T("黑体")); outtextxy(300, 15, _T("学生成绩管理系统")); } // 绘制导航栏 void drawNavigation() { setfillcolor(LIGHTGRAY); bar(0, TITLE_HEIGHT, NAVIGATION_WIDTH, WINDOW_HEIGHT); settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); drawButton(10, 70, 130, 30, "主菜单"); drawButton(10, 110, 130, 30, "添加学生"); drawButton(10, 150, 130, 30, "显示学生"); drawButton(10, 190, 130, 30, "修改学生"); drawButton(10, 230, 130, 30, "删除学生"); drawButton(10, 270, 130, 30, "查询学生"); } // 绘制内容区域 void drawContent(int page) { setfillcolor(WHITE); bar(CONTENT_X, CONTENT_Y, WINDOW_WIDTH, WINDOW_HEIGHT); switch (page) { case 1: // 主菜单 settextcolor(BLACK); settextstyle(20, 0, _T("宋体")); outtextxy(CONTENT_X + 100, CONTENT_Y + 50, _T("欢迎使用学生成绩管理系统")); outtextxy(CONTENT_X + 100, CONTENT_Y + 100, _T("请从左侧菜单选择操作")); break; case 2: // 添加学生 settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); outtextxy(CONTENT_X + 50, CONTENT_Y + 50, _T("学号:")); outtextxy(CONTENT_X + 50, CONTENT_Y + 100, _T("姓名:")); outtextxy(CONTENT_X + 50, CONTENT_Y + 150, _T("成绩:")); static char id[20] = { 0 }; static char name[50] = { 0 }; static char scoreStr[10] = { 0 }; inputBox(CONTENT_X + 150, CONTENT_Y + 50, 200, 25, id, 20); inputBox(CONTENT_X + 150, CONTENT_Y + 100, 200, 25, name, 50); inputBox(CONTENT_X + 150, CONTENT_Y + 150, 200, 25, scoreStr, 10); drawButton(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, "添加"); break; case 3: // 显示学生 settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); outtextxy(CONTENT_X + 30, CONTENT_Y + 20, _T("学号")); outtextxy(CONTENT_X + 180, CONTENT_Y + 20, _T("姓名")); outtextxy(CONTENT_X + 330, CONTENT_Y + 20, _T("成绩")); line(CONTENT_X + 20, CONTENT_Y + 40, CONTENT_X + CONTENT_WIDTH - 20, CONTENT_Y + 40); int yPos = CONTENT_Y + 60; for (int i = 0; i < MAX_STUDENTS; i++) { if (!students[i].deleted && strlen(students[i].id) > 0) { outtextxy(CONTENT_X + 30, yPos, students[i].id); outtextxy(CONTENT_X + 180, yPos, students[i].name); char scoreStr[10]; sprintf(scoreStr, "%d", students[i].score); outtextxy(CONTENT_X + 330, yPos, scoreStr); yPos += 30; // 如果超出显示区域则停止 if (yPos > CONTENT_Y + CONTENT_HEIGHT - 100) break; } } drawButton(CONTENT_X + 100, CONTENT_Y + CONTENT_HEIGHT - 50, 100, 30, "保存"); break; case 4: // 修改学生 settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); outtextxy(CONTENT_X + 50, CONTENT_Y + 50, _T("请输入要修改的学号:")); static char modifyId[20] = { 0 }; inputBox(CONTENT_X + 250, CONTENT_Y + 50, 200, 25, modifyId, 20); outtextxy(CONTENT_X + 50, CONTENT_Y + 100, _T("新姓名:")); outtextxy(CONTENT_X + 50, CONTENT_Y + 150, _T("新成绩:")); static char newName[50] = { 0 }; static char newScoreStr[10] = { 0 }; inputBox(CONTENT_X + 150, CONTENT_Y + 100, 200, 25, newName, 50); inputBox(CONTENT_X + 150, CONTENT_Y + 150, 200, 25, newScoreStr, 10); drawButton(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, "修改"); break; case 5: // 删除学生 settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); outtextxy(CONTENT_X + 50, CONTENT_Y + 50, _T("请输入要删除的学号:")); static char deleteId[20] = { 0 }; inputBox(CONTENT_X + 250, CONTENT_Y + 50, 200, 25, deleteId, 20); drawButton(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, "删除"); break; case 6: // 查询学生 settextcolor(BLACK); settextstyle(16, 0, _T("宋体")); outtextxy(CONTENT_X + 50, CONTENT_Y + 50, _T("请输入要查询的学号:")); static char queryId[20] = { 0 }; inputBox(CONTENT_X + 250, CONTENT_Y + 50, 200, 25, queryId, 20); drawButton(CONTENT_X + 100, CONTENT_Y + 200, 100, 30, "查询"); // 显示查询结果 static char queryResult[100] = { 0 }; outtextxy(CONTENT_X + 50, CONTENT_Y + 250, queryResult); break; } } // 添加学生 void addStudent() { static char id[20] = { 0 }; static char name[50] = { 0 }; static char scoreStr[10] = { 0 }; // 查找空位置 int emptyIndex = -1; for (int i = 0; i < MAX_STUDENTS; i++) { if (students[i].deleted || strlen(students[i].id) == 0) { emptyIndex = i; break; } } if (emptyIndex == -1) { MessageBox(NULL, _T("学生数量已达到最大值!"), _T("错误"), MB_OK | MB_ICONERROR); return; } // 复制数据 strcpy(students[emptyIndex].id, id); strcpy(students[emptyIndex].name, name); students[emptyIndex].score = atoi(scoreStr); students[emptyIndex].deleted = 0; // 清空输入框 memset(id, 0, sizeof(id)); memset(name, 0, sizeof(name)); memset(scoreStr, 0, sizeof(scoreStr)); MessageBox(NULL, _T("添加成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION); } // 显示学生 void displayStudents() { // 此功能在drawContent函数中实现 } // 修改学生 void modifyStudent() { static char modifyId[20] = { 0 }; static char newName[50] = { 0 }; static char newScoreStr[10] = { 0 }; for (int i = 0; i < MAX_STUDENTS; i++) { if (!students[i].deleted && strcmp(students[i].id, modifyId) == 0) { if (strlen(newName) > 0) strcpy(students[i].name, newName); if (strlen(newScoreStr) > 0) students[i].score = atoi(newScoreStr); MessageBox(NULL, _T("修改成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION); // 清空输入框 memset(modifyId, 0, sizeof(modifyId)); memset(newName, 0, sizeof(newName)); memset(newScoreStr, 0, sizeof(newScoreStr)); return; } } MessageBox(NULL, _T("未找到该学生!"), _T("错误"), MB_OK | MB_ICONERROR); } // 删除学生 void deleteStudent() { static char deleteId[20] = { 0 }; for (int i = 0; i < MAX_STUDENTS; i++) { if (!students[i].deleted && strcmp(students[i].id, deleteId) == 0) { students[i].deleted = 1; MessageBox(NULL, _T("删除成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION); // 清空输入框 memset(deleteId, 0, sizeof(deleteId)); return; } } MessageBox(NULL, _T("未找到该学生!"), _T("错误"), MB_OK | MB_ICONERROR); } // 查询学生 void queryStudent() { static char queryId[20] = { 0 }; static char queryResult[100] = { 0 }; for (int i = 0; i < MAX_STUDENTS; i++) { if (!students[i].deleted && strcmp(students[i].id, queryId) == 0) { sprintf(queryResult, "学号: %s, 姓名: %s, 成绩: %d", students[i].id, students[i].name, students[i].score); return; } } strcpy(queryResult, "未找到该学生!"); } // 保存到文件 void saveToFile() { FILE* file = fopen("students.dat", "wb"); if (file == NULL) { MessageBox(NULL, _T("无法保存文件!"), _T("错误"), MB_OK | MB_ICONERROR); return; } fwrite(students, sizeof(Student), MAX_STUDENTS, file); fclose(file); MessageBox(NULL, _T("保存成功!"), _T("提示"), MB_OK | MB_ICONINFORMATION); } // 从文件加载 void loadFromFile() { FILE* file = fopen("students.dat", "rb"); if (file == NULL) { // 文件不存在,初始化数组 memset(students, 0, sizeof(students)); return; } fread(students, sizeof(Student), MAX_STUDENTS, file); fclose(file); } // 绘制按钮 void drawButton(int x, int y, int width, int height, const char* text) { setfillcolor(LIGHTBLUE); fillrectangle(x, y, x + width, y + height); settextcolor(BLACK); settextstyle(14, 0, _T("宋体")); outtextxy(x + (width - textwidth(text)) / 2, y + (height - textheight(text)) / 2, text); } // 判断按钮是否被点击 int isButtonClicked(int x, int y, int width, int height, MOUSEMSG msg) { return (msg.x >= x && msg.x <= x + width && msg.y >= y && msg.y <= y + height); } // 输入框函数 void inputBox(int x, int y, int width, int height, char* text, int maxLength) { setfillcolor(WHITE); setlinecolor(BLACK); rectangle(x, y, x + width, y + height); settextcolor(BLACK); settextstyle(14, 0, _T("宋体")); outtextxy(x + 5, y + 5, text); #include <graphics.h> // Ensure this header is included for MOUSEMSG definition } 我使用的C语言版本是:ISO C17 (2018)标准 (/std:c17) 为什么警告MOUSEMSG为定义,该如何解决
06-11
#include <stdio.h> #include <Windows.h> #include <stdlib.h> #include <time.h> #include <conio.h> #define ROW 29 //游戏区行数 #define COL 20 //游戏区列数 #define DOWN 80 //方向键:下 #define LEFT 75 //方向键:左 #define RIGHT 77 //方向键:右 #define SPACE 32 //空格键 #define ESC 27 //Esc键 struct Face { int data[ROW][COL + 10]; //用于标记指定位置是否有方块(1为有,0为无) int color[ROW][COL + 10]; //用于记录指定位置的方块颜色编码 }face; struct Block { int space[4][4]; }block[7][4]; //用于存储7种基本形状方块的各自的4种形态的信息,共28种 //隐藏光标 void HideCursor(); //光标跳转 void CursorJump(int x, int y); //初始化界面 void InitInterface(); //初始化方块信息 void InitBlockInfo(); //颜色设置 void color(int num); //画出方块 void DrawBlock(int shape, int form, int x, int y); //空格覆盖 void DrawSpace(int shape, int form, int x, int y); //合法性判断 int IsLegal(int shape, int form, int x, int y); //判断得分与结束 int JudeFunc(); //游戏主体逻辑函数 void StartGame(); //从文件读取最高分 void ReadGrade(); //更新最高分到文件 void WriteGrade(); int max, grade; //全局变量 int main() { #pragma warning (disable:4996) //消除警告 max = 0, grade = 0; //初始化变量 system("title 俄罗斯方块"); //设置cmd窗口的名字 system("mode con lines=29 cols=60"); //设置cmd窗口的大小 HideCursor(); //隐藏光标 ReadGrade(); //从文件读取最高分到max变量 InitInterface(); //初始化界面 InitBlockInfo(); //初始化方块信息 srand((unsigned int)time(NULL)); //设置随机数生成的起点 StartGame(); //开始游戏 return 0; } //隐藏光标 void HideCursor() { CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量 curInfo.dwSize = 1; //如果没赋值的话,隐藏光标无效 curInfo.bVisible = FALSE; //将光标设置为不可见 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄 SetConsoleCursorInfo(handle, &curInfo); //设置光标信息 } //光标跳转 void CursorJump(int x, int y) { COORD pos; //定义光标位置的结构体变量 pos.X = x; //横坐标设置 pos.Y = y; //纵坐标设置 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄 SetConsoleCursorPosition(handle, pos); //设置光标位置 } //初始化界面 void InitInterface() { color(7); //颜色设置为白色 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL + 10; j++) { if (j == 0 || j == COL - 1 || j == COL + 9) { face.data[i][j] = 1; //标记该位置有方块 CursorJump(2 * j, i); printf("■"); } else if (i == ROW - 1) { face.data[i][j] = 1; //标记该位置有方块 CursorJump(2 * j, i); printf("■"); } else face.data[i][j] = 0; //标记该位置无方块 } } for (int i = COL; i < COL + 10; i++) { face.data[8][i] = 1; //标记该位置有方块 CursorJump(2 * i, 8); printf("■"); } CursorJump(2 * COL, 1); printf("下一个方块:"); CursorJump(2 * COL + 4, ROW - 19); printf("左移:←"); CursorJump(2 * COL + 4, ROW - 17); printf("右移:→"); CursorJump(2 * COL + 4, ROW - 15); printf("加速:↓"); CursorJump(2 * COL + 4, ROW - 13); printf("旋转:空格"); CursorJump(2 * COL + 4, ROW - 11); printf("暂停: S"); CursorJump(2 * COL + 4, ROW - 9); printf("退出: Esc"); CursorJump(2 * COL + 4, ROW - 7); printf("重新开始:R"); CursorJump(2 * COL + 4, ROW - 5); printf("最高纪录:%d", max); CursorJump(2 * COL + 4, ROW - 3); printf("当前分数:%d", grade); } //初始化方块信息 void InitBlockInfo() { //“T”形 for (int i = 0; i <= 2; i++) block[0][0].space[1][i] = 1; block[0][0].space[2][1] = 1; //“L”形 for (int i = 1; i <= 3; i++) block[1][0].space[i][1] = 1; block[1][0].space[3][2] = 1; //“J”形 for (int i = 1; i <= 3; i++) block[2][0].space[i][2] = 1; block[2][0].space[3][1] = 1; for (int i = 0; i <= 1; i++) { //“Z”形 block[3][0].space[1][i] = 1; block[3][0].space[2][i + 1] = 1; //“S”形 block[4][0].space[1][i + 1] = 1; block[4][0].space[2][i] = 1; //“O”形 block[5][0].space[1][i + 1] = 1; block[5][0].space[2][i + 1] = 1; } //“I”形 for (int i = 0; i <= 3; i++) block[6][0].space[i][1] = 1; int temp[4][4]; for (int shape = 0; shape < 7; shape++) //7种形状 { for (int form = 0; form < 3; form++) //4种形态(已经有了一种,这里每个还需增加3种) { //获取第form种形态 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { temp[i][j] = block[shape][form].space[i][j]; } } //将第form种形态顺时针旋转,得到第form+1种形态 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { block[shape][form + 1].space[i][j] = temp[3 - j][i]; } } } } } //颜色设置 void color(int c) { switch (c) { case 0: c = 13; //“T”形方块设置为紫色 break; case 1: case 2: c = 12; //“L”形和“J”形方块设置为红色 break; case 3: case 4: c = 10; //“Z”形和“S”形方块设置为绿色 break; case 5: c = 14; //“O”形方块设置为黄色 break; case 6: c = 11; //“I”形方块设置为浅蓝色 break; default: c = 7; //其他默认设置为白色 break; } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置 //注:SetConsoleTextAttribute是一个API(应用程序编程接口) } //画出方块 void DrawBlock(int shape, int form, int x, int y) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (block[shape][form].space[i][j] == 1) //如果该位置有方块 { CursorJump(2 * (x + j), y + i); //光标跳转到指定位置 printf("■"); //输出方块 } } } } //空格覆盖 void DrawSpace(int shape, int form, int x, int y) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (block[shape][form].space[i][j] == 1) //如果该位置有方块 { CursorJump(2 * (x + j), y + i); //光标跳转到指定位置 printf(" "); //打印空格覆盖(两个空格) } } } } //合法性判断 int IsLegal(int shape, int form, int x, int y) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { //如果方块落下的位置本来就已经有方块了,则不合法 if ((block[shape][form].space[i][j] == 1) && (face.data[y + i][x + j] == 1)) return 0; //不合法 } } return 1; //合法 } //判断得分与结束 int JudeFunc() { //判断是否得分 for (int i = ROW - 2; i > 4; i--) { int sum = 0; //记录第i行的方块个数 for (int j = 1; j < COL - 1; j++) { sum += face.data[i][j]; //统计第i行的方块个数 } if (sum == 0) //该行没有方块,无需再判断其上的层次(无需再继续判断是否得分) break; //跳出循环 if (sum == COL - 2) //该行全是方块,可得分 { grade += 10; //满一行加10分 color(7); //颜色设置为白色 CursorJump(2 * COL + 4, ROW - 3); //光标跳转到显示当前分数的位置 printf("当前分数:%d", grade); //更新当前分数 for (int j = 1; j < COL - 1; j++) //清除得分行的方块信息 { face.data[i][j] = 0; //该位置得分后被清除,标记为无方块 CursorJump(2 * j, i); //光标跳转到该位置 printf(" "); //打印空格覆盖(两个空格) } //把被清除行上面的行整体向下挪一格 for (int m = i; m >1; m--) { sum = 0; //记录上一行的方块个数 for (int n = 1; n < COL - 1; n++) { sum += face.data[m - 1][n]; //统计上一行的方块个数 face.data[m][n] = face.data[m - 1][n]; //将上一行方块的标识移到下一行 face.color[m][n] = face.color[m - 1][n]; //将上一行方块的颜色编号移到下一行 if (face.data[m][n] == 1) //上一行移下来的是方块,打印方块 { CursorJump(2 * n, m); //光标跳转到该位置 color(face.color[m][n]); //颜色设置为还方块的颜色 printf("■"); //打印方块 } else //上一行移下来的是空格,打印空格 { CursorJump(2 * n, m); //光标跳转到该位置 printf(" "); //打印空格(两个空格) } } if (sum == 0) //上一行移下来的全是空格,无需再将上层的方块向下移动(移动结束) return 1; //返回1,表示还需调用该函数进行判断(移动下来的可能还有满行) } } } //判断游戏是否结束 for (int j = 1; j < COL - 1; j++) { if (face.data[1][j] == 1) //顶层有方块存在(以第1行为顶层,不是第0行) { Sleep(1000); //留给玩家反应时间 system("cls"); //清空屏幕 color(7); //颜色设置为白色 CursorJump(2 * (COL / 3), ROW / 2 - 3); if (grade>max) { printf("恭喜你打破最高记录,最高记录更新为%d", grade); WriteGrade(); } else if (grade == max) { printf("与最高记录持平,加油再创佳绩", grade); } else { printf("请继续加油,当前与最高记录相差%d", max - grade); } CursorJump(2 * (COL / 3), ROW / 2); printf("GAME OVER"); while (1) { char ch; CursorJump(2 * (COL / 3), ROW / 2 + 3); printf("再来一局?(y/n):"); scanf("%c", &ch); if (ch == 'y' || ch == 'Y') { system("cls"); main(); } else if (ch == 'n' || ch == 'N') { CursorJump(2 * (COL / 3), ROW / 2 + 5); exit(0); } else { CursorJump(2 * (COL / 3), ROW / 2 + 4); printf("选择错误,请再次选择"); } } } } return 0; //判断结束,无需再调用该函数进行判断 } //游戏主体逻辑函数 void StartGame() { int shape = rand() % 7, form = rand() % 4; //随机获取方块的形状和形态 while (1) { int t = 0; int nextShape = rand() % 7, nextForm = rand() % 4; //随机获取下一个方块的形状和形态 int x = COL / 2 - 2, y = 0; //方块初始下落位置的横纵坐标 color(nextShape); //颜色设置为下一个方块的颜色 DrawBlock(nextShape, nextForm, COL + 3, 3); //将下一个方块显示在右上角 while (1) { color(shape); //颜色设置为当前正在下落的方块 DrawBlock(shape, form, x, y); //将该方块显示在初始下落位置 if (t == 0) { t = 15000; //这里t越小,方块下落越快(可以根据此设置游戏难度) } while (--t) { if (kbhit() != 0) //若键盘被敲击,则退出循环 break; } if (t == 0) //键盘未被敲击 { if (IsLegal(shape, form, x, y + 1) == 0) //方块再下落就不合法了(已经到达底部) { //将当前方块的信息录入face当中 //face:记录界面的每个位置是否有方块,若有方块还需记录该位置方块的颜色。 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (block[shape][form].space[i][j] == 1) { face.data[y + i][x + j] = 1; //将该位置标记为有方块 face.color[y + i][x + j] = shape; //记录该方块的颜色数值 } } } while (JudeFunc()); //判断此次方块下落是否得分以及游戏是否结束 break; //跳出当前死循环,准备进行下一个方块的下落 } else //未到底部 { DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置 y++; //纵坐标自增(下一次显示方块时就相当于下落了一格了) } } else //键盘被敲击 { char ch = getch(); //读取keycode switch (ch) { case DOWN: //方向键:下 if (IsLegal(shape, form, x, y + 1) == 1) //判断方块向下移动一位后是否合法 { //方块下落后合法才进行以下操作 DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置 y++; //纵坐标自增(下一次显示方块时就相当于下落了一格了) } break; case LEFT: //方向键:左 if (IsLegal(shape, form, x - 1, y) == 1) //判断方块向左移动一位后是否合法 { //方块左移后合法才进行以下操作 DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置 x--; //横坐标自减(下一次显示方块时就相当于左移了一格了) } break; case RIGHT: //方向键:右 if (IsLegal(shape, form, x + 1, y) == 1) //判断方块向右移动一位后是否合法 { //方块右移后合法才进行以下操作 DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置 x++; //横坐标自增(下一次显示方块时就相当于右移了一格了) } break; case SPACE: //空格键 if (IsLegal(shape, (form + 1) % 4, x, y + 1) == 1) //判断方块旋转后是否合法 { //方块旋转后合法才进行以下操作 DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置 y++; //纵坐标自增(总不能原地旋转吧) form = (form + 1) % 4; //方块的形态自增(下一次显示方块时就相当于旋转了) } break; case ESC: //Esc键 system("cls"); //清空屏幕 color(7); CursorJump(COL, ROW / 2); printf(" 游戏结束 "); CursorJump(COL, ROW / 2 + 2); exit(0); //结束程序 case 's': case 'S': //暂停 system("pause>nul"); //暂停(按任意键继续) break; case 'r': case 'R': //重新开始 system("cls"); //清空屏幕 main(); //重新执行主函数 } } } shape = nextShape, form = nextForm; //获取下一个方块的信息 DrawSpace(nextShape, nextForm, COL + 3, 3); //将右上角的方块信息用空格覆盖 } } //从文件读取最高分 void ReadGrade() { FILE* pf = fopen("俄罗斯方块最高得分记录.txt", "r"); //以只读方式打开文件 if (pf == NULL) //打开文件失败 { pf = fopen("俄罗斯方块最高得分记录.txt", "w"); //以只写方式打开文件(文件不存在可以自动创建该文件) fwrite(&grade, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高历史得分初始化为0 } fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头 fread(&max, sizeof(int), 1, pf); //读取文件中的最高历史得分到max当中 fclose(pf); //关闭文件 pf = NULL; //文件指针及时置空 } //更新最高分到文件 void WriteGrade() { FILE* pf = fopen("俄罗斯方块最高得分记录.txt", "w"); //以只写方式打开文件 if (pf == NULL) //打开文件失败 { printf("保存最高得分记录失败\n"); exit(0); } fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中(更新最高历史得分) fclose(pf); //关闭文件 pf = NULL; //文件指针及时置空 } 帮我看看这段代码能不能在VS上面进行运行以及应该如何使他运行
06-12
#include <graphics.h> #include <stdio.h> #include <conio.h> #include <mmsystem.h> #include <math.h> #include <time.h> #include <stdlib.h> // 添加缺少的头文件 #include <windows.h> // 添加缺少的头文件 #pragma comment(lib, "winmm.lib") #define WIDTH 640 #define HEIGHT 480 #define MAP_WIDTH 20 #define MAP_HEIGHT 20 #define PACMAN_SIZE 20 #define BEAN_SIZE 5 #define ENEMY_SIZE 15 #define MAX_BEANS 50 #define MAX_ENEMIES 5 #define MAX_PROPS 5 #define LEVEL_COUNT 3 // 游戏状态 typedef enum { MENU, SELECT_DIFFICULTY, PLAYING, PAUSED, GAME_OVER, LEVEL_COMPLETED, GAME_COMPLETED } GameState; // 方向 typedef enum { RIGHT = 0, DOWN = 1, LEFT = 2, UP = 3 } Direction; // 难度 typedef enum { EASY, MEDIUM, HARD } Difficulty; // 关卡结构体定义(新增) typedef struct { int map[MAP_HEIGHT][MAP_WIDTH]; int beanCount; int enemyCount; int propCount; int requiredScore; } Level; // 吃豆人结构体 typedef struct { int x; int y; int radius; Direction direction; int speed; int lives; int score; int invincible; // 无敌状态 int invincibleTime; IMAGE img; // 吃豆人图像 } Pacman; // 豆子结构体 typedef struct { int x; int y; int radius; int eaten; IMAGE img; // 豆子图像 } Bean; // 敌人结构体 typedef struct { int x; int y; int radius; int speed; Direction direction; int state; // 0: 巡逻, 1: 追逐, 2: 逃跑 int scaredTimer; // 被吓到的时间 IMAGE img; // 敌人图像 } Enemy; // 道具结构体 typedef struct { int x; int y; int radius; int type; // 0: 无敌, 1: 减速, 2: 加分 int active; int duration; IMAGE img; // 道具图像 } Prop; // 全局变量 GameState gameState = MENU; Difficulty difficulty = MEDIUM; int currentLevel = 0; int gamePaused = 0; // 地图数组 - 修改为20x20以匹配关卡定义 int map[MAP_HEIGHT][MAP_WIDTH] = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, {1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }; // 关卡定义 Level levels[LEVEL_COUNT] = { { // 第1关地图 { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, {1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }, 20, // 豆子数量 2, // 敌人数量 1, // 道具数量 15 // 通关分数 }, { // 第2关地图 { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }, 30, // 豆子数量 3, // 敌人数量 2, // 道具数量 25 // 通关分数 }, { // 第3关地图 { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }, 40, // 豆子数量 4, // 敌人数量 3, // 道具数量 35 // 通关分数 } }; // 函数声明 void initGame(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount); void drawMap(); void drawGame(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount); void movePacman(Pacman* pacman); void moveEnemy(Enemy* enemy, Pacman* pacman, Bean beans[], int beanCount); void checkCollision(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount); void drawMenu(); void drawDifficultyMenu(); void drawGameOver(int score); void drawLevelCompleted(int level, int score); void drawGameCompleted(int score); void handleInput(Pacman* pacman); void loadLevel(int level, Pacman* pacman, Bean beans[], Enemy enemies[], Prop props[]); void applyPropEffect(Pacman* pacman, Enemy enemies[], int enemyCount, int propType); void updateProps(Prop props[], int propCount); int main() { initgraph(WIDTH, HEIGHT); srand((unsigned int)time(NULL)); // 初始化随机数种子 Pacman pacman; Bean beans[MAX_BEANS]; Enemy enemies[MAX_ENEMIES]; Prop props[MAX_PROPS]; // 加载第一关 loadLevel(currentLevel, &pacman, beans, enemies, props); while (1) { // 处理输入 handleInput(&pacman); // 游戏逻辑 if (gameState == PLAYING && !gamePaused) { movePacman(&pacman); for (int i = 0; i < levels[currentLevel].enemyCount; i++) { moveEnemy(&enemies[i], &pacman, beans, levels[currentLevel].beanCount); } checkCollision(&pacman, beans, levels[currentLevel].beanCount, enemies, levels[currentLevel].enemyCount, props, levels[currentLevel].propCount); updateProps(props, levels[currentLevel].propCount); // 检查是否通关 if (pacman.score >= levels[currentLevel].requiredScore) { if (currentLevel < LEVEL_COUNT - 1) { gameState = LEVEL_COMPLETED; } else { gameState = GAME_COMPLETED; } } } // 绘制游戏 switch (gameState) { case MENU: drawMenu(); break; case SELECT_DIFFICULTY: drawDifficultyMenu(); break; case PLAYING: drawGame(&pacman, beans, levels[currentLevel].beanCount, enemies, levels[currentLevel].enemyCount, props, levels[currentLevel].propCount); if (gamePaused) { settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 80, HEIGHT / 2 - 20, _T("游戏暂停")); settextstyle(20, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 2 + 30, _T("按P键继续游戏")); } break; case GAME_OVER: drawGameOver(pacman.score); break; case LEVEL_COMPLETED: drawLevelCompleted(currentLevel + 1, pacman.score); break; case GAME_COMPLETED: drawGameCompleted(pacman.score); break; } Sleep(20); } getch(); closegraph(); return 0; } void initGame(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount) { // 初始化吃豆人 pacman->x = WIDTH / 2; pacman->y = HEIGHT / 2; pacman->radius = PACMAN_SIZE; pacman->direction = RIGHT; pacman->speed = 5; pacman->lives = 3; pacman->score = 0; pacman->invincible = 0; pacman->invincibleTime = 0; // 加载吃豆人图像 // loadimage(&pacman->img, _T("pacman.png")); // 初始化豆子 for (int i = 0; i < beanCount; i++) { int x, y; do { x = rand() % MAP_WIDTH; y = rand() % MAP_HEIGHT; } while (map[y][x] == 1); beans[i].x = x * 30 + 15; beans[i].y = y * 30 + 15; beans[i].radius = BEAN_SIZE; beans[i].eaten = 0; // 加载豆子图像 // loadimage(&beans[i].img, _T("bean.png")); } // 初始化敌人 for (int i = 0; i < enemyCount; i++) { int x, y; do { x = rand() % MAP_WIDTH; y = rand() % MAP_HEIGHT; } while (map[y][x] == 1 || (abs(x * 30 + 15 - pacman->x) < 100 && abs(y * 30 + 15 - pacman->y) < 100)); enemies[i].x = x * 30 + 15; enemies[i].y = y * 30 + 15; enemies[i].radius = ENEMY_SIZE; enemies[i].speed = 3 + difficulty; // 难度越高速度越快 enemies[i].direction = (Direction)(rand() % 4); enemies[i].state = 0; // 初始巡逻状态 enemies[i].scaredTimer = 0; // 加载敌人图像 // loadimage(&enemies[i].img, _T("enemy.png")); } // 初始化道具 for (int i = 0; i < propCount; i++) { int x, y; do { x = rand() % MAP_WIDTH; y = rand() % MAP_HEIGHT; } while (map[y][x] == 1); props[i].x = x * 30 + 15; props[i].y = y * 30 + 15; props[i].radius = 10; props[i].type = rand() % 3; // 随机道具类型 props[i].active = 1; props[i].duration = 500; // 道具持续时间 // 加载道具图像 // loadimage(&props[i].img, _T("prop.png")); } } void drawMap() { for (int y = 0; y < MAP_HEIGHT; y++) { for (int x = 0; x < MAP_WIDTH; x++) { if (map[y][x] == 1) { // 绘制墙壁 setfillcolor(BLUE); bar(x * 30, y * 30, (x + 1) * 30, (y + 1) * 30); } } } } void drawGame(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount) { // 清屏 cleardevice(); // 绘制地图 drawMap(); // 绘制吃豆人 static int frame = 0; frame = (frame + 1) % 10; if (pacman->invincible && (frame < 5)) { setfillcolor(YELLOW); } else { setfillcolor(RED); } // 如果加载了图像则显示图像,否则绘制圆形 // if (pacman->img.getwidth() > 0) { // putimage(pacman->x - pacman->radius, pacman->y - pacman->radius, &pacman->img); // } else { // 根据方向调整嘴巴 int startAngle = 30; int endAngle = 330; switch (pacman->direction) { case RIGHT: startAngle = 30; endAngle = 330; break; case DOWN: startAngle = 120; endAngle = 240; break; case LEFT: startAngle = 210; endAngle = 150; break; case UP: startAngle = 300; endAngle = 60; break; } pieslice(pacman->x, pacman->y, startAngle, endAngle, pacman->radius); // } // 绘制豆子 for (int i = 0; i < beanCount; i++) { if (!beans[i].eaten) { // if (beans[i].img.getwidth() > 0) { // putimage(beans[i].x - beans[i].radius, beans[i].y - beans[i].radius, &beans[i].img); // } else { setfillcolor(YELLOW); circle(beans[i].x, beans[i].y, beans[i].radius); // } } } // 绘制道具 for (int i = 0; i < propCount; i++) { if (props[i].active) { // if (props[i].img.getwidth() > 0) { // putimage(props[i].x - props[i].radius, props[i].y - props[i].radius, &props[i].img); // } else { // 根据道具类型设置不同颜色 switch (props[i].type) { case 0: // 无敌 setfillcolor(GREEN); break; case 1: // 减速 setfillcolor(BLUE); break; case 2: // 加分 setfillcolor(RED); break; } circle(props[i].x, props[i].y, props[i].radius); // } } } // 绘制敌人 for (int i = 0; i < enemyCount; i++) { // if (enemies[i].img.getwidth() > 0) { // if (enemies[i].scaredTimer > 0) { // // 被吓到的敌人显示为青色 // IMAGE tempImg; // tempImg = enemies[i].img; // for (int y = 0; y < tempImg.getheight(); y++) { // for (int x = 0; x < tempImg.getwidth(); x++) { // COLORREF color = getpixel(x, y, &tempImg); // if (color != BLACK) { // putpixel(x, y, CYAN); // } // } // } // putimage(enemies[i].x - enemies[i].radius, enemies[i].y - enemies[i].radius, &tempImg); // } else { // putimage(enemies[i].x - enemies[i].radius, enemies[i].y - enemies[i].radius, &enemies[i].img); // } // } else { if (enemies[i].scaredTimer > 0) { setfillcolor(CYAN); // 被吓到的敌人显示为青色 } else { setfillcolor(MAGENTA); } circle(enemies[i].x, enemies[i].y, enemies[i].radius); // } } // 显示得分和生命 char info[50]; sprintf_s(info, sizeof(info), "Score: %d Lives: %d", pacman->score, pacman->lives); settextcolor(WHITE); settextstyle(20, 0, _T("宋体")); outtextxy(10, 10, info); // 显示关卡 sprintf_s(info, sizeof(info), "Level: %d", currentLevel + 1); outtextxy(WIDTH - 100, 10, info); // 显示无敌时间 if (pacman->invincible) { sprintf_s(info, sizeof(info), "Invincible: %d", pacman->invincibleTime / 10); outtextxy(WIDTH / 2 - 50, 10, info); } } void movePacman(Pacman* pacman) { // 处理连续按键 if (_kbhit()) { char key = _getch(); Direction newDirection = pacman->direction; switch (key) { case 'w': newDirection = UP; break; case 's': newDirection = DOWN; break; case 'a': newDirection = LEFT; break; case 'd': newDirection = RIGHT; break; } // 改变方向 pacman->direction = newDirection; } // 根据当前方向移动 int newX = pacman->x; int newY = pacman->y; switch (pacman->direction) { case RIGHT: newX += pacman->speed; break; case DOWN: newY += pacman->speed; break; case LEFT: newX -= pacman->speed; break; case UP: newY -= pacman->speed; break; } // 检查是否可以移动 int mapX = newX / 30; int mapY = newY / 30; if (map[mapY][mapX] == 0) { pacman->x = newX; pacman->y = newY; } // 处理穿墙(从一边进入从另一边出来) if (pacman->x < 0) pacman->x = WIDTH; if (pacman->x > WIDTH) pacman->x = 0; if (pacman->y < 0) pacman->y = HEIGHT; if (pacman->y > HEIGHT) pacman->y = 0; // 无敌时间减少 if (pacman->invincible) { pacman->invincibleTime--; if (pacman->invincibleTime <= 0) { pacman->invincible = 0; } } } void moveEnemy(Enemy* enemy, Pacman* pacman, Bean beans[], int beanCount) { // 如果被吓到,随机移动 if (enemy->scaredTimer > 0) { enemy->scaredTimer--; // 随机改变方向 if (rand() % 20 == 0) { enemy->direction = (Direction)(rand() % 4); } } else { // 正常状态,决定是巡逻还是追逐 int dx = pacman->x - enemy->x; int dy = pacman->y - enemy->y; int distance = sqrt(dx * dx + dy * dy); // 如果吃豆人在范围内且不是无敌状态,追逐 if (distance < 200 && !pacman->invincible) { enemy->state = 1; // 追逐 } else { enemy->state = 0; // 巡逻 } // 根据状态决定移动方式 if (enemy->state == 1) { // 追逐 if (abs(dx) > abs(dy)) { if (dx > 0) { enemy->direction = RIGHT; } else { enemy->direction = LEFT; } } else { if (dy > 0) { enemy->direction = DOWN; } else { enemy->direction = UP; } } } else { // 巡逻 // 随机改变方向 if (rand() % 50 == 0) { enemy->direction = (Direction)(rand() % 4); } } } // 根据方向移动 int newX = enemy->x; int newY = enemy->y; switch (enemy->direction) { case RIGHT: newX += enemy->speed; break; case DOWN: newY += enemy->speed; break; case LEFT: newX -= enemy->speed; break; case UP: newY -= enemy->speed; break; } // 检查是否可以移动 int mapX = newX / 30; int mapY = newY / 30; if (map[mapY][mapX] == 0) { enemy->x = newX; enemy->y = newY; } else { // 撞到墙,随机改变方向 enemy->direction = (Direction)(rand() % 4); } // 处理穿墙 if (enemy->x < 0) enemy->x = WIDTH; if (enemy->x > WIDTH) enemy->x = 0; if (enemy->y < 0) enemy->y = HEIGHT; if (enemy->y > HEIGHT) enemy->y = 0; } void checkCollision(Pacman* pacman, Bean beans[], int beanCount, Enemy enemies[], int enemyCount, Prop props[], int propCount) { // 检测吃豆人吃豆子 for (int i = 0; i < beanCount; i++) { if (!beans[i].eaten) { int dx = pacman->x - beans[i].x; int dy = pacman->y - beans[i].y; if (dx * dx + dy * dy <= (pacman->radius + beans[i].radius) * (pacman->radius + beans[i].radius)) { beans[i].eaten = 1; pacman->score += 10; // PlaySound(TEXT("eat.wav"), NULL, SND_FILENAME | SND_ASYNC); } } } // 检测吃豆人吃道具 for (int i = 0; i < propCount; i++) { if (props[i].active) { int dx = pacman->x - props[i].x; int dy = pacman->y - props[i].y; if (dx * dx + dy * dy <= (pacman->radius + props[i].radius) * (pacman->radius + props[i].radius)) { props[i].active = 0; applyPropEffect(pacman, enemies, enemyCount, props[i].type); // PlaySound(TEXT("powerup.wav"), NULL, SND_FILENAME | SND_ASYNC); } } } // 检测吃豆人与敌人碰撞 for (int i = 0; i < enemyCount; i++) { int dx = pacman->x - enemies[i].x; int dy = pacman->y - enemies[i].y; if (dx * dx + dy * dy <= (pacman->radius + enemies[i].radius) * (pacman->radius + enemies[i].radius)) { if (pacman->invincible) { // 无敌状态,敌人被吃掉 enemies[i].x = rand() % MAP_WIDTH * 30 + 15; enemies[i].y = rand() % MAP_HEIGHT * 30 + 15; enemies[i].scaredTimer = 0; pacman->score += 50; // PlaySound(TEXT("eatghost.wav"), NULL, SND_FILENAME | SND_ASYNC); } else if (enemies[i].scaredTimer > 0) { // 敌人被吓到,被吃掉 enemies[i].x = rand() % MAP_WIDTH * 30 + 15; enemies[i].y = rand() % MAP_HEIGHT * 30 + 15; enemies[i].scaredTimer = 0; pacman->score += 50; // PlaySound(TEXT("eatghost.wav"), NULL, SND_FILENAME | SND_ASYNC); } else { // 普通碰撞,扣生命值 pacman->lives--; if (pacman->lives <= 0) { // 游戏结束 // PlaySound(TEXT("gameover.wav"), NULL, SND_FILENAME | SND_ASYNC); gameState = GAME_OVER; } else { // 重置吃豆人位置 pacman->x = WIDTH / 2; pacman->y = HEIGHT / 2; pacman->invincible = 1; pacman->invincibleTime = 200; // 短暂无敌 // PlaySound(TEXT("hurt.wav"), NULL, SND_FILENAME | SND_ASYNC); } } } } } void drawMenu() { cleardevice(); settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 4, _T("吃豆人游戏")); settextstyle(25, 0, _T("宋体")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 - 30, _T("1. 开始游戏")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 + 30, _T("2. 选择难度")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 + 90, _T("3. 退出游戏")); settextstyle(15, 0, _T("宋体")); outtextxy(WIDTH / 2 - 120, HEIGHT - 50, _T("使用WASD控制吃豆人,P键暂停游戏")); // 处理菜单选择 if (_kbhit()) { char key = _getch(); switch (key) { case '1': case '\r': // 回车 gameState = PLAYING; break; case '2': gameState = SELECT_DIFFICULTY; break; case '3': case 27: // ESC closegraph(); exit(0); break; } } } void drawDifficultyMenu() { cleardevice(); settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 4, _T("选择难度")); settextstyle(25, 0, _T("宋体")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 - 30, _T("1. 简单")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 + 30, _T("2. 中等")); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 + 90, _T("3. 困难")); // 处理难度选择 if (_kbhit()) { char key = _getch(); switch (key) { case '1': difficulty = EASY; gameState = MENU; break; case '2': difficulty = MEDIUM; gameState = MENU; break; case '3': difficulty = HARD; gameState = MENU; break; } } } void drawGameOver(int score) { cleardevice(); settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 4, _T("游戏结束")); settextstyle(30, 0, _T("宋体")); char info[50]; sprintf_s(info, sizeof(info), "得分: %d", score); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 - 30, info); settextstyle(20, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 2 + 30, _T("按任意键返回主菜单")); if (_kbhit()) { _getch(); // 消耗按键 gameState = MENU; loadLevel(0, &(Pacman){0}, (Bean[]) { 0 }, (Enemy[]) { 0 }, (Prop[]) { 0 }); // 重新加载第一关 } } void drawLevelCompleted(int level, int score) { cleardevice(); settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 4, _T("通关成功")); settextstyle(30, 0, _T("宋体")); char info[50]; sprintf_s(info, sizeof(info), "第 %d 关完成", level); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 - 30, info); sprintf_s(info, sizeof(info), "得分: %d", score); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 + 30, info); settextstyle(20, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 2 + 90, _T("按任意键进入下一关")); if (_kbhit()) { _getch(); // 消耗按键 currentLevel++; loadLevel(currentLevel, &(Pacman){0}, (Bean[]) { 0 }, (Enemy[]) { 0 }, (Prop[]) { 0 }); gameState = PLAYING; } } void drawGameCompleted(int score) { cleardevice(); settextcolor(WHITE); settextstyle(40, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 4, _T("恭喜通关")); settextstyle(30, 0, _T("宋体")); char info[50]; sprintf_s(info, sizeof(info), "总得分: %d", score); outtextxy(WIDTH / 2 - 70, HEIGHT / 2 - 30, info); settextstyle(20, 0, _T("宋体")); outtextxy(WIDTH / 2 - 100, HEIGHT / 2 + 30, _T("你完成了所有关卡!")); outtextxy(WIDTH / 2 - 100, HEIGHT / 2 + 90, _T("按任意键返回主菜单")); if (_kbhit()) { _getch(); // 消耗按键 gameState = MENU; currentLevel = 0; loadLevel(currentLevel, &(Pacman){0}, (Bean[]) { 0 }, (Enemy[]) { 0 }, (Prop[]) { 0 }); } } void handleInput(Pacman* pacman) { if (_kbhit()) { char key = _getch(); switch (key) { case 27: // ESC if (gameState == PLAYING) { gameState = MENU; } break; case 'p': case 'P': if (gameState == PLAYING) { gamePaused = !gamePaused; } break; } } } void loadLevel(int level, Pacman* pacman, Bean beans[], Enemy enemies[], Prop props[]) { // 复制地图 for (int y = 0; y < MAP_HEIGHT; y++) { for (int x = 0; x < MAP_WIDTH; x++) { map[y][x] = levels[level].map[y][x]; } } // 初始化游戏元素 initGame(pacman, beans, levels[level].beanCount, enemies, levels[level].enemyCount, props, levels[level].propCount); } void applyPropEffect(Pacman* pacman, Enemy enemies[], int enemyCount, int propType) { switch (propType) { case 0: // 无敌 pacman->invincible = 1; pacman->invincibleTime = 300; // 无敌时间 break; case 1: // 减速 for (int i = 0; i < enemyCount; i++) { enemies[i].speed = max(1, enemies[i].speed - 1); // 至少保留1的速度 enemies[i].scaredTimer = 200; // 被吓到的时间 } break; case 2: // 加分 pacman->score += 50; // 额外加分 break; } } void updateProps(Prop props[], int propCount) { for (int i = 0; i < propCount; i++) { if (!props[i].active && rand() % 1000 < 5) { // 5‰的概率重新生成道具 int x, y; do { x = rand() % MAP_WIDTH; y = rand() % MAP_HEIGHT; } while (map[y][x] == 1); props[i].x = x * 30 + 15; props[i].y = y * 30 + 15; props[i].type = rand() % 3; // 随机道具类型 props[i].active = 1; props[i].duration = 500; // 道具持续时间 } } }我vs2022运行报错,你帮我看看修改一下
05-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值