{希望改进我的帖子,请仍然建议您需要的其他代码,再次为我如此无知而感到抱歉,我决心克服这个问题,所以我真的很感谢您的时间!!
**编辑:感谢Frank的回复,程序现在开始,吸引三个敌人,但仅仅几秒钟后崩溃,因此下面的程序代码仍然适用,因为它基本上是移动循环和某处仍然有问题。
我意识到这是非常模糊的,我已经尽了最大的努力来解释它,但是如果没有人能给出建议的话,那么接下来的几秒钟它就应该足够完成这个教程了,并且在它完成后会对整个项目进行剖析,并且真的试着把它分解并尽可能多地学习。**
好的,我运行这个循环来创建新的敌人,然后把它们画到屏幕上,它现在起作用了,但是几秒钟后就崩溃了。下面是调试通过的步骤和在崩溃后显示的调用堆栈。希望你能帮忙!
这是一个视频教程im跟随和im卡住,找不到答案。一遍又一遍地检查代码。(完整的代码位于文章的底部(代码块),但我已经尝试在这篇文章中包含尽可能多的信息)。
其职能是:
level->addEnemies(3);在主game.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() Func:
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);
}
}
}idleUpdate():
void Enemy::idleUpdate(void)
{
if (goal)
simulateAI(); <------ Goes to this func
}simulateAI():
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 neededisValidMove功能:
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 int数组的界限。
另一个编辑:
这里是雪碧类,如果有帮助的话,如果需要的话,会在更多的地方进行编辑。
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
发布于 2011-06-19 15:31:14
这可能不是实际的问题,但可能是相关的。在Level::addEnemies(int num)函数中创建随机位置的代码将始终返回xpos和ypos的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,这将给出一些未定义的数字。使用这个数字,您正在尝试访问您的数组,这将导致程序崩溃的访问冲突。
所以,首先要做的是检查一个零距离,并以不同的方式处理。
https://stackoverflow.com/questions/6403127
复制相似问题