2013-04-24 4 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 's Resources로 가져 가십시오. 그래도 문제는 여전히 동일합니다. 총알이 발사 될 때마다 게임 속도가 점점 느려지고 지울 때까지 느리게 유지됩니다.

+0

총알이 지속되는 동안 또는 발사되는 순간에만 속도가 느려 집니까? –

+0

화면에 글 머리 기호가있는 동안 속도가 느려집니다. loadfromfile을 변경 한 후에도 우주선에서로드되고 전달 된 후에는 여전히 같은 속도가 느려집니다. 모든 탄환이 장면에서 제거되면 프로그램의 속도가 정상으로 돌아갑니다. – user2315574

답변

3

1. 당신은 (당신이 경우 촬영처럼 자주) 디스크에서 Bullet PNG 이미지를 새로운 객체를 생성 할 때마다로드. 디스크 로딩은 아마도 매우 느릴 것입니다. 대신에 같은 이미지를 여러 번 재사용하십시오!

아마도 LoadFromFile 기능을 LoadResources 개에서 꺼내서 게임 기간 동안 지속될 수 있습니다. 그런 다음 새 탄환을 만들어야 할 때마다 그 자리를 참조하십시오. LoadResources 게임에서 재사용 할 수있는 다른 이미지 나 리소스도 마찬가지입니다.

또한 코드에 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 
} 

3. 는 또한 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

+0

답변에 추가되었습니다. std :: cout을 제거해보십시오! –

+0

나는 모든 콘솔 출력을 제거했지만 여전히 같은 문제가 있습니다. 내가 쏜 총알이 총알이 지워질 때까지 점점 더 천천히 계속됩니다! – user2315574

1

매번 새 총알

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

또한

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

를 호출 LoadResources(x,y,v,r) 전화를 호출하고 호출은 매우 느린 작업입니다 디스크에서 파일을 읽을 수 다른 어떤 것보다 느린 순서로 프로그램이로드 지속 시간 동안 멈 춥니 다.

+0

질문에 대답 해 주셔서 감사합니다.하지만 우주선 클래스에 한 번로드 할 총알 이미지를 변경하고 리소스를로드 할 때 총알을 전달한 후에도 장면에 총알 개체가있는 동안 나는 여전히 같은 속도 저하를 보았습니다. – user2315574

+0

@ user2315574 당신이 게시하지 않은 코드를 호출 했으므로 어떤 문제인지 알 수 없습니다. 같은 시간에 너무 많은 총알을 낳을 수도 있습니다. –

+0

나는 또한 Armin에 동의합니다. 코드의 나머지 부분을 디버깅하고 "불릿"이 불필요하게/우발적으로 복사 된 부분 (일부 충돌 감지 기능)을주의 깊게 살펴보십시오. – psibar