【问题标题】:Can't get my maze wall collisions to work c#无法让我的迷宫墙碰撞工作c#
【发布时间】:2017-03-30 17:56:27
【问题描述】:

我试图让迷宫游戏的主要机制正常工作,但我无法弄清楚。

如果角色碰到矩形,我希望它跳回来,但它似乎没有这样做,你最终会卡住。

这是我的代码:

Texture2D txr;
    Rectangle rect;
    Vector2 position;
    Vector2 velocity;

    public player(Texture2D texture)
    {
        txr = texture;
        position = new Vector2(100, 100);
        rect = new Rectangle(100, 100, txr.Width, txr.Height);
    }

    public void update(Rectangle wall, GameTime gt)
    {
        MoveIfPossible(gt, wall);

        KeyboardState keys = Keyboard.GetState();

        if (keys.IsKeyDown(Keys.Up))
            velocity = new Vector2(0, -1);
        else if (keys.IsKeyDown(Keys.Down))
            velocity = new Vector2(0, 1);
        else if (keys.IsKeyDown(Keys.Left))
            velocity = new Vector2(-1, 0);
        else if (keys.IsKeyDown(Keys.Right))
            velocity = new Vector2(1, 0);
        else
            velocity = new Vector2(0, 0);

        rect.X = (int)position.X;
        rect.Y = (int)position.Y;

    }

    private void UpdatePositionBasedOnMovement(GameTime gameTime)
    {
        position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 4;
    }

    private void MoveIfPossible(GameTime gameTime, Rectangle wall)
    {
        Vector2 oldPosition = position;

        UpdatePositionBasedOnMovement(gameTime);
        if (rect.Intersects(wall))
        {
            position = oldPosition;
        }
    }

如果有人知道它为什么不起作用,请告诉我!!

很抱歉,这些改动并没有解决玩家卡在墙上的问题。如果有帮助,这是我的其余代码 游戏1

 KeyboardState curr_keys;
    Rectangle wall_rect;
    Texture2D wall;
    player player;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        // wall
        wall_rect = new Rectangle(200, 100, 100, 100);
        player = new player(Content.Load<Texture2D>("maze_rect_border"));
        wall = Content.Load<Texture2D>("maze_rect_border");
        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
    }

    protected override void UnloadContent()
    {
    }

    protected override void Update(GameTime gameTime)
    {
        curr_keys = Keyboard.GetState();
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();
        if (curr_keys.IsKeyDown(Keys.Escape))
            Exit();

        player.update(wall_rect, gameTime);

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.White);

        spriteBatch.Begin();
        spriteBatch.Draw(wall, wall_rect, Color.White);
        player.draw(spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }

玩家

Texture2D txr;
    Rectangle rect;
    Vector2 position;

    public player(Texture2D texture)
    {
        txr = texture;
        position = new Vector2(100, 100);
        rect = new Rectangle(100, 100, txr.Width, txr.Height);
    }

    public void update(Rectangle wall, GameTime gt)
    {
        KeyboardState keys = Keyboard.GetState();

        Vector2 velocity;
        if (keys.IsKeyDown(Keys.Up))
            velocity = new Vector2(0, -1);
        else if (keys.IsKeyDown(Keys.Down))
            velocity = new Vector2(0, 1);
        else if (keys.IsKeyDown(Keys.Left))
            velocity = new Vector2(-1, 0);
        else if (keys.IsKeyDown(Keys.Right))
            velocity = new Vector2(1, 0);
        else
            velocity = new Vector2(0, 0);

        Move(gt, wall, velocity);

        rect.X = (int)position.X;
        rect.Y = (int)position.Y;
    }

    private void Move(GameTime gameTime, Rectangle wall, Vector2 velocity)
    {
        Vector2 oldPosition = position;

        position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 4;
        if (rect.Intersects(wall))
        {
            position = oldPosition;
        }
    }


    public void draw(SpriteBatch sb)
    {
        sb.Draw(txr, position, Color.White);
    }

感谢您迄今为止的帮助,还有其他想法吗?

【问题讨论】:

  • 当您与墙相交时,您将返回与开始时相同的位置。向后移动将速度乘以 -1 并移动。

标签: c# collision maze


【解决方案1】:

我认为问题在于您在初始化之前使用了速度矢量。我不确定会产生什么结果。我认为根本原因是您将速度作为类变量,而实际上它应该是本地变量。

我会将 MoveIfPossible 更改为在速度初始化之后。我还将速度更改为局部变量。以下是使用 cmets 进行更改的摘要,以跟踪我所做的事情。

我也会摆脱 UpdatePositionBasedOnMovement 方法。除了混淆您在这种情况下尝试做的事情之外,我不确定它是否会在这种情况下添加任何内容。

Texture2D txr;
Rectangle rect;
Vector2 position;
//Vector2 velocity;

public player(Texture2D texture)
{
    txr = texture;
    position = new Vector2(100, 100);
    rect = new Rectangle(100, 100, txr.Width, txr.Height);
}

public void update(Rectangle wall, GameTime gt)
{
    //MoveIfPossible(gt, wall);     // the velocity vector was not set when this was being called

    KeyboardState keys = Keyboard.GetState();

    Vector2 velocity;  // Change this to local
    if (keys.IsKeyDown(Keys.Up))
        velocity = new Vector2(0, -1);
    else if (keys.IsKeyDown(Keys.Down))
        velocity = new Vector2(0, 1);
    else if (keys.IsKeyDown(Keys.Left))
        velocity = new Vector2(-1, 0);
    else if (keys.IsKeyDown(Keys.Right))
        velocity = new Vector2(1, 0);
    else
        velocity = new Vector2(0, 0);

    MoveIfPossible(gt, wall, velocity); // Pass vector as a parameter, if it's not needed elsewhere, keep it local

    rect.X = (int)position.X;
    rect.Y = (int)position.Y;

}

// private void UpdatePositionBasedOnMovement(GameTime gameTime)
// {
    // position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 4;
// }

private void MoveIfPossible(GameTime gameTime, Rectangle wall, Vector2 velocity)
{
    Vector2 oldPosition = position;

    //UpdatePositionBasedOnMovement(gameTime);          // Don't think this is adding anything with just one line of code
    position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 4;
    if (rect.Intersects(wall))
    {
        position = oldPosition;
    }
}

清理并移除所有 cmets,我个人会这样写/命名:

Texture2D txr;
Rectangle rect;
Vector2 position;

public player(Texture2D texture)
{
    txr = texture;
    position = new Vector2(100, 100);
    rect = new Rectangle(100, 100, txr.Width, txr.Height);
}

public void update(Rectangle wall, GameTime gt)
{
    KeyboardState keys = Keyboard.GetState();

    Vector2 velocity;
    if (keys.IsKeyDown(Keys.Up))
        velocity = new Vector2(0, -1);
    else if (keys.IsKeyDown(Keys.Down))
        velocity = new Vector2(0, 1);
    else if (keys.IsKeyDown(Keys.Left))
        velocity = new Vector2(-1, 0);
    else if (keys.IsKeyDown(Keys.Right))
        velocity = new Vector2(1, 0);
    else
        velocity = new Vector2(0, 0);

    Move(gt, wall, velocity);

    rect.X = (int)position.X;
    rect.Y = (int)position.Y;
}

private void Move(GameTime gameTime, Rectangle wall, Vector2 velocity)
{
    Vector2 oldPosition = position;

    position += velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds / 4;
    if (rect.Intersects(wall))
    {
        position = oldPosition;
    }
}

我猜这不是所有的代码。我的直觉告诉我最好将 Vector2 位置也移动到本地位置,尽管没有深入了解 rect.Intersects() 方法,我没有足够的信息可以肯定地说。或者更有可能它似乎应该是矩形类本身的属性。

一般来说,我会默认不使用类变量。首先不要将某些东西设为类变量。如果找到原因,您可以随时返回并更改它,但局部变量简化了代码。简单的代码错误少。

【讨论】:

  • 不幸的是,这并没有解决问题,所以我已将其余代码添加到我原来的问题中,请看一下
猜你喜欢
  • 2022-10-14
  • 2021-06-25
  • 1970-01-01
  • 2014-01-27
  • 2013-11-30
  • 2015-11-30
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多