2012-10-21 50 views
0

我的碰撞檢測似乎正在工作,所有這些都是它檢測到的碰撞是奇怪的,因爲它會說碰撞在平臺的底部,當它不是「T。但這不是主要問題。XNA 4.0碰撞檢測導致精靈彈跳

當玩家與平臺發生碰撞時,他不會移動到平臺的表面,而是移動到平臺的表面上,並且在我的重力的作用下,看起來他總是在彈跳。我無法弄清楚爲什麼。

如果你們可以幫助它,將不勝感激。這可能是一些非常簡單的東西,因爲我是XNA和C#的新手。

我將在下面列出我的Game1,Player和Platoform類。 (我的碰撞檢測是在播放器類)

感謝

Game1類

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

    Texture2D background; 
    Movement character; 
    Platform[] platforms; 
    //private Vector2 SnapePosition = Vector2.Zero; 

    public Game1() 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
     graphics.PreferredBackBufferHeight = 440; 
     graphics.PreferredBackBufferWidth = 782; 

    } 

    /// <summary> 
    /// Allows the game to perform any initialization it needs to before starting to run. 
    /// This is where it can query for any required services and load any non-graphic 
    /// related content. Calling base.Initialize will enumerate through any components 
    /// and initialize them as well. 
    /// </summary> 
    protected override void Initialize() 
    { 
     // TODO: Add your initialization logic here 
     platforms = new Platform[15]; 


     base.Initialize(); 
    } 

    /// <summary> 
    /// LoadContent will be called once per game and is the place to load 
    /// all of your content. 
    /// </summary> 
    protected override void LoadContent() 
    { 
     // Create a new SpriteBatch, which can be used to draw textures. 
     spriteBatch = new SpriteBatch(GraphicsDevice); 


     for (int i = 0; i < platforms.Length; i++) 
     { 
      platforms[i] = new Platform(
       Content.Load<Texture2D>("Platforms/lvl2_platform"), new Rectangle(i*100, 410, 100, 30)); 
     } 
     character = new Movement(Content.Load<Texture2D>("snape"), new Rectangle(0, 360, 50, 50), platforms); 

     // TODO: use this.Content to load your game content here 
     background = Content.Load<Texture2D>("Backgrounds/lvl2_background"); 
    } 

    /// <summary> 
    /// UnloadContent will be called once per game and is the place to unload 
    /// all content. 
    /// </summary> 
    protected override void UnloadContent() 
    { 
     // TODO: Unload any non ContentManager content here 
    } 

    /// <summary> 
    /// Allows the game to run logic such as updating the world, 
    /// checking for collisions, gathering input, and playing audio. 
    /// </summary> 
    /// <param name="gameTime">Provides a snapshot of timing values.</param> 
    protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     //Allows the player to move 
     character.Update(); 

     // TODO: Add your update logic here 


     base.Update(gameTime); 
    } 

    /// <summary> 
    /// This is called when the game should draw itself. 
    /// </summary> 
    /// <param name="gameTime">Provides a snapshot of timing values.</param> 
    protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 

     // TODO: Add your drawing code here 

     spriteBatch.Begin(); 
     spriteBatch.Draw(background, Vector2.Zero, Color.White); 
     character.Draw(spriteBatch); 

     foreach (Platform platform in platforms) 
     { 
      platform.Draw(spriteBatch); 
     } 
     spriteBatch.End(); 

     base.Draw(gameTime); 
    } 
} 

Player類

class Player 
{ 
    public Texture2D Snape; 
    public Rectangle SnapePosition; 

    public enum CollisionPosition { None, Top, Bottom, Left, Right }; 
    public CollisionPosition collisionType; 
    public bool inCollision; 
    public int collisionDepth; 
    public Platform[] plat; 
    public int num; 

    public virtual void Update() 
    { 

    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(Snape, SnapePosition, Color.White); 
    } 
} 

class Movement : Player 
{ 
     public Movement(Texture2D newSnape, Rectangle newSnapePosition, Platform[] a) 
    { 
     Snape = newSnape; 
     SnapePosition = newSnapePosition; 
     plat = a; 
    } 

     public override void Update() 
     { 
      // Check for collision 
      Collisions(); 

      // Determine collision type 
      //DetermineCollisionType(); 

      // Separate snape 
      //SeparateSnape(); 

      KeyboardState keyBoard = Keyboard.GetState(); 

      if (keyBoard.IsKeyDown(Keys.A)) 
      { 
       SnapePosition.X -= 5; 
      } 
      if (keyBoard.IsKeyDown(Keys.D)) 
      { 
       SnapePosition.X += 5; 
      } 
      if (keyBoard.IsKeyDown(Keys.W)) 
      { 
       SnapePosition.Y -= 5; 
      } 
      //if (keyBoard.IsKeyDown(Keys.S)) 
      //{ 
       SnapePosition.Y += 5; 
      // } 



      // if (SnapePosition.X < 0) 
      //  SnapePosition.X = 0; 
      // if (SnapePosition.Y < 0) 
      //  SnapePosition.Y = 0; 
      // if (SnapePosition.X > GraphicsDevice.Viewport.Width - Snape.Width) 
      //  SnapePosition.X = GraphicsDevice.Viewport.Width - Snape.Width; 
      // if (SnapePosition.Y > GraphicsDevice.Viewport.Height - Snape.Height) 
      //  SnapePosition.Y = GraphicsDevice.Viewport.Height - Snape.Height; 

     } 


     public void Collisions() 
     { 
      for (int i = 0; i < plat.Length; i++) 
      { 
       if (plat[i].rectangle.Intersects(SnapePosition)) 
       { 
        inCollision = true; 
        num = i; 
        DetermineCollisionType(); 
       } 

      } 

     } 

     public void DetermineCollisionType() 
     { 
      if (inCollision == false) 
      { 
       collisionType = CollisionPosition.None; 
       collisionDepth = 0; 
      } 
      else 
      { 
       // Determine the side of *least intersection* for snape 
       int minColDepth = int.MaxValue; 

       // Check the top side      
       int tColDepth = (plat[num].rectangle.Y + plat[num].texture.Height/2) - (SnapePosition.Y - Snape.Height/2); 

       if (tColDepth > 0 && tColDepth < minColDepth) 
       { 
        collisionType = CollisionPosition.Top; 
        minColDepth = tColDepth; 
       } 

       // Check the bottom side    
       int bColDepth = (SnapePosition.Y + Snape.Height/2) - (plat[num].rectangle.Y - plat[num].texture.Height/2); 

       if (bColDepth > 0 && bColDepth < minColDepth) 
       { 
        collisionType = CollisionPosition.Bottom; 
        minColDepth = bColDepth; 
       } 

       // Check the right overlap 
       int rColDepth = (SnapePosition.X + Snape.Width/2) - (plat[num].rectangle.X - plat[num].texture.Width/2); 

       if (rColDepth > 0 && rColDepth < minColDepth) 
       { 
        collisionType = CollisionPosition.Right; 
        minColDepth = rColDepth; 
       } 

       // Check the left overlap 
       int lColDepth = (plat[num].rectangle.X + plat[num].texture.Width/2) - (SnapePosition.X - Snape.Width/2); 

       if (lColDepth > 0 && lColDepth < minColDepth) 
       { 
        collisionType = CollisionPosition.Left; 
        minColDepth = lColDepth; 
       } 

       // Update the collision depth 
       collisionDepth = minColDepth; 
       SeparateSnape(); 
      } 
     } 



     public void SeparateSnape() 
     { 
      switch (collisionType) 
      { 
       case CollisionPosition.None: 
        break; 

       case CollisionPosition.Top: 
        SnapePosition.Y += (collisionDepth); 
        break; 

       case CollisionPosition.Bottom: 
        SnapePosition.Y -= collisionDepth; 
        break; 

       case CollisionPosition.Right: 
        SnapePosition.X -= collisionDepth; 
        break; 

       case CollisionPosition.Left: 
        SnapePosition.X += collisionDepth; 
        break; 
      } 
     } 
} 

平臺類

class Platform 
{ 
    public Texture2D texture; 
    public Rectangle rectangle; 

    public Platform(Texture2D newTexture, Rectangle newRectangle) 
    { 
     texture = newTexture; 
     rectangle = newRectangle; 
    } 

    public void Update() 
    { 

    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     spriteBatch.Draw(texture, rectangle, Color.White); 
    } 


} 

回答

0

我搞掂你collisi上。

所有深度計算都不正確。你是基於實體(玩家/平臺)的中心來做它們,並使用它們的紋理大小而不是它們的矩形大小。

你可能一直在想所有東西都從中間畫出來,但是默認情況下它從XNA的左上角畫出。

以下是位於「DetermineCollisionType()」函數下「運動」類中的新深度計算。

頂部深度需要在平臺頂部(Y)和snape底部(Y +高度)上工作。

int tColDepth = 
    (SnapePosition.Y + SnapePosition.Height) - (plat[num].rectangle.Y); 

底部深度需要對playform的底部(Y +高度)和斯內普(Y)的頂部工作。

int bColDepth = 
    (plat[num].rectangle.Y + plat[num].rectangle.Height) - (SnapePosition.Y); 

右深度需要對平臺(X)的左側和斯內普的右側(X +寬)工作。

int rColDepth = 
    (SnapePosition.X + SnapePosition.Width) - (plat[num].rectangle.X); 

左側深度需要在平臺右側(X +寬度)和Snape(X)左側工作。

int lColDepth = 
    (plat[num].rectangle.X + plat[num].rectangle.Width) - (SnapePosition.X); 

這將從現在開始工作。但是,您可能想要爲您的平臺使用列表。如果你做關卡編輯器時,列表比較容易,因爲你不必說「我想要15個平臺」。