我正在使用 SDL2 构建 C++ 游戏。一切进展顺利,我能够让玩家射出一颗子弹。后来我修改了我的代码以呈现多个项目符号,如下所示。
主游戏循环
void Game::gameLoop(){
Entity player;
Entity bulletHead;
Entity *bulletTail = new Entity();
bulletTail = &bulletHead;
player.x = 500;
player.y = 640;
player.dx = 0;
player.dy = 0;
player.texture = loadTexture((char*)"res/images/player.png");
SDL_QueryTexture(player.texture, NULL, NULL, &player.w, &player.h);
SDL_Texture *bulletTexture = loadTexture((char*)"res/images/bullet.png");
while(gameState != GameState::EXIT){
prepareScene(); // sets up rendering
handleEvents(); // collects and precesses user input
player.x += player.dx;
player.y += player.dy;
// Player key input
if(player.reload > 0) player.reload--;
if (up)
{
player.y -= 4;
}
if (down)
{
player.y += 4;
}
if (left)
{
player.x -= 4;
}
if (right)
{
player.x += 4;
}
// allow fire bullet every 8 frames
if(fire && player.reload == 0){
player.reload = 8;
// Create bullet
Entity *bullet = new Entity();
memset(bullet, 0, sizeof(Entity));
bulletTail->next = bullet;
bulletTail = bullet;
bullet->x = player.x + 8;
bullet->y = player.y;
bullet->dx = 0;
bullet->dy = -PLAYER_BULLET_SPEED;
bullet->health = 1;
bullet->texture = bulletTexture;
SDL_QueryTexture(bullet->texture, NULL, NULL, &bullet->w, &bullet->h);
}
// handle physics and render for each bullet
Entity *b = new Entity();
Entity *prev = new Entity();
prev = &bulletHead;
// Error starts here 👇 🚫🚫🚫🚫🚫🚫🚫🚫🚫🚫🚫
for (b = bulletHead.next ; b != NULL ; b = b->next){
b->x += b->dx;
b->y += b->dy;
blit(b->texture, b->x, b->y);
if(b->y < 0){
if (b == bulletTail)
{
bulletTail = prev;
}
prev->next = b->next;
free(b);
b = prev;
}
prev = b;
}
// Error stops here 🚫🚫🚫🚫🚫🚫🚫🚫🚫🚫🚫
blit(player.texture, player.x, player.y); // display image
presentScene(); // displays scene
SDL_Delay(16); // limits fps to around 62fps
}
SDL_DestroyWindow(window);
SDL_Quit();
}
如上所示,我可以成功创建项目符号,但每当我包含 for 循环以遍历我的项目符号链接列表并移动/绘制它们时,程序都会意外关闭。没有显示错误,我一运行它就关闭了。删除 for 循环是有效的,但我需要一种方法来遍历项目符号的链接列表并绘制/动画它们。
任何帮助将不胜感激
标准库有很多容器供你使用,例如
std::vector
。下面的例子假设你有一个std::vector<Entity> bullets
。
如果你想遍历一个向量并且可以选择在你走的时候删除项目,有两个选项,你可以使用erase
方法,它从向量中删除一个项目并返回一个新迭代器。
使用:
for (auto it = bullets.begin(); it != bullets.end(); /* no-op, see below */) {
// do stuff with *it
if (/* bullet needs to be removed */) {
it = bullets.remove(it);
} else {
// advance to the next item
it++;
}