как остановить параллакс-прокрутку, когда произошло столкновение в моно-игре?

#monogame

#моногейм

Вопрос:

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

 public class CollisionManager : GameComponent
    {
        private RacingCar car;
        private Obstacle obstacle;
        private Road road;
        public CollisionManager(Game game,RacingCar car,
            Obstacle obstacle, Road road) : base(game)
        {
            this.car = car;
            this.obstacle = obstacle;
        }

        public override void Update(GameTime gameTime)
        {
            //get the boundary of the car
            //get the boundary of the obstacle
            //if the car boundary intersects with the obstacle boundary 
            // stop the program 
            Rectangle obstacleRect1 = obstacle.getBound1();
            Rectangle obstacleRect2 = obstacle.getBound2();
            Rectangle carRect = car.getBound();
            if (obstacleRect1.Intersects(carRect) ||obstacleRect2.Intersects(carRect))
            {
                obstacle.Speed = new Vector2(0, 0);
                car.Speed = new Vector2(0, 0);
                //road.Speed = new Vector2(0, 0);
                //I want do something here, but I can't make getBound funcaiton here,

                
            }
            base.Update(gameTime);
        }
    }
 

функция привязки к автомобилю и препятствию

  public Rectangle getBound()
        {
            return new Rectangle((int)position.X, (int)position.Y, tex.Width, tex.Height);
        }
 
  public Rectangle getBound1()
        {
            return new Rectangle((int)position1.X, (int)position1.Y, tex.Width, tex.Height);
        }
        public Rectangle getBound2()
        {
            return new Rectangle((int)position2.X, (int)position2.Y, tex.Width, tex.Height);
        }
 

Ответ №1:

Я чувствую, что вам еще предстоит сообщить больше подробностей, но в любом случае я постараюсь ответить. Я не вижу реализации эффекта параллакса в вашем коде. Я вижу, что объект CollisionManager проверяет столкновения с автомобилем и объектами-препятствиями, и я не нахожу никаких серьезных проблем с указанным кодом. Тем не менее, я думаю, что попытка остановить эффект прокрутки внутри этого класса — не очень хорошая идея; Не то чтобы это невозможно, но ваш код станет только запутанным и его будет сложнее поддерживать / понимать.

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

Итак, сначала создайте public static bool поле внутри вашего CollisionManger класса, например

 public static bool HasCollided=false;
 

Это поле указывает, произошло столкновение или нет. Теперь CollisionManger объект проверяет наличие столкновения и устанавливает для него значение true в случае возникновения столкновения. Итак, вам нужно изменить существующий Update() метод внутри CollisionManager класса как

 public class CollisionManager : GameComponent
{
    private RacingCar car;
    private Obstacle obstacle;
    private Road road;
    public CollisionManager(Game game,RacingCar car,
        Obstacle obstacle, Road road) : base(game)
    {
        this.car = car;
        this.obstacle = obstacle;
    }

    public override void Update(GameTime gameTime)
    {
        //get the boundary of the car
        //get the boundary of the obstacle
        //if the car boundary intersects with the obstacle boundary 
        // stop the program 
        Rectangle obstacleRect1 = obstacle.getBound1();
        Rectangle obstacleRect2 = obstacle.getBound2();
        Rectangle carRect = car.getBound();
        if (obstacleRect1.Intersects(carRect) ||obstacleRect2.Intersects(carRect))
        {
            obstacle.Speed = new Vector2(0, 0);
            car.Speed = new Vector2(0, 0);
            //road.Speed = new Vector2(0, 0);

            Game1.HasCollided = true; //This is all you need here...

        }
        base.Update(gameTime);
    }
}
 

Теперь, когда у вас есть логика прокрутки, вы прокручиваете только в том случае, если это поле имеет значение true.

Я предполагаю, что ваша прокрутка выполняется в Update() методе вашего Game1 класса по умолчанию. (Возможно, вы сделали это в другом классе или переименовали его, поэтому, пожалуйста, поймите и примените изменения только в этом классе)

Для завершения предположим, что ваша указанная функция обновления выглядела следующим образом:

 public override void Update()
{
     .... //Your code

     .... //Your logic of parallax scrolling

     .... //Your remaining code
}
 

Теперь вы должны изменить его на что-то вроде этого

 public override void Update()
{
     .... //Your code
     
     if(CollisionManager.HasCollided == false)//Only scroll if collision has not happened yet
     {
         .... //Your logic of parallax scrolling
     }

     .... //Your remaining code
}
 

РЕДАКТИРОВАТЬ: кроме того, всякий раз, когда вам нужно перезапустить игру, вам нужно установить CollisionManager.HasCollided значение false .