2012-06-02 3 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 사각형에는 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 이하 모두 일 수 없습니다.

더욱이 모든 비교가 정확하더라도 모든 위치 AND (& &)를 사용하고 있습니다. 즉, 조건이 모두 참인 경우에만 조건이 참임을 의미합니다. 기본적으로, 교차로를 테스트하지 않고 containement를 테스트하고 있습니다. 즉 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