好久没编个像样的程序,手操编了一下,再不练一下脑袋就生锈了为什么选awds这几个按键(玩游戏的都懂)#include graphics.h//引用图形库头文件 #include conio.h #include Windows.h #include mmsystem.h #include exception//异常处理头文件 #include fstream//文件操作 #include string.h//字符串处理 #include iostream #include ctime #include stdlib.h #pragma comment(lib,winmm.lib) // 添加互斥锁句柄 HANDLE hMutex; bool bgmEnabledtrue;//bgm默认开启 int difficulty1;//默认简单模式 double speed1;//默认速度 int score0;//得分 bool keyAfalse,keyWfalse,keyDfalse,keySfalse;//按键状态 int left,top,right,bottom;//按键位置 DWORD timeA0,timeW0,timeD0,timeS0;//按键生成时间记录 bool gameRunningtrue;//游戏是否继续 char howToEnd[20];//失败形式 char whichKeyFail;//哪一个按键导致的失败 bool gameEndfalse;//判断游戏是否结束 struct KeyRect{//存储每个按键位置的矩形区域 int left, top, right, bottom; }rectA,rectW,rectD,rectS; void gameOver(char howToEnd[],char whichKeyFail){//游戏结束 if(gameEnd) return;//防止反复调用 gameEndtrue; setfillcolor(BLACK); setlinecolor(BLACK); fillrectangle(10,100,500,450); //清除剩余按键 if(whichKeyFaila){ setfillcolor(RED); setlinecolor(BLACK); fillrectangle(100,250,150,300); outtextxy(10015,2508,whichKeyFail); } if(whichKeyFailw){ setfillcolor(RED); setlinecolor(BLACK); fillrectangle(225,150,275,200); outtextxy(22515,1508,whichKeyFail); } if(whichKeyFaild){ setfillcolor(RED); setlinecolor(BLACK); fillrectangle(350,250,400,300); outtextxy(35015,2508,whichKeyFail); } if(whichKeyFails){ setfillcolor(RED); setlinecolor(BLACK); fillrectangle(225,250,275,300); outtextxy(22515,2508,whichKeyFail); } if(strcmp(howToEnd,timeout)0){//游戏结束以时间耗尽结束 settextstyle(35,25,微软雅黑); settextcolor(RED); char failc[]Time Out! You Fail!; outtextxy(20,70,failc);//显示失败标签 } if(strcmp(howToEnd,fatfinger)0){//游戏结束以按错键结束 settextstyle(35,25,微软雅黑); settextcolor(RED); char failc[]Fat Finger! You Fail!; outtextxy(10,70,failc);//显示失败标签 } settextstyle(25,15,微软雅黑); char restartc[]Press Any Key To Esc; outtextxy(50,110,restartc);//显示退出标签 } void graphLoad(){ setfillcolor(BLACK); setlinecolor(BLACK); fillrectangle(0,10,200,50); //用黑色背景覆盖原score settextstyle(30,15,微软雅黑);//设置字体格式 setfillcolor(WHITE); settextcolor(WHITE); char sc[]Score:; char scInt[50]; itoa(score,scInt,10);//将int转为char数组 outtextxy(45,10,sc);//score标签 outtextxy(145,10,scInt);//得分栏 char dc[]Difficulty:; char dInt[10]; itoa(difficulty,dInt,10); outtextxy(245,10,dc);//difficulty标签 outtextxy(395,10,dInt);//难度栏 } void gameConfig(){//游戏配置 FILE* filefopen(config.txt,r);//打开配置文件 if(fileNULL){ return;//文件不存在,退出配置读取采用默认值 } int bgmValue,diffValue; fscanf(file,%d,bgmValue);//读取第一行bgm fscanf(file,%d,diffValue);//读取第二行difficulty bgmEnabled(bgmValue1); difficultydiffValue; fclose(file); if(difficulty2){ speed0.7;//中等难度 } if(difficulty3){ speed0.5;//困难难度 } if(difficulty4){ speed0.1;//外挂难度 } } void loadMusic(){//载入音乐 if (!bgmEnabled){//如果bgmEnabled为false则不载入music return; } try{ mciSendString(open \bgm.mp3\ type mpegvideo alias myMusic,NULL,0,NULL);//打开音频文件 mciSendString(play myMusic repeat,NULL,0,NULL);//设置循环播放 }catch(std::exception e){//标准异常类要全小写 ; } } void generateOne(char one){ if (onea){//a按键位置 left100; top250; right150; bottom300; rectA.left left; rectA.top top; rectA.right right; rectA.bottom bottom; //保存a位置 } if (onew){//w按键位置 left225; top150; right275; bottom200; rectW.left left; rectW.top top; rectW.right right; rectW.bottom bottom; //保存w位置 } if (oned){//d按键位置 left350; top250; right400; bottom300; rectD.left left; rectD.top top; rectD.right right; rectD.bottom bottom; //保存d位置 } if (ones){//s按键位置 left225; top250; right275; bottom300; rectS.left left; rectS.top top; rectS.right right; rectS.bottom bottom; //保存a位置 } setfillcolor(WHITE);//填充颜色 setlinecolor(BLACK);//边框颜色 fillrectangle(left,top,right,bottom);//填充框架 setbkmode(TRANSPARENT); settextcolor(BLACK);//文本颜色 outtextxy(left15,top8,one);//按键字符 } DWORD WINAPI thinkGenerateKey(LPVOID lpParam){//判断创建awds按键函数 char awdsArr[]{a,w,d,s};//创建awds数组 char remainingKeys[4];//存储还未生成的按键 int remainingCount;//剩余按键数量 srand((unsigned)time(NULL));//设置随机种子 while(gameRunning){ Sleep(speed*1000);//每次刷新按键等待时间 if(!gameRunning){//再次检查游戏是否还在运行(防止最后生成一个按键) break; } WaitForSingleObject(hMutex, INFINITE); // 加锁 remainingCount0; if(!keyA) remainingKeys[remainingCount]a; if(!keyW) remainingKeys[remainingCount]w; if(!keyD) remainingKeys[remainingCount]d; if(!keyS) remainingKeys[remainingCount]s; if(remainingCount0){ ReleaseMutex(hMutex); continue;//如果所有按键都生成了,跳过,等待玩家按完其他键 } int randomIndexrand()%remainingCount; char generatedKeyremainingKeys[randomIndex]; //从未生成的按键中随机选一个 switch(generatedKey){//生成按钮的时候记录时间 case a:keyAtrue;generateOne(a);timeAGetTickCount();break; case w:keyWtrue;generateOne(w);timeWGetTickCount();break; case d:keyDtrue;generateOne(d);timeDGetTickCount();break; case s:keyStrue;generateOne(s);timeSGetTickCount();break; } ReleaseMutex(hMutex); // 解锁 } return NULL;//退出线程 } void removeKey(char one){ WaitForSingleObject(hMutex, INFINITE); setfillcolor(BLACK); setlinecolor(BLACK); //用黑色背景覆盖按键 switch(one){ case a: fillrectangle(rectA.left,rectA.top,rectA.right,rectA.bottom); break; case w: fillrectangle(rectW.left,rectW.top,rectW.right,rectW.bottom); break; case s: fillrectangle(rectS.left,rectS.top,rectS.right,rectS.bottom); break; case d: fillrectangle(rectD.left,rectD.top,rectD.right,rectD.bottom); break; } ReleaseMutex(hMutex); } DWORD WINAPI timeOutFail(LPVOID IpParam){//时间耗尽失败 while(gameRunning){ Sleep(50);//每50ms检查一次 WaitForSingleObject(hMutex, INFINITE); DWORD currentTimeGetTickCount();//记录现在时间(必须用DWORD,因为GetTickCount返回的是DWORD32位无符号整数) DWORD timeOut(DWORD)(speed*3000);//超时时间speedx3 if(keyA timeA!0 (currentTime-timeA)timeOut){ whichKeyFaila; gameRunningfalse; ReleaseMutex(hMutex); break; } if(keyW timeW!0 (currentTime-timeW)timeOut){ whichKeyFailw; gameRunningfalse; ReleaseMutex(hMutex); break; } if(keyD timeD!0 (currentTime-timeD)timeOut){ whichKeyFaild; gameRunningfalse; ReleaseMutex(hMutex); break; } if(keyS timeS!0 (currentTime-timeS)timeOut){ whichKeyFails; gameRunningfalse; ReleaseMutex(hMutex); break; } ReleaseMutex(hMutex); //如果超时,退出游戏继续循环 } if(howToEnd[0]\0){ strcpy(howToEnd,timeout); gameOver(howToEnd,whichKeyFail);//跳转到游戏结束画面 } return NULL; } DWORD WINAPI checkKeyPress(LPVOID lpParam){//检测按键按下状态 while(gameRunning){ if(_kbhit()){ char key_getch();//获取键盘输入 WaitForSingleObject(hMutex, INFINITE); switch(key){ case a: case A: if(keyA){ keyAfalse; removeKey(a);//删除a按键状态 score1;//加1分 graphLoad(); }else{//按了不存在的a键 whichKeyFaila; strcpy(howToEnd,fatfinger); gameRunningfalse; ReleaseMutex(hMutex); gameOver(howToEnd,whichKeyFail); return NULL; } break; case w: case W: if(keyW){ keyWfalse; removeKey(w);//删除w按键状态 score1;//加1分 graphLoad(); }else{//按了不存在的w键 whichKeyFailw; strcpy(howToEnd,fatfinger); gameRunningfalse; ReleaseMutex(hMutex); gameOver(howToEnd,whichKeyFail); return NULL; } break; case d: case D: if(keyD){ keyDfalse; removeKey(d);//删除d按键状态 score1;//加1分 graphLoad(); }else{//按了不存在的d键 whichKeyFaild; strcpy(howToEnd,fatfinger); gameRunningfalse; ReleaseMutex(hMutex); gameOver(howToEnd,whichKeyFail); return NULL; } break; case s: case S: if(keyS){ keySfalse; removeKey(s);//删除s按键状态 score1;//加1分 graphLoad(); }else{//按了不存在的s键 whichKeyFails; strcpy(howToEnd,fatfinger); gameRunningfalse; ReleaseMutex(hMutex); gameOver(howToEnd,whichKeyFail); return NULL; } break; case 27: gameRunningfalse; ReleaseMutex(hMutex); return NULL; } ReleaseMutex(hMutex); } Sleep(10); } return NULL; } int main() { initgraph(500, 400,NULL);//创建绘图窗口,大小为500x400像素 // 创建互斥锁 hMutex CreateMutex(NULL, FALSE, NULL); gameConfig();//调用gameConfig函数 loadMusic();//调用loadMusic函数 graphLoad();//调用graphLoad函数 // 创建Windows线程 HANDLE hThinkThreadCreateThread(NULL,0,thinkGenerateKey,NULL,0,NULL);//创建thinkGenerateKey的线程 HANDLE hTimeFailThreadCreateThread(NULL,0,timeOutFail,NULL,0,NULL);//创建timeOutFail的线程 HANDLE hCheckThreadCreateThread(NULL,0,checkKeyPress, NULL,0,NULL);//创建checkKeyPress的线程 // 等待线程结束 WaitForSingleObject(hThinkThread,INFINITE); WaitForSingleObject(hTimeFailThread,INFINITE); WaitForSingleObject(hCheckThread,INFINITE); // 关闭线程句柄 CloseHandle(hThinkThread); CloseHandle(hTimeFailThread); CloseHandle(hCheckThread); CloseHandle(hMutex); _getch();//按任意键继续 closegraph();//关闭绘图窗口 return 0; }