{私の投稿が改善されることを願っています。必要な他のコードを提案してください。また、無知で申し訳ありませんが、この問題を乗り越えることを決意しているので、お時間をいただきありがとうございます!!!}
**編集: 以下のフランクの返信に感謝します。プログラムが開始され、3 人の敵が描画されますが、わずか数秒後にクラッシュします。したがって、以下のプログラム コードは、基本的に移動ループとそこのどこかに何かがあるため、引き続き適用できます。まだ間違っています。
私はこれが非常に不明瞭であることを認識しており、説明するために最善を尽くしましたが、誰もアドバイスできない場合は、チュートリアルを完了するのに数秒で十分であり、終了後にプロジェクト全体を分析し、実際に試してみてくださいできるだけ多くのことを学びましょう**。
さて、新しい敵を作成するように設計されたこのループを実行し、それらを画面に描画すると、今は機能しますが、数秒後にクラッシュします. 以下は、デバッグが通過する手順と、クラッシュ後に表示された場合の最後のコールスタックです。あなたが助けてくれることを願っています!
これは私がフォローしているビデオチュートリアルであり、行き詰まっており、答えが見つかりません。コードを何度も確認しました。(完全なコードは投稿の下部にあります (コードブロック) が、この投稿にはできるだけ多くの情報を含めようとしました)
関数は次のとおり
です。 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);
}
}
}
アイドルアップデート():
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 がこのプロセスのどこかから切断されたことを示しており、drawengine の幅と高さの [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