gpt4 book ai didi

c++ - 崩溃,在控制台应用程序上,试图吸引敌人,出界(以下视频教程)

转载 作者:行者123 更新时间:2023-12-02 02:00:03 33 4
gpt4 key购买 nike

{希望改进我的帖子,仍然请建议您需要的任何其他代码,再次为我的无知感到抱歉,我决心克服这个问题,所以我真的很感谢您的时间! !}

**编辑:感谢弗兰克在下面的回复,程序现在启动并绘制了三个敌人,但几秒钟后就崩溃了,因此下面的程序代码仍然适用,因为它基本上是移动循环和某处仍然有问题。

我意识到这是非常晦涩的,我已经尽力解释它,但如果没有人可以建议,那么它的几秒钟应该足以完成教程无论如何,我会在完成后剖析整个项目并真正尝试并将其分解并尽可能多地学习。**

好的,所以我运行这个旨在创建新敌人的循环,然后将它们绘制到屏幕上,它现在可以工作,但几秒钟后崩溃了。下面是调试所经历的步骤以及最后的调用堆栈(如果崩溃后显示的内容)。希望您能帮忙!

这是一个视频教程,我正在关注,但我卡住了,找不到答案。一遍又一遍地检查代码。 (完整的代码位于帖子的底部(代码块),但我尝试在这篇文章中包含尽可能多的信息)

功能是:
关卡->addEnemies(3);

看起来像主游戏.cpp:

    bool Game::run(void)
{
level = new Level(&drawArea, 30, 20);

drawArea.createBackgroundTile(TILE_EMPTY, ' ');
drawArea.createBackgroundTile(TILE_WALL, 219);

drawArea.createSprite(SPRITE_PLAYER, 1);
drawArea.createSprite(SPRITE_ENEMY, '$');

player = new Character(level, &drawArea, 0);

level->draw();
level->addPlayer(player);
level->addEnemies(3); <-------- SKIPS TO THIS FUNC

char key = ' ';

startTime = timeGetTime();
frameCount = 0;
lastTime = 0;

posx = 0;

player->move(0,0);

while (key != 'q')
{
while (!getInput(&key))
{
timerUpdate();
}
level->keyPress(key);
}
delete player;

return true;
}

完整的函数如下,请注意,当我从主游戏循环中删除此 addEnemies 函数时,一切都运行得很好,没有崩溃,因此它与即将推出的函数有关。

    void Level::addEnemies(int num)
{
int i = num;

while (i > 0)
{
int xpos = int(float(rand() % 100) / 100) * (width - 2) + 1;
int ypos = int(float(rand() % 100) / 100) * (height - 2) + 1;

if (level[xpos][ypos] != TILE_WALL)
{
Enemy *temp = new Enemy(this, drawArea, SPRITE_ENEMY,
(float)xpos, float(ypos));

temp->addGoal(player);

addNPC((Sprite *)temp);

i--;
}
}
}

它似乎没有任何问题地完成了这个功能。

此函数返回游戏循环并正常执行后,进入计时器更新,没有任何问题。这是timerUpdate函数:

    void Game::timerUpdate(void)
{

double currentTime = timeGetTime() - lastTime;

if (currentTime < GAME_SPEED)
return;

level->update(); <--------SKIPS TO THIS FUNC

frameCount++;


lastTime = timeGetTime();
}

这是 Level->Update() 函数:

    void Level::update(void)
{
for (Iter = npc.begin(); Iter != npc.end(); Iter++)
{
(*Iter)->idleUpdate(); <-------------SKIPS TO THIS FUNC

if ((*Iter)->isAlive() == false)
{
Sprite *temp = *Iter;
//kill the enemy
Iter--;
delete temp;
npc.remove(temp);
}
}
}

空闲更新():

    void Enemy::idleUpdate(void)
{
if (goal)
simulateAI(); <------ Goes to this func
}

模拟AI():

    void Enemy::simulateAI(void)
{
vector goal_pos = goal->getPosition();
vector direction;

direction.x = goal_pos.x - pos.x;
direction.y = goal_pos.y - pos.y;

float mag = sqrt(direction.x * direction.x + direction.y * direction.y);

direction.x = direction.x / (mag);
direction.y = direction.y / (mag);

if (!move(direction.x, direction.y)) <------ SKIPS TO THIS FUNC
{
while (!move(rand() % 3 - 1, rand() % 3 - 1))
{

}
}

移动功能:

    bool Sprite::move(float x, float y)
{

int xpos = (int)(pos.x +x);
int ypos = (int)(pos.y +y);

if (isValidLevelMove(xpos,ypos)) SKIPS TO THIS FUNC
{
//.....rest not needed

isValidMove 函数:

    bool Sprite::isValidLevelMove(int xpos, int ypos)
{
if (level->level[xpos][ypos] != TILE_WALL) <-------------THIS LINE CRASHES!!
return true;

return false;
}

我真的不明白哪里出了问题,以及为什么最后调用 stakc 显示 xpos 和 ypos 的出界数字如此之高。

这是完整的调用堆栈:

    #0 00402920 Sprite::isValidLevelMove (this=0x791498, xpos=-2147483648, ypos=-2147483648) (sprite.cpp:95)
#1 00000000 0x00401750 in Enemy::move (this=0x791498, x=-nan(0x400000) (enemy.cpp:21)
#2 00401892 Enemy::simulateAI (this=0x791498) (enemy.cpp:67)
#3 004017E5 Enemy::idleUpdate (this=0x791498) (enemy.cpp:46)
#4 0040226E Level::update (this=0x792e90) (level.cpp:86)
#5 00401CB8 Game::timerUpdate (this=0x28fec0) (game.cpp:93)
#6 00401BB5 Game::run (this=0x28fec0) (game.cpp:54)
#7 0040258D main() (main.cpp:11)

这基本上告诉我 xpos 和 ypos 已经在这个过程中的某个地方被破坏了,这肯定会导致崩溃,因为它超出了绘图引擎宽度和高度的 [30][20] int 数组的范围。

另一个编辑:

这是 Sprite 类,如果有帮助,将在需要时编辑更多内容。

    enum
{
SPRITE_CLASSID,
CHARACTER_CLASSID,
ENEMY_CLASSID
};

struct vector
{
float x;
float y;
};

class Sprite
{
public:
Sprite(Level *l, DrawEngine *de, int s_index, float x = 1, float y = 1, int i_lives = 1);
~Sprite();

vector getPosition(void);
float getX(void);
float getY(void);

virtual void addLives(int num = 1);
int getLives(void);
bool isAlive(void);

virtual void idleUpdate(void);

virtual bool move(float x, float y);

protected:
Level *level;
DrawEngine *drawArea;

vector pos;

int spriteIndex;
int numLives;

int classID;

vector facingDirection;

void draw(float x, float y);
void erase(float x, float y);

bool isValidLevelMove(int xpos, int ypos);

};

无论如何,如果有任何帮助,我都会非常感激,我知道我一定看起来完全没用,但我真的决心学习,你们能提供的任何帮助都是无价的!!!!

完整代码文件(代码块):http://www.mediafire.com/?5xz2seadmagbetb

最佳答案

这可能不是实际问题,但可能是相关的。在 Level::addEnemies(int num) 函数中创建随机位置的代码将始终为 xposypos 返回 1 .

这是因为您应用强制转换的方式。您似乎错过了最终转换为 int 的括号。我想你想要这样的东西:

int xpos = int((float(rand() % 100) / 100) * (width - 2)) + 1;

更新:

导致崩溃的代码位于您的 simulateAI() 函数中。与:

float mag = sqrt(direction.x * direction.x + direction.y * direction.y);

您计算两点之间的距离,但如果两点具有相同的坐标,则距离为0

稍后使用:direction.x = Direction.x/(mag);,您除以这个潜在的0,结果您的坐标将包含NaN 。在您的 bool Sprite::move(float x, float y) 函数中,您将这些 NaN 转换为 int,这将为您提供一些未定义的值数字。您尝试使用此数字访问数组,这将导致访问冲突,从而导致程序崩溃。

所以首先要做的是检查零距离并以不同的方式处理它。

关于c++ - 崩溃,在控制台应用程序上,试图吸引敌人,出界(以下视频教程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6403127/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com