1

我要做的是在背景后面绘制矩形并进行本质上的碰撞检测。然而,我不确定我能如何实现它。我考虑过这样,当精灵接近这些矩形时,它们的速度会越来越慢,直到它们停下来,但那会奏效吗?抱歉,如果我听起来有点耳后,我对 C# 还很陌生,并且正在尝试自学。任何帮助,将不胜感激。

所以我有一个 CharacterSprite 类(walkingsprite),所有关于帧的东西只是我实现的一个行走动画序列。

namespace walkingsprite
{
class AnimatedSprite
{
    //keyboard
    KeyboardState currentKBState;
    KeyboardState previousKBState;

    Texture2D spriteTexture;

    float timer = 0f;
    float interval = 200f;
    int currentFrame = 0;
    int spriteWidth = 32;
    int spriteHeight = 48;
    int spriteSpeed = 2;

    Rectangle sourceRect;

    Texture2D obst;
    Rectangle obst1;

    Obstruction obstruction1;


    Vector2 position;
    Vector2 origin;


    public Vector2 Position
    {
        get { return position; }
        set { position = value; }
    }

    public Vector2 Origin
    {
        get { return origin; }
        set { origin = value; }
    }

    public Texture2D Texture
    {
        get { return spriteTexture; }
        set { spriteTexture = value; }
    }

    public Rectangle SourceRect
    {
        get { return sourceRect; }
        set { sourceRect = value; }
    }

    public int SpriteSpeed
    {
        get { return spriteSpeed; }
        set { spriteSpeed = value; }
    }

    public AnimatedSprite(Texture2D texture, int currentFrame, int spriteWidth, int spriteHeight)
    {
        this.spriteTexture = texture;
        this.currentFrame = currentFrame;
        this.spriteWidth = spriteWidth;
        this.spriteHeight = spriteHeight;
    }

    public void HandleSpriteMovement(GameTime gameTime)
    {
        previousKBState = currentKBState;
        currentKBState = Keyboard.GetState();

        sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);



        ////////////////////////////////////////////////////////////////////
        if (currentKBState.GetPressedKeys().Length == 0)
        {
            if (currentFrame > 0 && currentFrame < 4)
            {
                currentFrame = 0;
            }

            if (currentFrame > 4 && currentFrame < 8)
            {
                currentFrame = 4;
            }

            if (currentFrame > 8 && currentFrame < 12)
            {
                currentFrame = 8;
            }

            if (currentFrame > 12 && currentFrame < 16)
            {
                currentFrame = 12;
            }
        }
        ////////////////////////////////////////////////////////////////////

        //sprintin
        if (currentKBState.IsKeyDown(Keys.Space))
        {
            spriteSpeed = 2;
            interval = 100;
        }
        else 
        {
            spriteSpeed = 1;
            interval = 200;
        }
        ///////////////////////////////////////////////


        if (currentKBState.IsKeyDown(Keys.Down) == true)
        {
            AnimateDown(gameTime);
            if (position.Y < 575)
            {
                position.Y += spriteSpeed;
            }
        }

        ////////////////////////////////////////////////////

        if (currentKBState.IsKeyDown(Keys.Up) == true)
        {
            AnimateUp(gameTime);
            if (position.Y > 25)
            {
                position.Y -= spriteSpeed;
            }
        }
        //////////////////////////////////////////////////////////

        if (currentKBState.IsKeyDown(Keys.Right) == true)
        {
            AnimateRight(gameTime);
            if (position.X < 780)
            {
                position.X += spriteSpeed;
            }
        }
        ////////////////////////////////////////////////////////////////////
        if (currentKBState.IsKeyDown(Keys.Left) == true)
        {
            AnimateLeft(gameTime);
            if (position.X > 0)
            {
                position.X -= spriteSpeed;

            }
        }
        origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);

    }
        ////////////////////////////////////////////////////////////////////



    public void AnimateRight(GameTime gameTime)
    {
        if (currentKBState != previousKBState)
        {
            currentFrame = 9;
        }

        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

        if(timer > interval)
        {
            currentFrame++;

            if(currentFrame > 11)
            {
                currentFrame = 8;
            }
            timer = 0f;
        }

    }
    ////////////////////////////////////////////////////////////////////

    public void AnimateUp(GameTime gameTime)
    {
        if (currentKBState != previousKBState)
        {
            currentFrame = 13;
        }
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

        if (timer > interval)
        {
            currentFrame++;

            if (currentFrame > 15)
            {
                currentFrame = 12;
            }
            timer = 0f;
        }
    }
    //////////////////////////////////////////

    public void AnimateDown(GameTime gameTime)
    {
        if (currentKBState != previousKBState)
        {
            currentFrame = 1;
        }
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

        if (timer > interval)
        {
            currentFrame++;

            if (currentFrame > 3)
            {
                currentFrame = 0;
            }
            timer = 0f;
        }
    }

    ////////////////////////////////////////////////////

       public void AnimateLeft(GameTime gameTime)
    {
        if (currentKBState != previousKBState)
        {
            currentFrame = 5;
        }
        timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

        if (timer > interval)
        {
            currentFrame++;

            if (currentFrame > 7)
            {
                currentFrame = 4;
            }
            timer = 0f;
        }
    }
  }
   }

我有一个障碍类。

 namespace walkingsprite
 {
class Obstruction
{
    Texture2D obst;
    Rectangle obstRec1;

    public Rectangle ObstRec1
    {
        get { return obstRec1; }
        set { obstRec1 = value; }
    }

    public Texture2D Obst
    {
        get { return obst; }
        set { obst = value; }
    }

    public Obstruction(Texture2D texture, Rectangle rec)
    {
        this.obstRec1 = rec;
        this.obst = texture;
    }
}
}
4

1 回答 1

0

XNA 已经有一个Rectangle类,如果一个矩形与另一个矩形碰撞,则返回一个方法。

一个例子:

Rectangle rec1 = new Rectangle(0, 0, 10, 10);
Rectangle rec2 = new Rectangle(5, 5, 10, 10);
rec1.Intersects(rec2); //Return true if a rectangle intersects another one

人们通常做的是 a ListofRectangle并一个一个地测试以知道它们是否发生碰撞,或者他们实施 aQuadTree但一开始有点困难。

的一个List例子Rectangle

List<Rectangle> allObjects = new List<Rectangle>();
Rectangle rec1 = new Rectangle(0, 0, 10, 10);
Rectangle rec2 = new Rectangle(10, 15, 10, 10);
Rectangle mainCharRec = new Rectangle(10, 20, 10, 10);

allObjects.Add(rec1);
allObjects.Add(rec2);

要测试主角矩形是否与其他一些矩形相交,您可以使用这样的 foreach 方法:

foreach (Rectangle rec in allObjects)
     if(mainCharRec.Intersects(rec))
          return true;
return false;

关于变慢,我认为您可以对对象设置一个矩形,对“近距离区域”设置另一个矩形,当角色进入该区域时,您会按照您给该区域的距离减慢他的速度,例如,如果您有一个每边大 10 像素的矩形,当角色与更大的矩形碰撞时,他会失去 spriteSpeed/10 的步长,直到他停下来。当值太低时,它变为0:

if (spriteSpeed < 0.5)
     spriteSpeed = 0;
else
    spriteSpeed -= spriteSpeed/10;
于 2013-04-15T21:10:30.747 回答