2012-06-02 7 views
0

Я новичок в XNA и C# (я начал 2 дня назад, поэтому, пожалуйста, простите небрежное программирование), и у меня возникла проблема с простой игрой, которую я делаю. Я не могу найти решение в любом из онлайновых учебников. Я пытаюсь использовать обнаружение столкновения прямоугольника, но я не могу заставить его работать правильно. Персонаж полностью падает на пол, и кажется, что в любом месте не происходит столкновений. Я не могу найти здесь свою логическую ошибку. Ниже я опубликовал немного моего кода, который относится к обнаружению столкновения. При необходимости я могу разместить больше сообщений. Спасибо за помощь заранее!2D обнаружение столкновения не работает XNA C#

Level.cs

//The method below is called in the initial LoadContent method in Game1.cs. 'LoadBlocks()' is supposed to read in a text file and setup the level's "blocks" (the floor or platforms in the game). 

public void LoadBlocks(int level){ 
    if (level == 0) 
     { 
      fileName = "filepath"; 
     } 

     System.IO.StreamReader file = new System.IO.StreamReader(fileName); 
     while ((line = file.ReadLine()) != null) 
     { 
      for (int i = 0; i < 35; i++) 
      { 
       rectBlock = new Rectangle((int)positionBlock.X, (int)positionBlock.Y, width/30, height/30); 

       if (line.Substring(i, 1).Equals(",")) 
       { 
        positionBlock.X += (width/100) * 24; 
       } 
       if (line.Substring(i, 1).Equals("#")) 
       { //block -> (bool isPassable, Texture2D texture, Rectangle rectangle, Vector2 position) 
        block = new Block(false, textureBlock, rectBlock, positionBlock); 
        blocks.Add(block); 
        positionBlock.X += (width/100) * 24; 
       } 
      } 


      positionBlock.Y += (height/100) * 8; 
      positionBlock.X = 0; 
     } 
    } 

//This method below updates the character 'bob' position and velocity. 
public void UpdatePlayer() 
    { 
     bob.position += bob.velocity; 
     bob.rectangle = new Rectangle((int)bob.position.X, (int)bob.position.Y, width/30, height/30); 

     float i = 1; 
     bob.velocity.Y += 0.15f * i; 
     foreach (Block block in blocks) 
     { 
      if (bob.isOnTopOf(bob.rectangle, block.rectangle)) 
      { 
       bob.velocity.Y = 0f; 
       bob.hasJumped = false; 
      } 
     } 
    } 

Character.cs

//Here is my whole Character class for 'bob' 

public class Character 
{ 
    int height = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; 
    int width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; 

    int health; 
    String name; 
    bool gender; 
    Texture2D texture; 
    public Vector2 position; 
    public Vector2 velocity; 
    public bool hasJumped; 
    public Rectangle rectangle; 

    public Character(int newHealth, String newName, bool newGender, Texture2D newTexture, Vector2 newPosition) 
    { 
     health = newHealth; 
     gender = newGender; 
     name = newName; 
     texture = newTexture; 
     position = newPosition; 
     hasJumped = true; 
     rectangle = new Rectangle(0,0, width/30,height/30); 
     velocity = Vector2.Zero; 
    } 

    public bool isOnTopOf(Rectangle r1, Rectangle r2) 
    { 
     const int penetrationMargin = 5; 

     return (r1.Bottom >= r2.Top - penetrationMargin && 
      r1.Bottom <= r2.Top && 
      r1.Right >= r2.Left + 5 && 
      r1.Left <= r2.Right - 5); 

    } 


    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(texture, rectangle,null, Color.White,0,position,SpriteEffects.None,0); 
    } 

} 

Извините, если это слишком много писал код или сбивает с толку, но любая помощь очень ценится! Благодаря!

ответ

3

Ваше тестовое условие для пересечения, по-видимому, неверно. Там могут быть и другие проблемы, связанные с кодом (есть несколько просто дать быстрый взгляд на него), но давайте остановимся на этом:

r1.Bottom >= r2.Top - penetrationMargin && 
r1.Bottom <= r2.Top && 
r1.Right >= r2.Left + 5 && 
r1.Left <= r2.Right - 5; 

Во-первых, не существует кода, что в библиотеке для вас. У Xna Rectangles есть метод Intersects, поэтому замените этот код и используйте его вместо этого.

Мы будем смотреть на состояние в любом случае:

r1's Bottom is below r2's Top minus a margin AND 
r1's Bottom is above r2's Top AND (...) 

Это уже невозможно. r1.Bottom не может быть как ниже, так и выше r2.Top.

Кроме того, даже если все сравнения были правильными, вы используете AND везде (& &), что означает, что условие истинно только в том случае, если все 4 из них являются истинными. В принципе, вы не проверяете пересечение, вы тестируете наложение, т. Е. Вы проверяете, что r1 полностью находится в пределах r2. Тест пересечения присоединился бы к условиям, использующим OR (||) не AND (& &).

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

+0

Благодарим за помощь. Этот способ намного проще. – Derek

0

Я понял, но я не уверен, почему это действительно работает. Что-то не так с моим методом рисования. Я первоначально имел:

spriteBatch.Draw(texture, rectangle, null, Color.White, 0, position, SpriteEffects.None, 0); 

как мой метод, но затем я изменил это

spriteBatch.Draw(texture, rectangle, Color.White); 

и теперь все работает отлично.

+0

Не знаете, почему форматирование не работает, извините! – Derek

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