视觉 杀死入侵者在C++不起作用

visual Killing the invaders doesn't work in C++

本文关键字:C++ 不起作用 入侵者 视觉      更新时间:2023-10-16

我知道,要杀死C 的入侵者,我需要做一个对撞机。但是,没有什么能杀死那场比赛的入侵者。这是标题中的代码:

bool DoCollision(float Xbpos, float Ybpos, int BulWidth, int BulHeight, float Xipos, float Yipos, int InvWidth, int InvHeight);

这是我初始化的功能:

bool Game::DoCollision(float Xbpos, float Ybpos, int BulWidth, int BulHeight, float Xipos, float Yipos, int InvWidth, int InvHeight) {
if (Xbpos+BulWidth < Xipos || Xbpos > Xipos+InvWidth) return false;
if (Ybpos+BulHeight < Yipos || Ybpos > Yipos+InvHeight) return false;
return true;
}

,如果有人按空格键,就会发生这种情况:

if (code == 57) { //Space
    myKeyInvader.MeBullet.Active = true;
    myKeyInvader.MeBullet.Xpos = myKeyInvader.Xpos + 10;
    myKeyInvader.MeBullet.Ypos = myKeyInvader.Ypos - 10;
    myKeyInvader.MeBullet.yvuel = 0.2;
    myKeyInvader.MeBullet.BulletP->CopyTo(m_Screen,myKeyInvader.Xpos,myKeyInvader.Ypos);
    if (DoCollision(Invaders[counter].MyBullet.Xbpos,Invaders[counter].MyBullet.Ybpos,Invaders[counter].MyBullet.BulWidth,
    Invaders[counter].MyBullet.BulHeight,Invaders[counter].Xipos,Invaders[counter].Yipos,Invaders[counter].InvWidth,Invaders[counter].InvHeight)) {
        //myKeyInvader.Ypos = 100;
        Invaders[counter].Active = false;
        printf("Collide!n");
    }
}

有人知道怎么了吗?

问题不是C 。问题是您的使用方式。像书面的唯一唯一的方法是,如果入侵者在您的顶部。但这为时已晚。外星人入侵者已经杀死了你。

您需要做的是将这些子弹变成随着时间的流逝而传播的对象,就像您的入侵者是您随着时间的流逝而传播的对象。对用户按空格键的响应应该是将子弹的新实例添加到一组活动子弹中。这些活跃的子弹中的每一个都有随时间变化的位置。在每个时间步骤中,您都应该根据规则来推动活跃入侵者的状态,以决定入侵者如何按照决定子弹移动的规则行动和推进活跃子弹的状态。当子弹到达屏幕的顶部时,将其卸下,如果外星人入侵者到达屏幕的底部,请进行游戏。

在繁殖,删除屏幕外的子弹并检查游戏之后,您想检查n个子弹中的每个子弹之间的碰撞。检测到碰撞时,将子弹从一组活跃的子弹中删除,然后从活动入侵者组中删除外星人入侵者。当然,您需要一些漂亮的图形来向用户表明另一个外星人咬了灰尘。

旁边:作为一个NXM问题,此检查可能是CPU使用情况最大的耗竭。您可以使用一些简单的启发式方法加快此功能。

您可以自己使用newdelete仔细地管理外星人入侵者和子弹的集合,以防止入侵者和子弹在内存泄漏中杀死您的程序。您不必这样做。C 为您提供了管理这些集合的一些漂亮工具。使用C 标准库集合之一,而不是滚动您自己的藏品。例如,std::vector<AlienInvader> invaders;std::list<AlienInvader> invaders,对于子弹而言相同。您将从中间删除很多,这表明std::liststd::deque可能比std::vector更合适。

您只是在创建射击项目的碰撞

时测试碰撞

不应该是每个帧中每个现有项目的主循环中的测试碰撞?

不用担心,C 有您需要杀死入侵者的全部:)))

基于如此少的代码提供建议并不容易,但是这里唯一的逻辑错误似乎是您仅在按下空间时测试碰撞;您应该在外部循环中测试它:

if (code == 57) { //Space
    myKeyInvader.MeBullet.Active = true;
    myKeyInvader.MeBullet.Xpos = myKeyInvader.Xpos + 10;
    myKeyInvader.MeBullet.Ypos = myKeyInvader.Ypos - 10;
    myKeyInvader.MeBullet.yvuel = 0.2;
    myKeyInvader.MeBullet.BulletP->CopyTo(m_Screen,myKeyInvader.Xpos,myKeyInvader.Ypos);
}

从逻辑的角度来看,按空间应发射子弹:子弹的起始位置是设置的,其速度在y轴上也是如此(以便它上升)。

检查碰撞的代码应在此if块之外。实际上,仅当您仍在按空格时才执行此代码块 - 即:仍然 difing - 。仅当您"仍在射击"时才能检查碰撞吗?您发射了一颗子弹并开始等待它以某种方式摧毁入侵者干扰的事实是,该子弹可以到达侵略者,并确实摧毁了它的事实?当然不是!

if (DoCollision(Invaders[counter].MyBullet.Xbpos,Invaders[counter].MyBullet.Ybpos,Invaders[counter].MyBullet.BulWidth,
    Invaders[counter].MyBullet.BulHeight,Invaders[counter].Xipos,Invaders[counter].Yipos,Invaders[counter].InvWidth,Invaders[counter].InvHeight)) {
    //myKeyInvader.Ypos = 100;
    Invaders[counter].Active = false;
    printf("Collide!n");
}

您希望在外部循环中检查碰撞,也可能包含关键按下的检查。这样,即使您只是查看屏幕并等待,该程序仍在测试条件,并且在满足情况后,执行与碰撞事件相关的代码(也就是说:入侵者被"灭活")。

您说的是//Space,是什么是32(如果是ASCII),而不是57?程序是否流入if == 57块?

您的代码看起来不错,但是您需要在碰撞检查器周围进行两个循环:一个用于检查所有入侵者(不仅仅是其中一个),另一个用于检查沿其轨迹的每个子弹位置,不仅是离开枪的那一刻。

我将假设我们有一个辅助功能,它可以移动子弹并返回它是否仍在屏幕中:

bool bulletisinscreen();

然后我们可以编写循环:

if (code == 57) { // Space
  while (BulletIsInScreen()) {
    for (size_t i = 0; i < counter; ++i) { // counter is the number of invaders,
                                           // according to your comment to your own answer
      myKeyInvader.MeBullet.Active = true;
      myKeyInvader.MeBullet.Xpos = myKeyInvader.Xpos + 10;
      myKeyInvader.MeBullet.Ypos = myKeyInvader.Ypos - 10;
      myKeyInvader.MeBullet.yvuel = 0.2;
      myKeyInvader.MeBullet.BulletP->CopyTo(m_Screen,myKeyInvader.Xpos,myKeyInvader.Ypos);
      if (DoCollision(Invaders[i].MyBullet.Xbpos, Invaders[i].MyBullet.Ybpos,
                      Invaders[i].MyBullet.BulWidth, Invaders[i].MyBullet.BulHeight,
                      Invaders[i].Xipos, Invaders[i].Yipos,
                      Invaders[i].InvWidth, Invaders[i].InvHeight)) {
        //myKeyInvader.Ypos = 100;
        Invaders[i].Active = false;
        printf("Collide!n");
      }
    }
  }
}

现在这应该按预期工作。