SFML 2.0 c ++射弹

时间:2013-05-08 13:35:50

标签: c++ sfml

我目前有一个从坦克射击的射弹。目前它工作正常,但是一旦他们击中目标或离开屏幕,我就无法“重复使用”射弹。这是我目前正在使用的代码;

//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),但这只是给出了同样的问题,屏幕上的所有其他精灵都会冻结。

我只是不想要不必要的精灵,坦白说它们根本就不需要!

1 个答案:

答案 0 :(得分:2)

为什么要重复使用粒子?只要他们离开屏幕或点击目标,您就可以从列表中删除它们。如果你想限制粒子的数量,射击计时器就可以做到这一点。你这样做的方式总是有1000个对象,无论你是否使用它们都会被加载。这不是很有效。

由于我对C#和XNA比SFML更精通,我将使用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;

这样,您只使用受游戏逻辑约束的粒子数量。注意,这是一种伪代码。当然,您可以将此代码放入更新/主游戏循环中。根据需要调整它。

修改

删除此 - &gt; (1000,sf :: Sprite(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;
 }
}