2013-05-08 45 views
1

我目前有一個從坦克射擊的射彈。目前它的工作狀況良好,但是一旦他們擊中了目標或者離開了屏幕,我就無法「重複使用」炮彈。這是我目前使用的代碼;SFML 2.0 C++射彈

//Laser Shape 
sf::Texture LaserTexture; 
LaserTexture.loadFromFile("images/laser.png"); 
std::vector<sf::Sprite>Laser(1000, sf::Sprite(LaserTexture)); 

這是我的if語句時按下鍵盤:

if (Event.key.code == sf::Keyboard::Space) 
        { 
         if (laserCount==1000) 
         { 
          laserCount=0; 
         } 
         /*if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) 
         { 

         }*/ 
         laserSpeed=4; 
         laserCount++; 
         laser.play(); 
         std::cout << "laser count = " << laserCount << std::endl; 
        } 

而且我的實際發射飛彈時鐘計數器:

static float laserTimer =0.0; 
       laserTimer+=Clock.getElapsedTime().asSeconds(); 
       if (laserTimer<Ldelay) 
       { 
        laserTimer = 3; 
       } 
       else { 
        laserTimer = 0; 
       } 

       for (int i = 0; i < laserCount; i++) 
       { 
        Laser[i].move(0, -laserSpeed); 

       } 

這是一個非常糟糕的方式這樣做並且很少優化,我知道這一點。最初我試圖在我的矢量中只有50發射彈,當他們到達屏幕頂部或擊中目標時,他們會回到坦克。這根本行不通...即使我把它們放在相對於坦克的位置上,它們也會出現在屏幕的邊上並繼續射擊。

for (int i=0; i<laserCount; i++) 
    { 
    if (Laser[i].getPosition().y==0) 
     { 
     Laser[i].setPosition(xTank, yTank); 
     laserSpeed=0; 
     } 
} 

這將把激光放在屏幕的一側(即使坦克在屏幕中間)。我嘗試了一個實際的位置(300,200),但這只是給出了同樣的問題,屏幕上的所有其他精靈都會凍結。

坦率地說,他們只是不需要時,我只是不想有不必要的精靈數量!

回答

2

爲什麼你想重用粒子?您可以簡單地將它們從列表中刪除,一旦它們離開屏幕或擊中目標。如果你想限制粒子的數量,拍攝計時器就可以做到這一點。你這樣做的方式總是有1000個對象,無論你是否使用它們,它們都會被加載。這不是非常有效。因爲我比SFML更熟悉C#和XNA,所以我將使用C#代碼,但是您應該能夠應用相同的概念。

// global variables 

List<Particle> particles = new List<Particle>(); // empty list 

KeyboardState oldKeyState; 

float shootTimer = 0.0f; 
bool justShot = false; 

// ... in update function 

float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; // delta time 
KeyboardState curKeyState = Keyboard.GetState(); 

// Don't let the user hold down the space key. Has to tap it. 
if (curKeyState.isKeyDown(Keys.Space) && oldKeyState.isKeyUp(Keys.Space)) 
{ 
if (!justShot) 
{ 
    particles.Add(new Particle(tank.Position)); 
    justShot = true; 
} 
} 

if (justShot) 
{ 
if (shotTimer < shotDelay) 
{ 
    shotTimer += elapsed; // in seconds 
} else { justShot = false; shotTimer = 0; } 
} 

for (int i = 0; i < particles.Count; i++) 
{ 
particles[i].update(); 
// if (collision or past end of screen) 
particles.remove(particles[i]); // one way 
particles[i].active = false; // another way 
} 

oldKeyState = curKeyState; 

這樣,您只能使用盡可能多的粒子,因爲它受到遊戲邏輯的限制。請注意,這是一種僞代碼。當然,你會把這個代碼放在你的更新/主遊戲循環中。根據需要調整它。

編輯

刪除此 - >(1000,SF ::雪碧(LaserTexture))

你有一個空載體的方式。無論何時需要添加粒子,請使用push_back。

在C#的顆粒類的一個例子:

class Particle 
{ 
public Particle(Texture2D texture, Vector2 position) { 
    Texture = texture; 
    Position = position; 
} 
public Texture2D Texture; 
public Vector2 Position; 

public void Update(GameTime gameTime) { 
    // get delta time here 
    Position += new Vector2(speedX, speedY) * elapsed; 
} 
} 
+0

嗯還好。我似乎看到你在這裏得到什麼,謝謝。一個簡單的問題,這個代碼'List particles = new List (); //空列表「這基本上是我使用的矢量?如果是這樣,那麼不會有一個固定的數額來阻止緩衝區溢出/通常是因爲straint崩潰嗎? – 2013-05-08 13:50:40

+0

「粒子」被認爲是一個包含粒子邏輯的類。例如,它有自己的更新函數,它自己的'Texture'變量,等等。所以在你的情況下,SFML已經有了一個你使用的Sprite類。我將編輯答案使其更加清晰。 – 2013-05-08 13:53:39

+0

我現在完全理解,謝謝。 – 2013-05-08 13:55:34