使用定时器随机刷出升级道具

本文关键字:定时器 随机 | 更新日期: 2023-09-27 18:12:18

我正在制作一款2D游戏,在尝试"随机"刷出升级道具时遇到了严重的障碍。基本上,我想做的就是在屏幕上刷出升级道具,然后它们移动到屏幕上(与我滚动背景的速度相同)。一旦三个升级道具中的一个被刷出,另一个将在10到30秒后才会被刷出。我也明白,护盾能量是我目前唯一想要随机生成的东西。我已经研究了几个小时,并编写了代码,我将在下面发布。我已经尝试过自己做这一切,所以我为代码的质量道歉,我仍然是一个初学者和学习。任何帮助或链接到网站将非常感激,因为我不知道从这里进行。提前谢谢。

game1.cs

public List<PowerUps> powerUpList = new List<PowerUps>();
public double counterPower = 0;
public bool powerUpCollision = false;
public bool invincibility = false;
Sprite shieldPower;
Sprite infiniteAmmoPower;
Sprite livesPower;
bool isVisible = true;
public bool infiniteAmmoBool = false;
public bool infiniteAmmoCol = false;
protected override void Initialize()
{
    shieldPower = new Sprite();
    infiniteAmmoPower = new Sprite();
    livesPower = new Sprite();
}
protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    shieldPower.LoadContent(this.Content, "powerUpShield");
    infiniteAmmoPower.LoadContent(this.Content, "infinitePowerUp");
    livesPower.LoadContent(this.Content, "livePowerUp");
}
protected override void Update(GameTime theGameTime)
{
}
public void powerUps(GameTime theGameTime)
{
    //if (mPlayer.boundingBox.Intersects(shieldPower.boundingBoxShieldPower))
    {
        Console.WriteLine(shieldPower.Position.X);
        if (shieldPower.isVisible == true)
        {
            Console.WriteLine("collision working");
            powerUpCollision = true;
            invincibility = true;
            shieldPower.isVisible = false;
            if (powerUpCollision == true && invincibility == true)
            {
                lives = lives - 0;
            }
            counterPower = 0;
        }
    }
    counterPower += theGameTime.ElapsedGameTime.TotalSeconds;
    {
        //  Console.WriteLine(counterPower);
        if (counterPower > 7)
        {
            powerUpCollision = false;
            invincibility = false;
        }
    }

    if (mPlayer.boundingBox.Intersects(livesPower.boundingBoxLives))
    {
        if (livesPower.isVisible == true)
        {
            lives = lives + 1;
            livesPower.isVisible = false;
        }
    }
}

public void loadPowerUps()
{
    int randPowerX = random.Next(850, 1400); // spawns randomly between these coordinates
    int randPowerY = random.Next(-300, 300);
    Console.WriteLine(shieldPower.Position.X);
    if (powerUpList.Count < 1) // limits the powerUp count to 1 at a time
    {
        powerUpList.Add(new PowerUps(Content.Load<Texture2D>("powerUpShield"), new Vector2(randPowerX, randPowerY)));
    }
    for (int i = 0; i < powerUpList.Count; i++)
    {
        if (powerUpList[i].isVisible == false)
        {
            powerUpList.RemoveAt(i);
            i--;
        }
    }
}
protected override void Draw(GameTime theGameTime)
{
    foreach (PowerUps powerup in powerUpList)
    {
        powerup.Draw(spriteBatch);
    }
    mPlayer.Draw(this.spriteBatch);
    enemyShip.Draw(this.spriteBatch);
    if (shieldPower.isVisible == true)
    {
        shieldPower.Draw(this.spriteBatch);
    }
    if (livesPower.isVisible == true)
    {
        livesPower.Draw(this.spriteBatch);
    }
    if (infiniteAmmoPower.isVisible == true)
    {
        infiniteAmmoPower.Draw(this.spriteBatch);
    }
}

PowerUps.cs

public class PowerUps : Game1
{
    Random randomPower = new Random();
    int minPowerSpawnTimer = 10000; // 10 seconds 
    int maxPowerSpawnTimer = 30000; // 30 seconds
    double nextSpawnTime;
    float powerUpSpeed = -0.5f;
    Vector2 position;
    Texture2D texture;

    public PowerUps(Texture2D newText, Vector2 newPos)
    {
        position = newPos;
        texture = newText;
    }
    public void Update(GameTime theGameTime)
    {
        position.X += powerUpSpeed;
        nextSpawnTime -= theGameTime.ElapsedGameTime.Milliseconds;
        if (nextSpawnTime < 0)
        {
            loadPowerUps();
            resetSpawnTime();
        }
    }
    public void resetSpawnTime()
    {
        nextSpawnTime = randomPower.Next(minPowerSpawnTimer, maxPowerSpawnTimer);
    }
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, Color.White);
    }
}

使用定时器随机刷出升级道具

您的问题是您创建的类结构。不应该在PowerUps类中继承Game1。它正在创建Game1对象的多个实例,每个实例都有自己的powerup列表。

在我看来,PowerUps实例中的任何Update()方法都不会被调用。

我认为你可能想从你的PowerUps类访问Game1类的功能。继承(PowerUps : Game1)在这里不是这样做的。

相反,创建一个不继承任何内容的PowerUps类。然后从你的Game1 Update方法中,调用你的PowerUps实例的Update方法并传递它所需的变量。与图纸相同

为了使您的Update方法被调用,您的PowerUps类必须继承自GameComponent,而不是Game1

因为你也有一个Draw方法,要让你的Draw方法也被自动调用,你必须继承DrawableGameComponent

这些基类将Game1作为参数,因此您必须修改构造函数:

public class PowerUps : DrawableGameComponent
{
    //Variables
    public PowerUps(Texture2D newText, Vector2 newPos, Game1 game) : base(game)
    {
        position = newPos;
        texture = newText;
    }

现在您有了GameComponent,您必须在创建时在Game1类中注册它。因此,当在powerUpList中创建增强道具时,从

更改代码
powerUpList.Add(new PowerUps(Content.Load<Texture2D>("powerUpShield"), new Vector2(randPowerX, randPowerY)));

:

PowerUps powerUp = new PowerUps(Content.Load<Texture2D>("powerUpShield"), new Vector2(randPowerX, randPowerY))
powerUpList.Add(powerUp);
Components.Add(powerUp);

当你的组件在Components列表中注册时,游戏可以开始调用组件的DrawUpdate方法。完成后,将其从列表中删除。