2013-05-08 87 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