Не могу заставить мои стены лабиринта работать C#

Я пытаюсь получить основную механику для игры лабиринта, но я не могу понять это.

Я хочу, чтобы персонаж отскочил назад, если он попал в прямоугольник, но, похоже, это не так, и вы просто застряли.

вот мой код:

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;
        }
    }

Если кто-то знает, почему это не работает, пожалуйста, дайте мне знать!

Мне жаль говорить, что эти изменения не зафиксировали тот факт, что игрок застрял на стене. Вот остальная часть моего кода, если это помогает Game1

 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 ответ

Я думаю, проблема в том, что вы используете вектор скорости до того, как он был инициализирован. Я не уверен, какой результат это даст. Я думаю, что основной причиной является то, что у вас есть скорость как переменная класса, тогда как она действительно должна быть локальной.

Я бы изменил MoveIfPossible, чтобы быть после инициализации скорости. Я также изменил бы скорость, чтобы быть локальной переменной. Вот краткое изложение изменений с комментариями, чтобы отслеживать, что я сделал.

Я также избавился бы от метода 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;
    }
}

Убирая и удаляя все комментарии, я бы лично написал / назову это так:

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() у меня недостаточно информации, чтобы сказать наверняка. Или, скорее, кажется, что это должно быть свойство самого класса прямоугольника.

В общем, я бы по умолчанию не использовал переменные класса. Начните с того, что вы не сделаете что-то переменным класса. Вы всегда можете вернуться и изменить это, если найдете причину, но локальные переменные упрощают код. Простой код имеет меньше ошибок.

Другие вопросы по тегам