【问题标题】:Randomly spawn power ups using a timer xna c#使用计时器 xna c# 随机生成电源
【发布时间】:2015-09-11 18:31:51
【问题描述】:

我正在创建一个 2D 游戏,但在尝试“随机”生成道具时遇到了严重的障碍。基本上我想要做的是在屏幕外产生电源UPS,然后它们移动到屏幕上(以与我的滚动背景相同的速度)一旦产生了三个电源UPS中的一个,直到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);
    }
}

【问题讨论】:

  • GameTime.ElapsedGameTime.Milliseconds 的值为正数,并且您正在将该值添加到 nextSpawnTime。因此,nextSpawnTime 永远不会
  • 我从来没有注意到这一点。它已更改,但问题本身仍然存在。不过我想我更近了一步。谢谢你的评论,格里芬。
  • 盾牌精灵本身没有绘制。我跟踪了精灵的 X 位置,它返回 0。另外两个精灵正在绘制,但它们是静态的,我已经定义了它们的位置。盾牌精灵(我现在正在尝试随机生成的那个)不是。很抱歉没有在一开始就澄清这一点。
  • 就我为尝试解决问题所做的事情而言,我几乎只是研究了列表和计时器,但事实证明这两者都没有什么帮助。我正在努力为这个持续存在的问题想出一个解决方案,所以我求助于 Stackoverflow,看看是否有人能解释我的问题,干杯。

标签: c# list random timer xna


【解决方案1】:

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

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

我认为您可能希望从您的 PowerUps 类访问您的 Game1 类的功能。继承 (PowerUps : Game1) 不是这里的做法。

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

【讨论】:

    【解决方案2】:

    为了调用您的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 方法。完成后,将其从列表中删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 2011-01-24
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多