0

我是 SFML 的新手,目前我只是在玩一个例子。我尝试在窗口中最后一次单击鼠标的位置绘制一个精灵。但是由于某种原因,事件触发并且没有绘制精灵。我真的不知道为什么。

我一直在查看文档,但似乎没有做错任何事情。请帮帮我好吗?:3

该事件称为 OnMouseLeftClick,我正在尝试绘制 mouseLeftClickSprite 对象。我已经删除了一些无关紧要的代码,例如 OnMouseMoved 事件和 OnClose 事件。他们与此无关。

using System;
using SFML.Audio;
using SFML.Graphics;
using SFML.Window;

namespace SFMLExample
{
    class Program
    {
        static Text xMouseCoord;
        static Text yMouseCoord;
        static Text statusMsg;
        static float mouseX, mouseY;
        static Texture mouseLeftClickTexture;
        static Sprite mouseLeftClickSprite;

        static void OnMouseLeftClick(object sender, EventArgs e)
        {
            if (Mouse.IsButtonPressed(Mouse.Button.Left))
            {
                statusMsg.DisplayedString = "Console: OnMouseLeftClick() Fired";
                RenderWindow window = (RenderWindow)sender;
                mouseLeftClickSprite.Position = new Vector2f(mouseX, mouseY);
                window.Draw(mouseLeftClickSprite);
            }
        }

        static void Main(string[] args)
        {
            mouseX = 0.0f;
            mouseY = 0.0f;
            // Create the main window
            RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML Window");
            window.Closed += new EventHandler(OnClose);
            window.MouseMoved += new EventHandler<MouseMoveEventArgs>(OnMouseMoved);
            window.MouseButtonPressed += new EventHandler<MouseButtonEventArgs>(OnMouseLeftClick);

            // Load a sprite to display
            Texture texture = new Texture("cute_image.jpg");
            Sprite sprite = new Sprite(texture);

            mouseLeftClickTexture = new Texture("GM106.png");
            mouseLeftClickSprite = new Sprite(mouseLeftClickTexture);

            // Create a graphical string to display
            Font font = new Font("arial.ttf");
            Text text = new Text("Hello SFML.Net", font);

            xMouseCoord = new Text("Mouse X: ", font);
            yMouseCoord = new Text("Mouse Y: ", font);
            statusMsg = new Text("Console: ", font);

            // Play some Music
            //Music music = new Music("nice_music.mp3");
            //music.Play();

            // Start the game loop
            while (window.IsOpen())
            {
                // Process events
                window.DispatchEvents();

                // Clear screen
                window.Clear();

                sprite.Scale = new Vector2f(1.0f, 1.0f);
                sprite.Position = new Vector2f(window.Size.X / 2, window.Size.Y / 2);
                // Draw the sprite
                window.Draw(sprite);

                // Draw the strings
                xMouseCoord.Position = new Vector2f(text.Position.X, text.Position.Y + 30);
                yMouseCoord.Position = new Vector2f(xMouseCoord.Position.X, xMouseCoord.Position.Y + 30);
                statusMsg.Position = new Vector2f(yMouseCoord.Position.X, yMouseCoord.Position.Y + 30);
                window.Draw(text);
                window.Draw(xMouseCoord);
                window.Draw(yMouseCoord);
                window.Draw(statusMsg);

                // Update the window
                window.Display();
            }
        }
    }
}

在下面添加了这一点以进行澄清

 static void OnMouseMoved(object sender, EventArgs e)
    {
        RenderWindow window = (RenderWindow)sender;
        Vector2i vector = window.InternalGetMousePosition();
        mouseX = vector.X;
        mouseY = vector.Y;
        xMouseCoord.DisplayedString = "Mouse X: " + mouseX;
        yMouseCoord.DisplayedString = "Mouse Y: " + mouseY;
        statusMsg.DisplayedString = "Console: ";
    }
4

2 回答 2

1

你只画一次你的精灵。在大约每秒 60 帧的情况下,您可能会看到它闪烁……或不闪烁。如果您需要它保持永久状态,则需要记住主程序中的点,然后在每次绘制其他内容时在该点绘制一个精灵。

您可能想研究游戏编程模式。通常情况下,您有三个不断重复的大块:获取用户输入、根据用户输入采取行动、绘制结果。

在伪代码中:

while(isRunning)
{
    HandleUserInput();

    ChangeWorld():

    Render();
}

这样,您可以检查自己所做的是否正确。例如,在您的场景中,您会在处理用户输入时绘制一些东西。不好。

于 2013-05-16T08:38:52.023 回答
0

事件在所谓的window.DispatchEvents(). 当您单击窗口时,将触发该事件并绘制您的精灵。

问题是你正在调用window.Clear()它,所以你看不到结果。正如 nvoigt 所说,您必须在每一帧渲染所有内容,也就是说在循环的每一轮。这就是为什么使用Clear()Window 中的方法来清除前一帧的结果的原因。

您可以做的是记住触发事件时鼠标的位置或直接根据它设置精灵的位置。然后将精灵与文本等一起绘制。如果您不希望在单击鼠标之前显示它,只需将其坐标放在窗口外的某个点上,这样它就不会被绘制。

于 2013-05-17T17:33:21.477 回答