2013-04-24 52 views
1

我在使用SFML在C++中製作小行星遊戲。雖然射擊子彈似乎有問題。雖然每次擊中子彈時班級似乎都能正常工作,但遊戲速度顯着下降。這是宇宙飛船和子彈的代碼。我似乎無法找到它的問題!感謝您的時間。當射擊項目符號時SFML遊戲速度減慢

這是這艘船的代碼:

#include "Spaceship.h" 

Spaceship::Spaceship(void){} 

Spaceship::~Spaceship(void){} 

void Spaceship::LoadResources() 
{ 

    if(!shipAnimImg.LoadFromFile("Resources/Images/SpaceshipAnimation.png")) 
     std::cout <<"Could not locate the ship animation image" <<std::endl; 

    if(!shipIdleImg.LoadFromFile("Resources/Images/SpaceshipIdle.png")) 
     std::cout <<"Could not locate the ship idle image" <<std::endl; 

    if(!bulletImg.LoadFromFile("Resources/Images/Bullet.png")) 
     std::cout <<"Could not locate the bullet image" <<std::endl; 

    shipSpr.SetImage(shipIdleImg); 
    shipSpr.SetScale(0.5,0.5); 
    shipSpr.SetCenter(shipIdleImg.GetWidth()/2,shipIdleImg.GetHeight()/2); 

    x = DEFAULT_SCREENWIDTH/2; 
    y = DEFAULT_SCREENHEIGHT/2; 

    shipSpr.SetPosition(x,y); 
    shipSpr.SetRotation(90); 

    std::cout<<shipSpr.GetCenter().x<<std::endl; 
    std::cout<<shipSpr.GetCenter().y<<std::endl; 

    vx = 0.2; 
    vy = 0.2; 

    isBulletOnScreen = false; 
    isPressed = false; 
} 

void Spaceship::UnloadResources(){} 

void Spaceship::Update(sf::RenderWindow &Window,sf::Event event) 
{ 

    if (Window.GetInput().IsKeyDown(sf::Key::A)) 
    { 
     shipSpr.Rotate(0.08); 
    } 

    if (Window.GetInput().IsKeyDown(sf::Key::D)) 
    { 
     shipSpr.Rotate(-0.08); 
    } 

    if (Window.GetInput().IsKeyDown(sf::Key::W)) 
    { 
     x += (cos(shipSpr.GetRotation() * (3.14159265/180.0)) *0.2); 
     y -= (sin(shipSpr.GetRotation() * (3.14159265/180.0)) *0.2); 
     shipSpr.SetPosition(x,y); 
    } 



    if (Window.GetInput().IsKeyDown(sf::Key::Space) && !isPressed) 
    { 
    isBulletOnScreen = true; 
    isPressed = true; 
    bullets.push_back(new Bullet(shipSpr.GetPosition().x,shipSpr.GetPosition().y,0.3,shipSpr.GetRotation(),bulletImg)); 
    } 

    if (event.Type == sf::Event::KeyReleased) 
    { 
     isPressed = false; 
    } 

    if(bullets.size() != 0) 
    { 
     for (int i=0; i<bullets.size(); i++) 
     { 
      bullets[i]->Update(Window,event); 
      if ((bullets[i]->GetX() > DEFAULT_SCREENWIDTH + 40) || (bullets[i]->GetX() < 0 - 40) || 
       (bullets[i]->GetY() > DEFAULT_SCREENWIDTH + 40) || (bullets[i]->GetY() < 0 - 40)) 
       { 
        bullets.erase(bullets.begin() +i); 
       } 
     } 
     std::cout<<bullets.size()<<std::endl; 
    } 
    std::cout<<bullets.size()<<std::endl; 

} 

void Spaceship::Draw(sf::RenderWindow &Window) 
{ 
    if(isBulletOnScreen) 
    for (int i=0; i<bullets.size(); i++) 
    { 
     Bullet *cur = bullets[i]; 
     bullets[i]->Draw(Window); 
     std::cout<<bullets.size()<<std::endl; 
    } 

    Window.Draw(shipSpr); 
} 

這是子彈:

#include "Bullet.h" 

Bullet::Bullet(void){} 

Bullet::Bullet(float x,float y,float v,float r,sf::Image image) 
{ 
    LoadResources(x,y,v,r,image); 
} 

Bullet::~Bullet(void){} 

void Bullet::LoadResources(float x,float y,float v,float r , sf::Image image) 
{ 
    this->x = x; 
    this->y = y; 
    this->v = v; 

    bulletImg = image; 
    bulletSpr.SetImage(bulletImg); 
    bulletSpr.SetScale(0.5,0.5); 
    bulletSpr.SetCenter(bulletImg.GetWidth()/2,bulletImg.GetHeight()/2); 
    bulletSpr.SetPosition(x,y); 
    bulletSpr.SetRotation(r); 
} 

void Bullet::UnloadResources(){} 

void Bullet::Update(sf::RenderWindow &Window,sf::Event event) 
{ 
    x += (cos(bulletSpr.GetRotation() * (3.14159265/180.0)) *v); 
    y -= (sin(bulletSpr.GetRotation() * (3.14159265/180.0)) *v); 

    bulletSpr.SetPosition(x,y); 
} 

void Bullet::SetX(float x) 
{ 
    this->x = x; 
} 

void Bullet::SetY(float y) 
{ 
    this->y = y; 
} 

void Bullet::SetRotation(float r) 
{ 
    rotation = r; 
} 

float Bullet::GetX() 
{ 
    return x; 
} 

float Bullet::GetY() 
{ 
    return y; 
} 

void Bullet::Draw(sf::RenderWindow &Window) 
{ 
    Window.Draw(bulletSpr); 
} 

編輯:改變了代碼,以便它加載的飛船類和通行證內的圖像它在創建之後被添加到Bullet的資源。問題仍然保持不變。每次彈出子彈時,遊戲變得越來越慢,並且在被擦除之前它保持緩慢。

+0

它在子彈的持續時間內減速還是僅在被觸發的時刻減速? – 2013-04-24 13:08:26

+0

當屏幕上出現子彈時它會變慢。即使在改變從被加載的子彈的loadfrom文件並僅從宇宙飛船傳入後,我仍然得到相同的減速。當所有子彈從場景中移除時,程序的速度恢復正常。 – user2315574 2013-04-24 13:29:31

回答

3

您在每次創建新的對象時,從磁盤上加載Bullet PNG圖像(通常,如果你喜歡拍攝)。從磁盤加載可能會非常緩慢。嘗試多次重複使用相同的圖像!

你也許可以將LoadFromFile函數從LoadResources中取出,並將其放在遊戲持續時間的某個地方。那麼每當需要創建新的子彈時,只需要LoadResources就可以引用該地點。對於可以在遊戲中重用的任何其他圖像或資源也是如此。

2. 我也看到你在你的代碼中有std::cout。嘗試刪除渲染循環中的所有內容,因爲打印速度慢。

for (int i=0; i<bullets.size(); i++) 
{ 
    Bullet *cur = bullets[i]; 
    bullets[i]->Draw(Window); 
    std::cout<<bullets.size()<<std::endl; // This is going to be slow 
} 

你也可能想看看bullets載體。當向它添加項目符號時,push_back會改變向量的大小,並且每次都需要分配和釋放內存。更好的方法是爲最大數量的子彈開始騰出空間(例如使用resize函數),以便在創建子彈時矢量不會更改大小。

if (Window.GetInput().IsKeyDown(sf::Key::Space) && !isPressed) 
{ 
    isBulletOnScreen = true; 
    isPressed = true; 
    bullets.push_back(new Bullet(...); // avoid this 
} 
+0

謝謝您花時間回答。即使改變了png在宇宙飛船類中只能載入一次,並在創建子彈時傳遞,我仍然會在場景中存在子彈對象的同時減速。 – user2315574 2013-04-24 13:31:20

+0

已被添加到答覆中。嘗試刪除std :: cout! – 2013-04-24 13:34:11

+0

我已經刪除了每個控制檯輸出,但我仍然有同樣的問題。隨着每一顆子彈的射擊,它越來越慢,直到子彈被擦除! – user2315574 2013-04-24 13:49:27

1

每次你打電話了新的子彈

Bullet::Bullet(float x,float y,float v,float r) 
{ 
    LoadResources(x,y,v,r); 
} 

也叫LoadResources(x,y,v,r)這就要求

bulletImg.LoadFromFile("Resources/Images/Bullet.png") 

和呼叫從磁盤,這是一個非常緩慢的操作讀取的文件,按照比任何其他的更慢的順序,所以你的程序在負載期間停止。

+0

謝謝你回答這個問題,但即使我將子彈圖像更改爲在太空船類中加載一次,並在加載資源時將它傳遞給子彈,我仍然遇到同樣的減速,同時場景中有子彈對象。 – user2315574 2013-04-24 13:32:52

+0

@ user2315574你正在調用你沒有發佈的代碼,所以我不知道可能是什麼問題。也許你同時產生太多子彈。 – 2013-04-24 14:09:36

+0

我也同意阿明。只需對代碼的其餘部分進行一些調試,並注意「子彈」在哪裏被不必要地/意外複製 - 可能在某些碰撞檢測功能中? – psibar 2013-04-26 12:56:47