【问题标题】:C#/XNA How do I get my classes to "speak" to each other?C#/XNA 如何让我的班级互相“交流”?
【发布时间】:2013-09-04 15:28:47
【问题描述】:

我正在尝试构建超级马里奥兄弟第一关的克隆,但我在让我的班级互相“交流”时遇到了一些麻烦。到目前为止,我有两个控制器类(键盘、游戏手柄)和两个动画精灵类(RunMarioSprite、DeadMarioSprite)。我想要做的是根据用户的键盘/游戏板输入在屏幕上显示的这两个精灵之间切换。如果按下 F 键,马里奥应该会显示为向右运行。如果按下 D 键,马里奥应该上下移动。

通过我的控制器类更改在屏幕上绘制的动画精灵类的正确方法是什么?

键盘类

public class KeyboardController : IController
{
    KeyboardState keyboard = Keyboard.GetState();
    private IAnimatedSprite marioSprite;
    Texture2D texture;

    public void Update()
    {
        if (keyboard.IsKeyDown(Keys.Q))
        {
            // QUIT GAME    
        }
        if (keyboard.IsKeyDown(Keys.F))
        {
            // MARIO RUN RIGHT             
        }
        if (keyboard.IsKeyDown(Keys.D))
        {
            // DEAD MARIO UP DOWN

        }
    }
}

动画精灵类的示例

public class RunMarioSprite : IAnimatedSprite
{
    public Texture2D Texture { get; set; }
    private int currentFrame = 0;
    private int totalFrames = 4;
    public int frameShift = 30;

    public RunMarioSprite(Texture2D texture)
    {
        currentFrame = 0;
        this.Texture = texture;
    }

    public void Update()
    {
        currentFrame++;
        if (currentFrame == totalFrames)
            currentFrame = 0;
    }

    public void Draw(SpriteBatch spriteBatch)
    {

        Rectangle sourceRectangle2 = new Rectangle((240 +(currentFrame*frameShift)), 0, 30, 30);
        Rectangle destinationRectangle2 = new Rectangle(100, 100, 30, 30);

        spriteBatch.Begin();
        spriteBatch.Draw(Texture, destinationRectangle2, sourceRectangle2, Color.White);
        spriteBatch.End();
    }
}


    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();


        // TODO: Add your update logic here
      foreach (IController Controller in ControllerList)
        {
           Controller.Update();
        }

        marioSprite.Update();
        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
        marioSprite.Draw(this.spriteBatch);

        base.Draw(gameTime);
    }

主要(更新和绘制)

    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();


        // TODO: Add your update logic here
      foreach (IController Controller in ControllerList)
        {
           Controller.Update();
        }

        marioSprite.Update();
        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
        marioSprite.Draw(this.spriteBatch);

        base.Draw(gameTime);
    }

如果问题格式不正确,我深表歉意。感谢您的帮助!

【问题讨论】:

  • 你有什么问题?如何根据你得到的输入画出左右奔跑的马里奥?
  • @pinckerman 我希望我的键盘类根据用户的输入选择适当的动画精灵类。也就是说,如果用户按下“F”键,我希望我的 RunMarioSprite 类执行它的绘图。如果用户要按“D”键,我希望我的 DeadMarioSprite 执行它的绘图。实际的绘图方法运行正常。只需要我的 KeyboardController 类来“控制”一切,但我不确定如何引用该原始类中的特定类。谢谢!
  • 如果 RunMarioSprite 和 DeadMarioSprite 之间的区别只是要绘制的纹理,你只需要改变它,但如果它们有不同的行为,你必须改变 marioSprite 的实例。这样,您的游戏将绘制正确的实例。
  • 注意:在 Main(Update/Draw) 中,marioSprite 是 IAnimatedSprite 类型(所有动画精灵类的接口)。 内容加载如下: 'spriteSheet = Content.Load("MarioSpriteSheet"); marioSprite = new DeadMarioSprite(spriteSheet);'
  • @pinckerman 我想这是我最初的问题。如何从我的 KeyboardController 类中更改 marioSprite 的实例?

标签: c# class xna


【解决方案1】:

您需要在精灵管理器类中处理您的KeyboardController,其目的是在屏幕上绘制您的整个关卡。可能你不需要KeyboardController,而只需要KeyboardState

KeyboardController keyboardController = new KeyboardController();

public void Update()
{
   // you should implement a method like this
   KeyboardState keyboard = keyboardController.GetKeyboardState();

   if (keyboard.IsKeyDown(Keys.F))
   {
      //change marioSprite instance         
   }
   if (keyboard.IsKeyDown(Keys.D))
   {
      //change marioSprite instance
   }
 }

【讨论】:

  • 我想实现一个键盘控制器,因为我还需要一个游戏手柄控制器的功能。我不希望代码位于更新中。
  • 您可以创建一个 KeyboardController 实例和一个公共方法,该方法将为您提供当前按下的键,因此具有其实例的类将知道您的游戏正在接收什么输入,或者传递 KeyboardState。
  • 我已经编辑了我的答案。关键是你不能修改你的marioSprite表单KeyboardController,你必须在你的“主”类中利用KeyboardController,我不知道你是怎么命名的。
【解决方案2】:

如果您要求的是一种基于另一个类中的键盘输入来知道在 Main.Draw() 方法中绘制哪个精灵的方法,您可以尝试这样的方法:

public class Main
{
    public static bool DrawAliveMario;
    RunMarioSprite runmariosprite;
    DeadMarioSprite deadmariosprite;

    protected override void Draw(GameTime gameTime)
    {
        //...

        // TODO: Add your drawing code here
        if (DrawAliveMario) runmariosprite.Draw(this.spriteBatch);
        else deadmariosprite.Draw(this.spriteBatch);

        base.Draw(gameTime);
    }

}

然后你可以在你的控制器类中:

public class KeyboardController : IController
{
    KeyboardState keyboard = Keyboard.GetState();

    public void Update()
    {
        if (keyboard.IsKeyDown(Keys.Q))
        {
            // QUIT GAME    
        }
        if (keyboard.IsKeyDown(Keys.F))
        {
            Main.DrawAliveMario = true;           
        }
        if (keyboard.IsKeyDown(Keys.D))
        {
            Main.DrawAliveMario = false;

        }
    }
}

希望这会有所帮助。

【讨论】:

  • 当然 DrawAliveMario 是 bool,你缺少声明中的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 2018-07-24
相关资源
最近更新 更多