2013-02-03 5 views
0

나는 C# 및 XNA 4.0뿐만 아니라 Farseer Physics Engine (Box2D와 매우 유사)을 사용하고 있으며 OBlock, LBlock, 등은 다음기본 클래스 목록에서 파생 클래스 필드에 액세스

블록대로 :

class Block 
{ 
    public Body m_body; 
    public virtual void Draw(SpriteBatch spriteBatch) { } 

    public virtual void RemoveBody(World world) 
    { 
     //world.RemoveBody(m_body); 
    } 
} 

내가

그래서 내 오버라이드 (override) 버전은 뭔가를 그래서 나는이 목록에 자신의 오버라이드 (override) 버전에 액세스 할 수있는 등 그 메소드, 필드, 봐 넣어 만했습니다 이렇게 : OBlock.cs

class OBlock : Block 
{ 

    private static Texture2D blockImg; //I load this in LoadContent so I don't have loads of Texture2Ds 
    public new Body m_body; //Is this right? 

    public OBlock(World world, Vector2 position) 
    { 
     m_body = BodyFactory.CreateBody(world, position); // Create the body, changing it from null 
     FixtureFactory.AttachRectangle(Game1.blockSide *2, Game1.blockSide *2, 1.0f, new Vector2(0, 0), m_body); //This bit changes between classes 
     m_body.BodyType = BodyType.Dynamic; 

    } 

    public override void RemoveBody(World world) 
    { 
     world.RemoveBody(m_body); 
    } 

    public static void LoadImage(Texture2D tex) 
    { 
     OBlock.blockImg = tex; 
    } 

    public override void Draw(SpriteBatch spriteBatch) 
    { 

     Vector2 position = m_body.Position * Game1.MetreInPixels; 
     Vector2 origin = new Vector2(blockImg.Width/2, blockImg.Height/2); 

     float rotation = m_body.Rotation; 

     spriteBatch.Begin(); 

     spriteBatch.Draw(blockImg, position, null, Color.White, rotation, origin, Game1.BLOCK_SCALE, SpriteEffects.None, 1); 

     spriteBatch.End(); 

     base.Draw(spriteBatch); 
    } 
} 

또한 LBlock, ZBlock 등이 모두 제가 주석 처리 한 비트와 매우 유사하게 보입니다.

내가 다음

List<Block> blocks //As a field in Game1 

blocks = new List<Block>(); // In LoadContent after loading images 

에 그들 모두를 난 할 노력하고있어 분명히 m_body 항상 null 관계없이

blocks[index].m_body.DOSTUFF(); 

를 사용하여 유형의 목록에있는 블록에 대한 액세스 m_body입니다. ..

+0

줄에서 한 줄씩 코드를 단계별로 실행하면 개체에서 m_body를 보면서 어떻게됩니까? – SecurityMatt

답변

0
public new Body m_body; 

이것은 올바르지 않습니다. Block 클래스의 m_body (abstractbtw라고 표시해야 함)은 해당 클래스에서 파생되는 모든 클래스에서 볼 수 있습니다. 지금 당신이하고있는 일은 다양한 합병증을 일으키는 은신처 (항상 피해야 함)라고합니다.

는 이제 각 OBlock는 두 멤버 m_body, Block에 속하는 한, OBlock에 속하는 하나가되도록 만들었습니다. OBlock 클래스에서 클래스의 this.m_body을 참조 할 때마다 OBlock에 속한 m_body 필드가 할당되고 m_blockBlock으로 남겨집니다.이 숨어 회원과 함께 제공되는 이상한 합병증 중 하나입니다 예상대로이 반면

Block myBlock = new OBlock(); 
// myBlock.m_block is null, because myBlock is of type block, and remember, 
// the m_block belonging to Block is never assigned to, only the one belonging 
// to OBlock 

가 작동합니다 :

OBlock myOBlock = new OBlock(); 
// myOBlock.m_block isn't null, because it was assigned to in the constructor. 

그래서 숨어을 피하기! 코드 파일에서

public new Body m_body; 

를 제거하고 m_block 어쨌든 그것에서 파생하는 모든 클래스에 의해 상속 Block 선언 때문에 당신은 갈 수 있어요.

+0

것은, 나는 나가 족 답할 수있는 모든 나의 다른 구획의 명부가 있고 싶다, 나가 원하는 어떤 구획의 몸에 접근하십시오. 기본 클래스 목록을 단계별로 실행해야하는데이 클래스를 파생 클래스에 넣어야합니까? –

+0

@WilliamOsborne 목록을 반복하여 파생 클래스 yes로 각각의 인스턴스를 인스턴스화합니다. 코드에서'public new Body m_body;'줄을 지우면 모든 것이 잘되어 있어야하고 설명대로 작동 할 것이다. – antonijn

+0

아 맞습니다. 이제 작동합니다. 감사! –

2

public new body m_body; //이게 옳은 거니?

아니요! 이것은 저장소의 두 번째 비트를 선언합니다. 그래서 당신은 Block의 m_body와 OBlock의 m_body를 가지며, 단지 널이 아닌 것으로 초기화합니다. m_body에 대한 특정 참조가 해결할 정확한 규칙은 이해하기가 너무 지루합니다.

위의 행을 완전히 삭제하고 상속의 기본 사항에 익숙해지는 데 시간을 할애해야합니다. 예 : http://msdn.microsoft.com/en-gb/library/ms173149.aspx

0
public new Body m_body; 

이렇게하면 기본 클래스의 m_body가 숨겨집니다. 그래서 기본적으로 파생 클래스 (기본 클래스가 아닌)에서 m_body의 새 인스턴스를 정의합니다. 그래서 그것은 기본 클래스의 m_body가 초기화되지 않기 때문에 null이 될 것이라고 생각합니다.

그래서 모든 파생 클래스에 대해 m_body가 이미 정의되어 있으므로 Block 클래스에서 파생되므로 해당 특정 행을 제거하십시오. 자세한 내용은 this MSDN article을 참조하십시오.

관련 문제