SFML 2.0 c++ projectiles
SFML 2.0 c++ projectiles
我现在有一个从坦克发射的炮弹。目前它运行得很好,但一旦炮弹击中目标或离开屏幕,我就无法"重复使用"它们。这是我现在使用的代码;
//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),但这只会产生同样的问题,屏幕上的所有其他精灵都会冻结。
我只是不想有不必要的精灵,当坦率地说,他们只是不需要!
为什么要重复使用粒子?一旦他们离开屏幕或击中目标,你可以简单地将他们从列表中删除。如果你想限制粒子的数量,拍摄计时器就可以做到这一点。你这样做的方式是,总是有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;
通过这种方式,你只使用受游戏逻辑限制的粒子数量。注意,这是一种伪代码。当然,你可以将这些代码放入更新/主游戏循环中。
编辑
Remove this -> (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;
}
}