C语言指针修改游戏按键绑定失效问题求助
解决可重绑定控件的生效问题
看起来你遇到的问题核心是参数传递错误和指针操作逻辑错误,导致除了ConfirmButton外,其他按键的实际绑定没有更新到全局变量上。咱们一步步拆解问题并修复:
1. 函数调用的参数传递错误
你当前的调用方式是:
ControlsMenu(*MoveLeftP,*MoveRightP,*MoveUpP,*MoveDownP,*BackButtonP,*ConfirmButtonP,*ShowStatsP,*ShowInventoryP,*ShowLegendP,*ShowControlsP);
这里你把指针MoveLeftP解引用(*MoveLeftP),传递的是char类型的按键值,但ControlsMenu的参数要求是char*指针。这相当于把字符的ASCII值(比如'a'是97)当成内存地址传递,属于非法操作,会导致未定义行为——ConfirmButton能生效纯粹是巧合。
修正方式:直接传递指针变量本身,不需要解引用:
ControlsMenu(MoveLeftP, MoveRightP, MoveUpP, MoveDownP, BackButtonP, ConfirmButtonP, ShowStatsP, ShowInventoryP, ShowLegendP, ShowControlsP);
2. 函数内修改绑定的逻辑错误
在ControlsMenu的switch语句里,你写的是:
case 0: MoveLeft = Input; break;
这里的MoveLeft是函数的形参(char*类型),你直接给指针变量赋值,只是修改了形参的地址,并没有修改它指向的全局变量的值。
修正方式:需要解引用指针,修改指针指向的内存内容:
case 0: *MoveLeft = Input; break; case 1: *MoveRight = Input; break; case 2: *MoveUp = Input; break; case 3: *MoveDown = Input; break; case 4: *BackButton = Input; break; case 5: *ConfirmButton = Input; break; case 6: *ShowStats = Input; break; case 7: *ShowInventory = Input; break; case 8: *ShowLegend = Input; break; case 9: *ShowControls = Input; break;
3. 修复ControlNames数组的定义错误
你当前的ControlNames是char数组,存储的是指针的地址(转成char后的值),这完全不符合你的需求。应该把它改成char*数组,用来存储各个按键的指针,这样显示的时候才能正确获取当前的按键值:
char* ControlNames[] = {MoveLeft, MoveRight, MoveUp, MoveDown, BackButton, ConfirmButton, ShowStats, ShowInventory, ShowLegend, ShowControls};
然后在显示的时候,需要解引用指针获取字符:
printf("%c", ToUpper(*ControlNames[i]));
4. 其他小问题修正
- 你的
MaxArray设为8,但实际菜单有10个选项(索引0-9),应该改成int MaxArray = 9;,避免菜单选择时越界。 - 循环里的
for (int i = 0; i < 9; i++)应该改成i < 10,才能显示所有10个控制选项。 - 判断确认按键的条件里,也要解引用
ConfirmButton指针:Input == *ConfirmButton,否则你是在和指针地址做比较,逻辑错误。
修复后的核心代码片段
修正后的函数调用
ControlsMenu(MoveLeftP, MoveRightP, MoveUpP, MoveDownP, BackButtonP, ConfirmButtonP, ShowStatsP, ShowInventoryP, ShowLegendP, ShowControlsP);
修正后的ControlsMenu关键部分
void ControlsMenu(char *MoveLeft, char *MoveRight, char *MoveUp, char *MoveDown, char *BackButton, char *ConfirmButton, char *ShowStats, char *ShowInventory, char *ShowLegend, char *ShowControls) { //Input char Input = '0'; //Menu Variables char* ControlNames[] = {MoveLeft, MoveRight, MoveUp, MoveDown, BackButton, ConfirmButton, ShowStats, ShowInventory, ShowLegend, ShowControls}; char *MainMenuNames[] = {"- Move Left", "- Move Right","- Move Up","- Move Down","- Back","- Confirm","- Show Stats","- Show Inventory","- Show Legend","- Show Controls"}; int MenuChosen = 0; int *MenuPointer = &MenuChosen; int MinArray = 0; int MaxArray = 9; // 修正为9,匹配0-9的索引 //Main Loop do { system("cls"); for (int i = 0; i < 10; i++) { // 修正为10,显示所有选项 printf("%c ", ToUpper(*ControlNames[i])); // 解引用获取字符 ShowMenu(MainMenuNames, i, MenuChosen); } Input = getch(); ControlMenu(Input, MenuChosen, MenuPointer, MinArray, MaxArray); if ((Input == *ConfirmButton || Input == ToUpper(*ConfirmButton))) { // 解引用ConfirmButton获取实际按键值 system("cls"); printf("Changing key binding for %s\n", MainMenuNames[MenuChosen]); printf("Old Binding: %c\n", ToUpper(*ControlNames[MenuChosen])); printf("Press the key you want to bind\n"); Input = getch(); *ControlNames[MenuChosen] = Input; // 解引用修改绑定值 //Commit Controls到全局变量 switch (MenuChosen) { case 0: *MoveLeft = Input; break; case 1: *MoveRight = Input; break; case 2: *MoveUp = Input; break; case 3: *MoveDown = Input; break; case 4: *BackButton = Input; break; case 5: *ConfirmButton = Input; break; case 6: *ShowStats = Input; break; case 7: *ShowInventory = Input; break; case 8: *ShowLegend = Input; break; case 9: *ShowControls = Input; break; } } } while (1); }
这样修改后,所有按键的绑定应该都能正确更新到全局变量上,显示的文本和实际功能会保持一致。
内容的提问来源于stack exchange,提问作者VallyMan
相关产品推荐
相关产品推荐

