XNA C#:Player类下的列表中的射弹对象,Enemy类无法识别

时间:2018-12-02 19:21:15

标签: c# xna 2d

好,所以我有一个CollisionManager来更新我的碰撞。我有一个弹丸类,一个玩家类和一个敌人类。在Player类中,我创建了一个弹丸列表(Projectile objs),Player类对其进行更新以增加或减少其数量。到目前为止,一切都很好。

现在是问题,当检查冲突时,播放器obj被敌人obj识别。但是,敌人不会识别投射物obj,除非我遍历整个投射物列表并手动检查其对撞机是否相交。除非特别检查,否则实际上看起来是射弹对撞机并且不存在。

代码如下:

玩家冲突代码(工作):

public override void OnCollision(Collidable obj)
{
    Enemies enemy = obj as Enemies;
    if (enemy != null)
      {
        health -= enemy.dmg; //if player collides with enemy, take dmg damage  
      }
}

弹丸碰撞代码(WORKING):

public override void OnCollision(Collidable obj)
    {
        Enemies enemy = obj as Enemies;
        if (enemy != null)
        {
            exists = false;
            if (!exists) FlaggedForRemoval = true;
        }                               
    }

敌人的碰撞代码(仅适用于玩家)

 public override void OnCollision(Collidable obj)
    {
        //Check collision with player
        Player pl = obj as Player;
        if (pl != null)
        {
           exists = false;
           ScoreManager.UpdateScore(pointsWorth);
        }

        //Check collision with projectile
        Projectile pr = obj as Projectile;
        if (pr != null)
        {
            health -= dmgReceived;
            if (health <= 0)
            {
                ScoreManager.UpdateScore(pointsWorth);
                exists = false;
                FlaggedForRemoval = true;
            }
        }

    }

仅当在Main.Update()期间,如果我遍历整个弹丸列表并手动检查与敌人的碰撞,敌对对象与弹丸的碰撞(针对敌人的对象-因为proj起作用)才起作用

 foreach (Enemies e in enemyList)
                    {
                        e.Update(gameTime);
                        e.dmgReceived = player.dmg;


                        for (int i = 0; i < player.projList.Count; i++)
                        {
                            if (player.projList[i].collider.Intersects(e.BoundingRectangle))
                            {

                               //Some code
                            }
                        }

那是什么问题?在我看来,由于某种原因,在敌方碰撞代码中,obj类型未被识别为投射物,可能是因为它在列表中吗?

第一次在这里发布,所以我希望我做对了。感谢您的帮助!

更新以包含碰撞代码

    public class Collidable
{
    protected Rectangle boundingRectangle = new Rectangle();
    public bool FlaggedForRemoval { get; protected set; }

    //Constructor
    public Collidable()
    {
        FlaggedForRemoval = false;
    }

    public Rectangle BoundingRectangle
    {
        get { return boundingRectangle; }
    }


    public virtual bool CollisionTest(Collidable obj)
    {
        return false;
    }

    public virtual void OnCollision(Collidable obj)
    {
    }
}

碰撞类:

public class CollisionComparer : IEqualityComparer<Collision>
{
    public bool Equals(Collision a, Collision b)
    {
        if ((a == null) || (b == null))
        {
            return false;
        }

        return a.Equals(b);
    }

    public int GetHashCode(Collision a)
    {
        return a.GetHashCode();
    }
}

public class Collision
{
    public Collidable A;
    public Collidable B;

    public Collision(Collidable a, Collidable b)
    {
        A = a;
        B = b;
    }

    public bool Equals(Collision other)
    {
        if (other == null) return false;
        if ((this.A.Equals(other.A) && this.B.Equals(other.B))) return true;
        return false;
    }

    public void Resolve()
    {
        this.A.OnCollision(this.B);
    }
}

Collision Manager类:

 public class CollisionManager
{

    //List of classes inheriting from Collidables
    private List<Collidable> m_Collidables = new List<Collidable>(); 

    //Hashset to collect all collisions in a single update
    private HashSet<Collision> m_Collisions = new HashSet<Collision>(new CollisionComparer()); 

    public void AddCollidable(Collidable c)
    {
        m_Collidables.Add(c);
    }

    public void RemoveCollidable(Collidable c)
    {
        m_Collidables.Remove(c);
    }

    public void Update()
    {
        UpdateCollisions();
        ResolveCollisions();
    }

    //Check Collisions hashset

    private void UpdateCollisions()
    {
        if (m_Collisions.Count > 0) m_Collisions.Clear();

        //Iterate thgouh collidable objects to check for collisions
        for(int i =0; i<m_Collidables.Count; i++)
        {
            for (int j = 0; j < m_Collidables.Count; j++)
            {
                Collidable collidable1 = m_Collidables[i];
                Collidable collidable2 = m_Collidables[j];

                //Ensure we are not checking object with itself
                if (!collidable1.Equals(collidable2))
                {
                    //if two objects colliding then add them to the set
                    if (collidable1.CollisionTest(collidable2))
                    {
                        m_Collisions.Add(new Collision(collidable1, collidable2));
                    }
                }
            }
        }
    }

    private void ResolveCollisions()
    {
        foreach (Collision c in m_Collisions)
        {
            c.Resolve();
        }
    }

}

基于上面的代码,这三个类(玩家,敌人,投射物)的碰撞检测为:

   //Collision Detection
    public override bool CollisionTest(Collidable obj)
    {
        if (obj != null)
        {
            return collider.Intersects(obj.BoundingRectangle);
        }
        else
            return false;
    }

我使用游戏main.Update()中的crashManager.Update()更新所有碰撞。

抱歉,代码太长!

更新2个已添加到列表中的显示项目

以下两者均在Player类下,而UpdateProjectile属于player.Update();

 public void PlayerShoots()
    {
        //Fire only if projectile delay resets
        if (projDelay >= 0)
            projDelay--;

        // if projectile delay is at 0 then create a new projectile(add to list)
        if(projDelay <=0)
        {

            Projectile newProj = new Projectile(projTexture);
            collisionManager.AddCollidable(newProj);
            newProj.position = new Vector2(position.X + 100 - newProj.texture.Width / 2, position.Y ); //+ newProj.texture.Height/10
            newProj.collider = new Rectangle((int)newProj.position.X, (int)newProj.position.Y, newProj.texture.Width, newProj.texture.Height);
            newProj.exists = true;


            if (projList.Count() < 80)
            {
                projList.Add(newProj);

            }
        }

        //reset projectile delay
        if (projDelay == 0)
            projDelay = 50;
    }

// update projectile functioN
    public void UpdateProjectile()
    {
        // for each projectile in the list update its position and remove it if it reaches right screen boundary
        foreach(Projectile p in projList)
        {
            //Update collider for every projectile in our list
            p.collider = new Rectangle((int)p.position.X, (int)p.position.Y, p.texture.Width, p.texture.Height);
           //Projectile motion
            p.position.X = p.position.X + p.speed+1;
            if (p.position.X >= 1118)
                p.exists = false;
        }

        for(int i = 0; i<projList.Count; i++)
        {
            if(!projList[i].exists)
            {
                projList.RemoveAt(i);
                i--;
            }
        }

0 个答案:

没有答案