我的程序中存在一个有关碰撞的小错误

4

我已经努力尝试解决问题有一个小时了。
我将绘制正在发生的事情。

char trap = 'Q'; 
char character = 'L';

.... 
.Q..
..L.
....

当L向上移动并且Q向右移动时,它们会相撞并且程序结束。但是:
....
.QL.
....
....

当L向左移动而Q向右移动时,它们并不像上面的例子一样发生碰撞,实际上发生的情况是:
....
..Q.
....
....



这是我的代码。抱歉我的英语不太好 :(

测试移动是否为'w','a','s'或'd':

void cave::move(int& x, int& y, char m, char unit)
{
                if ( m == 'W' || m == 'w' ) // if moves up
                {
                    floor[x][y] = tile;
                    x -= 1;
                    for ( unsigned short int x = 0; x < 3; x++ )
                    {
                            if ( floor[x][y] == wall && floor[x][y] == trap[x] )
                            {
                                x += 1;
                                trapsMove();
                        }
                        }
                        floor[x][y] = unit;
                }

                else if ( m == 'A' || m == 'a' ) // if moves to left
                {
                            floor[x][y] = tile;
                            y -= 1;
                        for ( unsigned short int x = 0; x < 3; x++ )
                        {
                            if ( floor[x][y] == wall && floor[x][y] == trap [x] )        
                            {
                                   y += 1;
                                   trapsMove();
                                }
                        }
                            floor[x][y] = unit;
                }

                else if ( m == 'S' || m == 's' ) // if moves down
                {
                        floor[x][y] = tile;
                            x += 1;
                            for ( unsigned short int x = 0; x < 3; x++ )
                        {
                                if ( floor[x][y] == wall && floor[x][y] == trap[x] )
                                {
                                    x -= 1;
                                    trapsMove();
                                }
                            }
                            floor[x][y] = unit;
                }
               else if ( m == 'D' || m == 'd' )  // if moves to right
               {
                        floor[x][y] = tile;
                            y += 1;
                            for ( unsigned short int x = 0; x < 3; x++ )
                            {
                                if ( floor[x][y] == wall && floor[x][y] == trapx] )
                                {
                                    y -= 1;
                                    trapsMove();
                                }
                            }
                            floor[x][y] = unit;
               }
               else 
                        control(); 
               return;
 }

AI移动函数

void cave::trapsMove() 
{
                    int r[3]; // each index will hold the movement of traps 
                    for ( unsigned short int x = 0; x < 3; x++ )
                    {
                            r[x] = rand() % 4 + 1;
                            if ( r[x] == 1 ) // moves up
                                move(traps_positionX[x],traps_positionY[x],'w',trap[x]);
                            else if ( r[x] == 2 ) // moves to left
                                move(traps_positionX[x],traps_positionY[x],'a',trap[x]);
                            else if ( r[x] == 3 ) // moves down
                                move(traps_positionX[x],traps_positionY[x],'s',trap[x]);
                            else if ( r[x] == 4 ) // moves to right
                                move(traps_positionX[x],traps_positionY[x],'d',trap[x]);
                    }
                    return;
}

检查是否发生碰撞

bool cave::collision()
{
                    for ( unsigned short int x = 0; x < 3; x++ )
                    {
                            if ( floor[character_positionX][character_positionY] == trap[x] )
                                return true;
                    }
                    return false;
}

3
问题描述得很好,但是需要读者阅读的代码比较多,其中大部分可能与问题无关。您可以尝试制作一个 SSCCE,使得代码更简洁易懂,仍保留原有意义。 - BoBTFish
@BoBTFish 抱歉,我以为他们只是运行代码。 - Lorence Hernandez
2
忙碌忙碌!一小段代码即将得到更多的帮助! - user146043
@KarolyHorvath谢谢你这样的回应。 - Lorence Hernandez
1个回答

1
根据您的代码,陷阱和玩家交换了位置。然而,陷阱(Q)的位置覆盖了玩家(L),变成了地板砖。

本质上发生了以下情况:

(1) .QL.

(2) .L.. // L 和 Q 占据同一块瓦片

(3) ..Q. // Q 用 '.' 瓦片覆盖了 L


你的代码存在卷积,因为你试图在一个函数中做太多事情或在几个不同的地方做它。这会导致你在上面的示例中错过必要的碰撞检查。
更好的策略是尝试构建程序流程。例如,你目前有:
(1)提示方向
(2)移动玩家块
(2a)如果玩家撞到陷阱或墙壁(你的代码中有错别字,必须使用||而不是&&),则移动陷阱 <-- (2a)是另一个陷阱,其中陷阱可以连续移动两次。
(3)移动陷阱
(4)检查碰撞
(5)重复从(1)
我认为你想要的是:
(1)提示方向
(2)移动玩家块
(2a)检查碰撞
(3)移动陷阱
(3a)检查碰撞
(6)重复从(1)

关于重构,请尝试回收代码。例如,在您的move()函数中,char 'w' (...)只影响'x'或'y'变量。因此,您也可以将其编写为

move(...) {
    if((m=='w')||(m=='W')) { y = y+1 }
    else if((m=='a')||(m=='A')) { x = x-1 } // same for SD

    if(floor[x][y] != wall) {
        // set new position to object, if it can't move, just don't set it
    }
}

这样,您就不必复制并粘贴您的for循环,并进行最小的修改。

哦,这对我来说有意义。 因为在游戏循环中,用户移动将首先执行,然后是陷阱移动。 所以如果我先执行trapmove,L会覆盖Q。 - Lorence Hernandez
“is another pitfall where traps can do two moves in a row.” 的意思是什么?如果陷阱的移动受限制,如撞墙或与共同陷阱碰撞,则它们只能执行两个移动。 - Lorence Hernandez
你说得对,我在一个函数中做了太多的事情,所以当玩家撞到墙壁时,陷阱会再次移动,而不是再次提示用户选择方向。 - Lorence Hernandez
我使用循环来检查所有的协同陷阱是否相互碰撞。 - Lorence Hernandez
你的move()函数可以调用trapsMove()函数,而trapsMove()函数又会调用move()函数——这个过程会一直持续,直到陷阱成功移动一次(当它们的第一次移动尝试被墙壁或其他陷阱阻挡时)。之后,你需要从main()方法中再次调用trapsMove()函数,这样陷阱在每个“游戏回合”中最多会移动两次,特别是当陷阱位于墙壁旁边时。 - Sorin Totuarez
当我运行游戏时,陷阱能够正常工作。 如果move()调用trapsMove()因为移动被禁止,则以下代码将不会被执行。 因此,floor[x][y] = unit;,这将移动单位,将不会被执行。那么在哪个部分他们每个游戏回合都移动了多次? - Lorence Hernandez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接