2013-05-27 2 views
2

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

Я сделал исследование и задал вопрос, чтобы получить меня так далеко: Я сделал класс врага, а затем сделал список, который может добавить больше врагов и установить их отдельные нерестилища. Затем я сделал класс EnemyBlock, поэтому я могу установить, где будут находиться различные объекты столкновения (в этом случае они всего лишь кирпичные квадраты).

У меня возникли проблемы
A. При повороте врагов, когда они покидают игровой экран.
И B. написать код столкновения для врагов и блоков врагов, как при попытке написать код столкновения в разделе Game1.cs Update под номером foreach (Enemy enemy in enemies) он не выбирает прямоугольник вражеского блока. Если это имеет смысл. Мне жаль, но я довольно новичок в коде XNA.

Game1.cs код

public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    SpriteBatch spriteBatch; 

    public Rectangle bounds; 

    List<Enemy> Enemies = new List<Enemy>(); 
    List<EnemyBlock> Blocks = new List<EnemyBlock>(); 

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


    protected override void Initialize() 
    { 
     // TODO: Add your initialization logic here 

     base.Initialize(); 
    } 


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

     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(50, 100))); 
     Enemies.Add(new Enemy(Content.Load<Texture2D>("Mario_Sprite"), new Vector2(100, 100), new Vector2(1, 0))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(500, 100))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(50, 200))); 
     Enemies.Add(new Enemy(Content.Load<Texture2D>("Mario_Sprite"), new Vector2(100, 200), new Vector2(1, 0))); 
     Blocks.Add(new EnemyBlock(Content.Load<Texture2D>("02Brick"), new Vector2(400, 200))); 

     foreach (Enemy enemy in Enemies) 
     { 
      enemy.bounds = new Rectangle((int)(enemy.position.X - enemy.texture.Width), (int)(enemy.position.Y - enemy.texture.Height), enemy.texture.Width, enemy.texture.Height); 
     } 
     foreach (EnemyBlock block in Blocks) 
     { 
      block.bounds = new Rectangle((int)(block.position.X - block.texture.Width), (int)(block.position.Y - block.texture.Height), block.texture.Width, block.texture.Height); 
     } 

    } 


    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 


    protected override void Update(GameTime gameTime) 
    { 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     foreach (Enemy enemy in Enemies) 
     { 
      if (!GraphicsDevice.Viewport.Bounds.Contains(enemy.bounds)) 
      { 
       enemy.velocity = -enemy.velocity; 
       enemy.position += enemy.velocity; 

      } 

      else 
      { 

       enemy.position += enemy.velocity; 

      } 
     } 

     base.Update(gameTime); 
    } 


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

     spriteBatch.Begin(); 
     foreach (Enemy enemy in Enemies) 
     { 
      spriteBatch.Draw(enemy.texture, enemy.position, Color.White); 
     } 
     foreach (EnemyBlock block in Blocks) 
     { 
      spriteBatch.Draw(block.texture, block.position, Color.White); 
     } 
     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 
} 
} 

Enemy код класса

class Enemy 
    { 
     public Texture2D texture; 
     public Rectangle bounds; 
     public Vector2 position; 
     public Vector2 velocity; 

     public Enemy(Texture2D Texture, Vector2 Position, Vector2 Velocity) 
     { 
      texture = Texture; 
      position = Position; 
      velocity = Velocity; 
     } 
    } 

EnemyBlock код класса

class EnemyBlock 
{ 
    public Texture2D texture; 
    public Rectangle bounds; 
    public Vector2 position; 

    public EnemyBlock(Texture2D Texture, Vector2 Position) 
    { 
     texture = Texture; 
     position = Position; 
    } 
} 

ответ

2

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

В любом случае, я думаю, у меня может быть ответ на вашу проблему.

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

Это прекрасно, за исключением того, что вы не обновляете положение прямоугольников. Вы обновляете скорость и положение врагов и блокируете, проверяя наличие столкновения с ограничивающими прямоугольниками.

Это означает, что ваши враги смогут перемещаться по экрану и через объекты, потому что ваше положение ничьей перемещено, но прямоугольник не означает, что он не обнаружит столкновения.

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

enemy.bounds = new Rectangle((int)(enemy.position.X - enemy.texture.Width), (int)(enemy.position.Y - enemy.texture.Height), enemy.texture.Width, enemy.texture.Height); 

должен выглядеть

enemy.bounds = new Rectangle(enemy.position.X, enemy.position.Y, enemy.texture.Width, enemy.texture.Height); 

основан на том, как вы рисуете ваши изображения.

Конструктор прямоугольника указывает х верхнего левого угла в, Y положение и ширина/высота прямоугольника. Прямоугольник r = новый прямоугольник (100, 100, 200, 200) создает прямоугольник шириной 100, 100 и 200 и 200 высот.

Это будет совпадать с тем, как вы рисуете врагов и блоки.

И, наконец, код столкновения довольно прост:

foreach(Enemy enemy in Enemies) 
{ 
    foreach(EnemyBlock block in Blocks) 
    { 
    if(enemy.bounds.Contains(block.bounds)) 
    { 
     //what to do on collision 
    } 
    } 
} 

Я надеюсь, что это все правильно и помогает.

+0

Вы, г-н Камминг, являются спасатель жизни. Огромное спасибо. Я экспериментировал всю ночь разными способами, чтобы заставить код работать. Создание новых классов, новых списков, новых проектов! И я действительно хочу, чтобы мой код был аккуратным по этой причине. Поэтому я могу пойти и исправить ситуацию и найти их легко. Новый код работает как шарм. – FLAVAred

+0

Без проблем я рад помочь. :) –

0

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

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

Что касается столкновения с вражескими блоками, вот хороший учебник от MSDN по созданию 2D-прокручивающих игр, таких как mario. CLICK HERE

в учебнике все рассматривается как объект плитки на 2-й карте массива и на обновление, он проверяет на плитке массива, где противник в настоящее время стоя (позиция противника)

Смежные вопросы