2016-10-12 1 views
1

J'utilise le framework MonoGame pour créer un jeu de plateforme. Le jeu a quelques mécanismes de base comme: la gravité, et la détection de collision qui ne fonctionne que sur le dernier objet d'une liste.XNA/MonoGame - Comment vérifier la collision de chaque objet d'une liste en utilisant un rectangle comme boîte de délimitation

Voici le code de la zone de jeu du jeu (script principal): `

using Microsoft.Xna.Framework; 
    using Microsoft.Xna.Framework.Graphics; 
    using Microsoft.Xna.Framework.Input; 
    using Survive.Engine; 
    using System.Collections.Generic; 

    namespace Game 
    { 
     public class MainGame : Game 
     { 
      GraphicsDeviceManager graphics; 
      SpriteBatch spriteBatch; 

      Player player = new Player(); 

      List<Box> boxes = new List<Box>(); 

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

      protected override void Initialize() 
      { 
       Box box = new Box(); 
       box.Init(new Vector2(100, 400), Content.Load<Texture2D>("Player")); 

       Box box2 = new Box(); 
       box2.Init(new Vector2(132, 400), Content.Load<Texture2D>("Player")); 

       player.Init(new Vector2(100, 100), Content.Load<Texture2D>("Player")); 

       boxes.Add(box); 
       boxes.Add(box2); 

       base.Initialize(); 
      } 

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

      protected override void UnloadContent() 
      { 

      } 

      protected override void Update(GameTime gameTime) 
      { 
       if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) 
        Exit(); 

       for (int i = 0; i < boxes.Count; i++) 
       { 
        if (player.Colliding(boxes[i])) 
        { 
         player.falling = false; 
        } 

        if (!player.Colliding(boxes[i])) 
        { 
         player.falling = true; 
        } 
       } 

       player.Update(); 
       boxes.ForEach(k => k.Update()); 

       base.Update(gameTime); 
      } 

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

       spriteBatch.Begin(); 

       player.Draw(spriteBatch); 

       for (int i = 0; i < boxes.Count; i++) 
       { 
        boxes[i].Draw(spriteBatch); 
       } 

       spriteBatch.End(); 

       base.Draw(gameTime); 
      } 
     } 
    }` 

Voici la classe d'objet (ce joueur, et la boîte est construite hors de):

`

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Game.Engine 
{ 
    public class Object2D 
    { 
     public int Health = 100; 
     public Vector2 Position; 
     public Texture2D Texture; 
     public Rectangle BoundingBox; 

     public bool Colliding(Object2D obj) 
     { 
      bool col = false; 

      if (BoundingBox.Intersects(obj.BoundingBox)) 
      { 
       col = true; 
      } 

      return col; 
     } 

     public virtual void Init(Vector2 pos, Texture2D text) 
     { 
      Position = pos; 
      Texture = text; 
     } 

     public virtual void Update() 
     { 
      BoundingBox = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height); 
     } 

     public virtual void Draw(SpriteBatch spriteBatch) 
     { 
      spriteBatch.Draw(Texture, Position, Color.White); 
     } 
    } 
} 

`

script joueur:

`

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Survive.Engine; 
using Microsoft.Xna.Framework.Input; 

namespace Survive 
{ 
    public class Player : Object2D 
    { 
     public float vsp = 0; 
     public float grav = 0.1f; 
     public bool falling = true; 
     public bool jmping = false; 

     public override void Init(Vector2 pos, Texture2D text) 
     { 
      base.Init(pos, text); 
     } 

     public override void Update() 
     { 
      if (Keyboard.GetState().IsKeyDown(Keys.A)) 
      { 
       Position.X -= 2; 
      } 

      if (Keyboard.GetState().IsKeyDown(Keys.D)) 
      { 
       Position.X += 2; 
      } 

      if (falling) 
      { 
       vsp += grav; 
       Position.Y += vsp; 
      } 

      base.Update(); 
     } 

     public override void Draw(SpriteBatch spriteBatch) 
     { 
      base.Draw(spriteBatch); 
     } 
    } 
}` 

La boîte hérite seulement de Object2D.cs, aucun code a été modifié.

Mais dans le vide de mise à jour du MainGame.cs, où nous vérifions la collision:

`

 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) 
      Exit(); 

     for (int i = 0; i < boxes.Count; i++) 
     { 
      if (player.Colliding(boxes[i])) 
      { 
       player.falling = false; 
      } 

      if (!player.Colliding(boxes[i])) 
      { 
       player.falling = true; 
      } 
     } 

     player.Update(); 
     boxes.ForEach(k => k.Update());` 

Le code fonctionne, mais seulement pour le second objet dans notre liste, quand je me déplace au-dessus de la première boîte ajoutée, je tombe juste, comme la gravité est appliquée.

Je ne suis pas sûr pourquoi il vérifie seulement pour la dernière boîte dans la liste des boîtes.

Répondre

1

Vous n'arrêtez pas la recherche une fois que vous avez trouvé une collision. Modifier ce code:

for (int i = 0; i < boxes.Count; i++) 
    { 
     if (player.Colliding(boxes[i])) 
     { 
      player.falling = false; 
     } 

     if (!player.Colliding(boxes[i])) 
     { 
      player.falling = true; 
     } 
    } 

... à quelque chose comme:

var isFalling=true; // assume the worst 

for (int i = 0; i < boxes.Count; i++) 
    { 
     if (player.Colliding(boxes[i])) 
     { 
      isFalling = false; 
      break; 
     } 
    } 

player.falling = isFalling; 
+0

Merci! Je vais essayer ça. –

+0

Cela n'a pas fonctionné –

+0

Êtes-vous sûr que vos boîtes de délimitation sont correctes? – MickyD