当前位置: 首页 > 知识库问答 >
问题:

带有对象列表的C# XNA冲突检测

长孙鸿
2023-03-14

我目前正在学习C#和XNA,我在让碰撞检测正常工作方面遇到了一些问题。当敌人物体相交时,我希望我的玩家消失。

下面显示了我在Obj类中的代码

class Obj
{
    public Vector2 position;
    public float rotation = 0.0f;
    public Texture2D spriteIndex;
    public string spriteName;
    public float speed = 0.0f;
    public float scale = 1.0f;
    public bool alive = true;
    public Rectangle area;
    public bool solid = false;


    public Obj(Vector2 pos)
    {
        position = pos;
    }

    private Obj()
    {

    }

    public virtual void Update()
    {
        if (!alive) return;

        UpdateArea();
        pushTo(speed, rotation);
    }

    public virtual void LoadContent(ContentManager content)
    {
        spriteIndex = content.Load<Texture2D>("sprites\\" + spriteName);
        area = new Rectangle(0, 0, spriteIndex.Width, spriteIndex.Height);
    }

    public virtual void Draw(SpriteBatch spriteBatch)
    {
        if (!alive) return;

        Rectangle Size;
        Vector2 center = new Vector2(spriteIndex.Width / 2, spriteIndex.Height / 2);

        spriteBatch.Draw(spriteIndex, position, null, Color.White, MathHelper.ToRadians(rotation), center, scale, SpriteEffects.None, 0);

    }

    public bool Collision(Vector2 pos, Obj obj)
    {
        Rectangle newArea = new Rectangle(area.X, area.Y, area.Width, area.Height);
        newArea.X += (int)pos.X;
        newArea.Y += (int)pos.Y;

        foreach (Obj o in Items.objList)
        {
            if (o.GetType() == obj.GetType() && o.solid)
                if (o.area.Intersects(newArea))
                    return true;
        }
        return false;
    }

    public Obj Collision(Obj obj)
    {
        foreach (Obj o in Items.objList)
        {
            if (o.GetType() == obj.GetType())
                if (o.area.Intersects(area))
                    return o;
        }
        return new Obj();
    }

    public void UpdateArea()
    {
        area.X = (int)position.X - (spriteIndex.Width / 2);
        area.Y = (int)position.Y - (spriteIndex.Height / 2);
    }

    public T CheckCollisionAgainst<T>() where T : Obj
    {
        // If collision detected, returns the colliding object; otherwise null.
        return Items.objList
            .OfType<T>()
            .FirstOrDefault(o => o.solid && o.area.Intersects(area));
    }

    public virtual void pushTo(float pix, float dir)
    {
        float newX = (float)Math.Cos(MathHelper.ToRadians(dir));
        float newY = (float)Math.Sin(MathHelper.ToRadians(dir));
        position.X += pix * (float)newX;
        position.Y += pix * (float)newY;
    }
}

我正在循环查看objList中的每个项目,看它们是否相交。在这种情况下,如果敌人与我的玩家相交,我希望玩家消失,但这并没有发生。

此代码来自我的Player类

class Player : Obj
{
    KeyboardState keyboard;
    KeyboardState prevKeyboard;

    float spd;

    public static Player player;

    public Player(Vector2 pos) 
        : base(pos)
    {
        position = pos;
        spd = 4;
        spriteName = "WhiteBall";
        solid = false;
        player = this;
    }

    public override void Update()
    {
        player = this;
        //If the player is NOT alive, end.
        if (!alive) return;

        keyboard = Keyboard.GetState();

        //Keyboard controls for game
        if(keyboard.IsKeyDown(Keys.W) && !Collision(new Vector2(0, -spd), new Enemy(new Vector2(0, 0))))
        {
            position.Y -= spd;
        }
        if (keyboard.IsKeyDown(Keys.A) && !Collision(new Vector2(-spd, 0), new Enemy(new Vector2(0, 0))))
        {
            position.X -= spd;
        }

        if (keyboard.IsKeyDown(Keys.S) && !Collision(new Vector2(0, spd), new Enemy(new Vector2(0, 0))))
        {
            position.Y += spd;
        }

        if (keyboard.IsKeyDown(Keys.D) && !Collision(new Vector2(spd, 0), new Enemy(new Vector2(0, 0))))
        {
            position.X += spd;
        }
        prevKeyboard = keyboard;

        //Collision with enemy
        Enemy enemy = CheckCollisionAgainst<Enemy>();
        if (enemy != null)
        {
            alive = false;
        }

        base.Update();
    }


    public override void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.DrawString(Game1.font, "Pick Up The Crew", new      Vector2(350, 0), Color.White);

        base.Draw(spriteBatch);
    }
}

如果它与敌人相交,它应该消失,但这似乎没有发生。

共有1个答案

缪远
2023-03-14

根据您提供的意见,我在这里尝试一下,并提供一个可能的解决方案(请确保在调用之前调用UpdateArea):

public T CheckCollisionAgainst<T>() where T : Obj
{      
    // If collision detected, returns the colliding object; otherwise null.
    return Items.objList
        .OfType<T>()
        .FirstOrDefault(o => o.area.Intersects(area));
}
Enemy enemy = CheckCollisionAgainst<Enemy>();
if (enemy != null)
{
    alive = false;
}
 类似资料:
  • 我正在尝试为我的大学工作制作一个基于2D平台的游戏(在SFML)。我不是要求任何人为我编写一些代码,但如果有人能提供一些指示,我将非常感激:) 目前我有大约13门课,包括: BaseEntity(大多数游戏对象都是由此派生的) 玩家(继承自BE) 魔法宝石(玩家需要这些来通过关卡晋级) 平台 SolidBlock(从平台继承) 可以说,我已经构建了大部分的游戏“积木”--每个类都有自己的更新函数,

  • 问题内容: 我想知道判断Shape对象是否与另一个形状相交的最佳方法。目前,我在游戏中已对碰撞检测进行了分类,只要它涉及与矩形相交的Shape,反之亦然。我遇到的问题是Shape类中的intersects()方法只能将Rectangle或Point作为参数,而不能将另一个Shape用作参数。有没有一种有效的方法来测试两个Shape对象是否以任何方式重叠?我尝试的一种方法是使用for循环生成一个点区

  • 问题内容: 在检测播放器与许多相同对象(在本例中为墙砖)之间的碰撞时,我遇到了一个问题。问题是我的程序仅在与 最后添加的 墙砖接触时才检测到碰撞。这是用java写的… 我正在使用矩形(它们的相交方法)来检测碰撞。 代码示例: 更新图块: 这是我的课程,使墙从砖块中脱颖而出: } 这是我的班级,使房间或房屋带有墙壁: } 将图块和墙壁添加到其arrayList中的代码: 在wallTile.java

  • 我正在为一项大学作业创建一个项目,我遇到了一点障碍。这个问题很小,很可能被认为是没有被注意到的,但它仍然困扰着我,作为一个程序性的人,在完成工作方面,我不能继续做任何事情,直到它被解决。 我有桨和球代码工作良好,以及一个简单的角速度的基础上,球击中桨,但我的问题是当球击中砖块。代码大多有效,似乎完美无瑕,但当球做以下两件事之一时,情况会发生变化: 击中砖块的一个角可能会错误地扭转球的速度轴 同时击

  • 我是碰撞检测新手,在游戏原型中遇到了一些问题。我已经做了好几天了。经过一些阅读和辅导,我仍然不明白我做错了什么,所以这里的其他人应该能够解释我做错了什么。 游戏运行时,屏幕上有10个绿色矩形(NPC)和1个红色矩形(吸血鬼)。作为一个起点,我希望吸血鬼“喝血”,当它通过愚蠢的运气随机穿过npc时。如果我不注释掉冲突检测方法,代码中就会出现一个nullpointexception。 公共类屏幕扩展J

  • 我一直在尝试用C语言编写一些碰撞检测代码,下面是我目前拥有的函数,它在每帧调用一次,但是由于某些原因,当两个精灵重叠时,碰撞不起作用 任何指向正确方向的指示都将不胜感激