0

我正在尝试Mouse.GetState()用于我的菜单选择。目前,只有当我将鼠标悬停在菜单所在区域的左侧和上方时,它才会突出显示。我使用 DrawString 显示鼠标坐标,发现 0,0 点不在显示器的左上角或游戏窗口的左上角。它距离屏幕左上角大约 100,100 像素。此外,每次运行程序时,0,0 点都会移动。

我查看了其他有同样问题但无法解决的人。我尝试Mouse.WindowHandle = this.Window.Handle;在我的中使用,Initialize()但没有任何效果。我有两台显示器,当我强制全屏游戏时,它会在我的第二台显示器上打开,所以我禁用了它,但问题仍然存在。

这是我的代码http://pastebin.com/PNaFADqp的链接

游戏1类:

public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont spriteFont;

    public const int WINDOW_HEIGHT = 800;
    public const int WINDOW_WIDTH = 600;

    public int tree;

    public TitleScreen titleScreen;
    public SATDemo satDemo;
    public SeparatingAxisTest separatingAxisTest;
    public SATWithAABB sATWithAABB;

    GameState currentState;

    public static Dictionary<string, Texture2D> m_textureLibrary = new Dictionary<string, Texture2D>();
    public static Dictionary<string, SpriteFont> m_fontLibrary = new Dictionary<string, SpriteFont>();

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        graphics.PreferredBackBufferHeight = WINDOW_HEIGHT;
        graphics.PreferredBackBufferWidth = WINDOW_WIDTH;
    }

    protected override void Initialize()
    {
        Mouse.WindowHandle = this.Window.Handle;
        //enable the mousepointer
        IsMouseVisible = true;
        currentState = GameState.TitleScreen;
        //sets the windows mouse handle to client bounds handle

        base.Initialize();
    }

    public void RequestSATDemo()
    {
        currentState = GameState.RequestSATDemo;
    }

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);


        m_textureLibrary.Add("Pixel", Content.Load<Texture2D>("White_Pixel"));
        m_fontLibrary.Add("Font", Content.Load<SpriteFont>("MotorwerkOblique"));

        titleScreen = new TitleScreen();
        satDemo = new SATDemo();
        separatingAxisTest = new SeparatingAxisTest();
        sATWithAABB = new SATWithAABB();
     }

    public void RequestSeparatingAxisTest()
    {
        currentState = GameState.SeparatingAxisTest;
    }

    public void RequestSATWithAABB()
    {
        currentState = GameState.SATWithAABB;
    }

    protected override void Update(GameTime gameTime)
    {
        MouseTestState = Mouse.GetState();
        switch (currentState)
        {
            case GameState.TitleScreen:
                {
                    titleScreen.Update(gameTime);
                    break;
                }
            case GameState.SeparatingAxisTest:
                {
                    separatingAxisTest.Update(gameTime);
                    break;
                }
            case GameState.SATWithAABB:
                {
                    sATWithAABB.Update(gameTime);
                    break;
                }
            case GameState.Exit:
                {
                    Exit();
                    break;
                }
            default:
                {
                    titleScreen.Update(gameTime);
                    break;
                }
        }

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        spriteBatch.Begin();

        spriteBatch.DrawString(m_fontLibrary["Font"], MouseTestState.ToString(), new Vector2(0, 0), Color.White);
        switch (currentState)
        {
            case GameState.TitleScreen:
                {
                    titleScreen.Draw(spriteBatch, spriteFont);
                    break;
                }
            case GameState.SeparatingAxisTest:
                {
                    separatingAxisTest.Draw(gameTime, spriteBatch);
                    break;
                }
            case GameState.SATWithAABB:
                {
                    sATWithAABB.Draw(gameTime, spriteBatch);
                    break;
                }
            case GameState.Exit:
                {
                    Exit();
                    break;
                }
            default:
                {
                    titleScreen.Update(gameTime);
                    break;
                }
        }

        spriteBatch.End(); 
        base.Draw(gameTime);
    }
}

TitleScreen 类:

public class TitleScreen : Screen
{ 
    List<Button> buttonList = new List<Button>();
    public Menu mainMenu;
    public TitleScreen()
    {
        mainMenu = new Menu(new Vector2(200, 100), buttonList, 0); 
        buttonList.Add(new PushButton("Separating Axis Test"));
        buttonList.Add(new PushButton("SAT With AABB"));
        buttonList.Add(new PushButton("Awesome"));
        buttonList.Add(new PushButton("Awesomere"));
        buttonList.Add(new PushButton("Awesomere")); 
    }

    public override void Update(GameTime gametime)
    {
        mainMenu.Update(gametime);
    }

    public void Draw(SpriteBatch sB, SpriteFont sF)
    {
        mainMenu.Draw(sB, sF); 
    } 
}

按钮类:

public class PushButton : Button
{
    string m_text;
    SpriteFont m_font;
    Color m_static, m_onClick, m_onHover;
    Texture2D m_sprite2D, m_onClick2D;

    static public int Pbuttoncount;

    //click processing
    bool m_clickedInside =  false,
         m_releasedInside = false,
         m_OnClicked =      false,
         selected =         false;

    Rectangle drawRectangle;

    public PushButton(string Text)
    {
        m_text = Text;

        drawRectangle = new Rectangle((int)Menu.m_position.X, (int)Menu.m_position.Y + (15 * Pbuttoncount), 200, 15);
        ButtonRegion = new Rectangle((int)Position.X, (int)Position.Y, 200, 15);
        Pbuttoncount++;
    }

    public PushButton(Rectangle ButtonRegion, SpriteFont Font, string Text, Color Static, Color OnClick, Color OnHover)
    {
        m_buttonRegion = ButtonRegion;
        m_font = Font;
        m_text = Text;
        m_static = Static;
        m_onClick = OnClick;
        m_onHover = OnHover;
        // drawRectangle = ButtonPosition(m_buttonRegion);
     }

    public PushButton(Rectangle ButtonRegion, Texture2D Sprite2D, Texture2D OnClick2D)
    {
        m_buttonRegion = ButtonRegion;
        m_sprite2D = Sprite2D;
        m_onClick2D = OnClick2D;
        //drawRectangle = ButtonPosition(m_buttonRegion);
    }

    public override void Update(GameTime gameTime)
    {
        MouseState currentMouse = Mouse.GetState();

        selected = MouseState(drawRectangle, currentMouse);
        m_clickedInside = ClickInside(currentMouse, m_lastMouseState);
        ReleaseInside(currentMouse, m_lastMouseState);

        if (selected && m_clickedInside && m_releasedInside)
            m_OnClicked = true;
        else
            m_OnClicked = false;

        m_lastMouseState = currentMouse;
    }

    public override void Draw(SpriteBatch spriteBatch, SpriteFont spriteFont, int buttonCount, Vector2 Position)
    {
        spriteBatch.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)Position.X + 10, (int)(Position.Y + 15 * buttonCount), 180, 15), Color.Wheat);

        if (selected)
            spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Orange);
        else
            spriteBatch.DrawString(Game1.m_fontLibrary["Font"], m_text, new Vector2(Position.X + 15, Position.Y + 15 * buttonCount), Color.Black);
    }
}

菜单类:

public class Menu
{
    List<Button> m_buttonList;
    float m_transparency;
    public int n = 0;
    public Rectangle buttonRegion, m_menuRegion, m_dimensions;
    static public Vector2 m_position;
    int m_WINDOW_HEIGHT = Game1.WINDOW_HEIGHT;
    int m_WINDOW_WIDTH = Game1.WINDOW_WIDTH;
    private Game1 m_managerClass;

    public Menu(Vector2 Position, List<Button> ButtonList, float Transparency)
    {
        m_position = Position;
        m_buttonList = ButtonList;
        m_transparency = Transparency;
        m_managerClass = new Game1();
    }

    public Rectangle MenuRegion
    {
        get { return m_menuRegion; }
        set { m_menuRegion = value; }
    }

    static public Vector2 Position
    {
        get { return m_position; }
    }

    public void Update(GameTime gametime)
    {
        for (int i = 0; i < m_buttonList.Count; i++)
        {
            m_buttonList[i].Update(gametime);
            if (m_buttonList[0].OnClicked)
            {
                SeperatingAxisTest();
            }
        }
    }

    public void Draw(SpriteBatch sB, SpriteFont sF)
    {
        sB.Draw(Game1.m_textureLibrary["Pixel"], new Rectangle((int)m_position.X - 5, (int)m_position.Y - 10, (m_buttonList[0].ButtonRegion.Width + 10), (m_buttonList[0].ButtonRegion.Height * m_buttonList.Count) + 20), Color.Blue);
        for (int i = 0; i < m_buttonList.Count; i++)
        {
            m_buttonList[i].Draw(sB, sF, i, new Vector2(Position.X, Position.Y));
        } 
    }

    private void SeperatingAxisTest()
    {
        m_managerClass.RequestSeparatingAxisTest();
    }
}

节目类:

public static class Program
{
    [STAThread]
    static void Main()
    {
        using (var game = new Game1())
            game.Run();
    }
}

需要帮助请叫我。我还在学习,我会把我的灵魂卖给你以获得答案。

4

1 回答 1

0

您的Menu班级正在创建Game1. 这很可能不是您想要的,因为Game1它是在您的应用程序的入口点中实例化的。该Game1实例有一个 的实例TitleScreen,而该实例又具有该类的一个实例Menu,因此 aMenu不应该创建自己的游戏。

创建此(其他)实例时,它会调用特定于平台的 (Windows) 方法,创建一个额外的窗口句柄(从未显示)并配置Mouse.WindowHandle.

顺便说一句,WindowHandle手动设置在 Monogame 中绝对没有任何作用,所以所有这些提到的消息来源都在谈论 XNA。

所以,有几点说明:

  1. 您可能应该有一个包含当前屏幕的“屏幕管理器”类。在你的游戏类中有一个 type 字段是很奇怪的TitleScreen,它至少应该是基本类型 ( Screen),这样游戏类才能透明地绘制和更新每个屏幕。

  2. 如果你需要在任何地方引用游戏类,不要实例化一个新的,而是通过构造函数传递它。

  3. m_managerClass对于实际上是Game. 还 google 了 C# 命名约定。也许您甚至可能想要下载现有的单人游戏模板,例如在线查看一些示例NetRumble 示例似乎实现了一个屏幕管理器。

  4. 删除该Mouse.WindowHandle行,默认情况下应将其设置为您的唯一游戏窗口。

tl; dr在您可能需要的地方添加Game1作为参数(但仅在您需要的地方)。

abstract class Screen
{
     private readonly Game1 _game;
     public Game1 Game 
     { get { return _game; } }

     public Screen(Game1 game)
     {
         _game = game;
     }
}

class TitleScreen : Screen 
{
     public TitleScreen(Game1 game)
         : base(game)
     { ... }
}

class Menu 
{
     private readonly Screen _screen;

     public Menu(Screen parentScreen, Vector2 pos, List<Button> list, float alpha)
     {
          _screen = parentScreen;
          ...

          // if you need the game instance, just use _screen.Game
     }
}
于 2016-02-16T13:55:59.597 回答