gpt4 book ai didi

c++ - SFML 2.0 c++ 射弹

转载 作者:行者123 更新时间:2023-11-30 04:18:25 32 4
gpt4 key购买 nike

我目前有一个从坦克发射的射弹。目前它工作得很好,但我无法在射弹击中目标或离开屏幕后“重新使用”射弹。这是我目前正在使用的代码;

//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);

}

这是一种非常糟糕的做法,而且优化不佳,我知道这一点。最初我试图在我的 vector 中只包含 50 个射弹,当它们到达屏幕顶部或击中目标时,它们会返回坦克。这根本不起作用......即使我将它们设置为相对于坦克,它们也只会出现在屏幕的一侧并继续射击。

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

这会将激光放在屏幕的一侧(即使坦克在屏幕中间)。我在实际位置 (300,200) 上进行了尝试,但这只是给出了同样的问题,屏幕上的所有其他 Sprite 都会卡住。

坦率地说,我只是不想拥有不必要的 Sprite 数量!

最佳答案

为什么要复用粒子?一旦它们离开屏幕或击中目标,您就可以简单地将它们从列表中删除。如果你想限制粒子的数量,射击计时器就可以做到这一点。你这样做的方式,总是有 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;

这样一来,您只会使用受游戏逻辑限制的尽可能多的粒子。请注意,这是一种伪代码。当然你会把这段代码放在你的更新/主游戏循环中。根据需要进行调整。

编辑

删除这个 --> (1000, sf::Sprite(LaserTexture))

这样你就有了一个空 vector 。每当您需要添加粒子时,请使用 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;
}
}

关于c++ - SFML 2.0 c++ 射弹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16442182/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com