C# XNA与多个类相交/碰撞?

C# XNA与多个类相交/碰撞?,c#,xna,collision,intersect,C#,Xna,Collision,Intersect,在过去的12个小时里,我一直在尝试我能想到的“所有”不同的方法,以便在XNA(4.0)中使两个矩形相交/正确测试碰撞 我有三个类(仅示例名称): 游戏1.cs Player.cs 男演员 在Game1中,我加载的内容如下: playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight); class Man { Texture2D _texture; public Vect

在过去的12个小时里,我一直在尝试我能想到的“所有”不同的方法,以便在XNA(4.0)中使两个矩形相交/正确测试碰撞

我有三个类(仅示例名称):

  • 游戏1.cs
  • Player.cs
  • 男演员
在Game1中,我加载的内容如下:

playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
class Man
{
    Texture2D _texture;

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Man(Texture2D texture)
    {
        this._texture = texture;
        this.Width = texture.Width;
        this.Height = texture.Height;
    }

    ... //other man related logic!
}

class Player
{
    Texture2D _texture;
    int _frameCount;
    int _currentFrame;
    //other frame related logic...

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Rectangle SourceRectangle
    {
        get
        {
            return new Rectangle(Width * _currentFrame, 0, Width, Height);
        }
    }

    public Player(Texture2D texture, int frameWidth, int frameCount)
    {
        this._texture = texture;
        this.Width = frameWidth;
        this.Height = texture.Height;
        this._frameCount = frameCount;
        this._currentFrame = 0;
        //etc...
    }

    ... //other player related logic! such as updating _currentFrame

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, SourceRectangle, Color.White);
    }
}
//在游戏1开始时:

    Player player;
    Man man;
    man = new Man(Content.Load<Texture2D>("ManImage"), new Rectangle(440, 310, 150, 98));
    player = new Player(Content.Load<Texture2D>("playerSheet"), new Vector2(40, 420), 50, 44);
//加载内容:

    Player player;
    Man man;
    man = new Man(Content.Load<Texture2D>("ManImage"), new Rectangle(440, 310, 150, 98));
    player = new Player(Content.Load<Texture2D>("playerSheet"), new Vector2(40, 420), 50, 44);

我是不是已经完全“代码盲”了?如果有人能帮我解决这个问题,经过12个小时的碰撞测试后,我的动力下降了。

对于这两个类,你都可以添加一个属性

public Rectangle PositionRectangle { get; private set; }
然后,在相关的构造函数中,您需要初始化这个属性

public Man(..., Rectangle rectangle)
{
    PositionRectangle = rectangle;
}

public Player(..., Vector2 position, int width, int height)
{
    PositionRectangle = new rectangle((int)position.X, (int)position.Y, width, height);
}
您不必担心显示的是哪一帧,因为这与源矩形相关,而与目标矩形相关(需要测试冲突)

然后你可以很容易地测试这些碰撞

if(man.PositionRectangle.Intersects(player.PositionRectangle))
{
    //collision logic
}
当然,在更改位置(或宽度和高度,如果可以更改)时,需要注意随时更新这些矩形


轻微编辑(或更好的版本) 如果您想轻松定位人和玩家,而不必担心他们的矩形如何更新,您可以这样设置:

playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
class Man
{
    Texture2D _texture;

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Man(Texture2D texture)
    {
        this._texture = texture;
        this.Width = texture.Width;
        this.Height = texture.Height;
    }

    ... //other man related logic!
}

class Player
{
    Texture2D _texture;
    int _frameCount;
    int _currentFrame;
    //other frame related logic...

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Rectangle SourceRectangle
    {
        get
        {
            return new Rectangle(Width * _currentFrame, 0, Width, Height);
        }
    }

    public Player(Texture2D texture, int frameWidth, int frameCount)
    {
        this._texture = texture;
        this.Width = frameWidth;
        this.Height = texture.Height;
        this._frameCount = frameCount;
        this._currentFrame = 0;
        //etc...
    }

    ... //other player related logic! such as updating _currentFrame

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, SourceRectangle, Color.White);
    }
}
在这里,我给出了一个示例,说明如何使用属性访问器动态生成相关的矩形

您可以使用
PositionRectangle
确定玩家(或玩家)在屏幕上的位置,并使用
SourceRectangle
确定要绘制的纹理部分

此外,如果你的球员和球员的宽度和高度不会改变,那么你应该将他们的
set
访问者设置为
private

当您需要更改位置时,只需设置其“位置”属性

man.Position = new Vector2(100, 100); //i.e.
您的碰撞和绘制逻辑将自动使用新的矩形,无需任何进一步的干预

希望你喜欢

编辑2 与源矩形是公共的相关,您只需要从外部绘制这些矩形(即
Game1
调用
spriteBatch.Draw(player.Texture、player.PositionRectangle、player.SourceRectangle、Color.White);

如果您像示例中那样(从内部)绘制它,您可以放弃整个
public Recangle SourceRectangle{…}
东西,直接在绘图中使用该矩形:

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, new Rectangle(Width * _currentFrame, 0, Width, Height), Color.White);
    }

您可以为这两个类添加一个属性

public Rectangle PositionRectangle { get; private set; }
然后,在相关的构造函数中,您需要初始化这个属性

public Man(..., Rectangle rectangle)
{
    PositionRectangle = rectangle;
}

public Player(..., Vector2 position, int width, int height)
{
    PositionRectangle = new rectangle((int)position.X, (int)position.Y, width, height);
}
您不必担心显示的是哪一帧,因为这与源矩形相关,而与目标矩形相关(需要测试冲突)

然后你可以很容易地测试这些碰撞

if(man.PositionRectangle.Intersects(player.PositionRectangle))
{
    //collision logic
}
当然,在更改位置(或宽度和高度,如果可以更改)时,需要注意随时更新这些矩形


轻微编辑(或更好的版本) 如果您想轻松定位人和玩家,而不必担心他们的矩形如何更新,您可以这样设置:

playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
class Man
{
    Texture2D _texture;

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Man(Texture2D texture)
    {
        this._texture = texture;
        this.Width = texture.Width;
        this.Height = texture.Height;
    }

    ... //other man related logic!
}

class Player
{
    Texture2D _texture;
    int _frameCount;
    int _currentFrame;
    //other frame related logic...

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Rectangle SourceRectangle
    {
        get
        {
            return new Rectangle(Width * _currentFrame, 0, Width, Height);
        }
    }

    public Player(Texture2D texture, int frameWidth, int frameCount)
    {
        this._texture = texture;
        this.Width = frameWidth;
        this.Height = texture.Height;
        this._frameCount = frameCount;
        this._currentFrame = 0;
        //etc...
    }

    ... //other player related logic! such as updating _currentFrame

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, SourceRectangle, Color.White);
    }
}
在这里,我给出了一个示例,说明如何使用属性访问器动态生成相关的矩形

您可以使用
PositionRectangle
确定玩家(或玩家)在屏幕上的位置,并使用
SourceRectangle
确定要绘制的纹理部分

此外,如果你的球员和球员的宽度和高度不会改变,那么你应该将他们的
set
访问者设置为
private

当您需要更改位置时,只需设置其“位置”属性

man.Position = new Vector2(100, 100); //i.e.
您的碰撞和绘制逻辑将自动使用新的矩形,无需任何进一步的干预

希望你喜欢

编辑2 与源矩形是公共的相关,您只需要从外部绘制这些矩形(即
Game1
调用
spriteBatch.Draw(player.Texture、player.PositionRectangle、player.SourceRectangle、Color.White);

如果您像示例中那样(从内部)绘制它,您可以放弃整个
public Recangle SourceRectangle{…}
东西,直接在绘图中使用该矩形:

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, new Rectangle(Width * _currentFrame, 0, Width, Height), Color.White);
    }

我可能不理解这个问题,但如果你能得到两个矩形对象,一个给玩家,一个给男人,你就不能在Game1中编写一个函数来检查两个矩形是否相交吗?那你就不用担心“参加”这些课程了,对吧?只需为玩家和玩家创建一个GetRect()函数,然后将这两个矩形发送到Game1中的Intersects()函数。我可能不理解这个问题,但如果你能得到两个矩形对象,一个为玩家,一个为玩家,你能不能在Game1中编写一个函数来检查两个矩形是否相交?那你就不用担心“参加”这些课程了,对吧?只需为玩家和玩家创建一个GetRect()函数,然后将这两个Rect发送到Game1中的Intersects()函数。这看起来确实是一个很棒的主意!我现在已经实现了您更新的想法,但到目前为止,播放器角色完全静止(但是,当我使用关键点时,精灵动画工作),但它不会在屏幕上移动。我想这与frameCount和currentFrame有关。我还实现了“Edit2”功能,但我必须处理角色的移动。嗯,这应该与currentFrame无关(这仅用于源代码)-您确定要更新播放器。位置?试着给它赋值,看看玩家是否移动到了那里哈哈,我犯了一个多么愚蠢的错误。我意外