C# XNA/MonoGame 分页:如何防止重复

C# XNA/MonoGame Paging: How To Prevent Duplicates

所以,最近我遇到了一个问题。你们中的一些人可能已经在 上看到了我的 post。不过,这一次不是用户。这是接口。

我创建了一个游戏,您可以在其中创建用户,用户使用用户界面 class 显示,您可以点击用户名登录或点击垃圾桶登录删除用户。然而,我意识到如果你创建超过 4 个用户,他们就会开始离开屏幕。于是,我开始实现分页。

这就是我遇到的问题。

我创建了 5 个用户:z、x、c、v 和 b。第一页正确绘制了 z、x、c 和 v。但是,在第 2 页上,b 被绘制了两次。当我创建另一个用户 "n" 时,它们被绘制在第二页 第三页。

我一直在尝试几种不同的解决方案。一种是尝试查找并删除每个重复项。但是,我觉得这不是很有效,所以我放弃了它。

已经查找了如何防止列表中的重复项,但是我的问题是:我有一个列表>,它是一个用于跟踪每个页面的列表,它保持跟踪每个用户界面。

这是我的一些代码:

List<UserInterface> interfaces; // This is all the interfaces
int page = 0;
List<List<UserInterface>> pages; // This is the list of pages of interfaces
const int INTERFACES_PER_PAGE = 4;

public Menu(args...)
{
    if (User.LoadUsers() /*User.LoadUsers returns a list with all the saved users*/ != null)
    {
        foreach (User u in User.LoadUsers())
        {
                UserInterface interfaceToAdd = new UserInterface(u, content, trashAsset, bigFont, whiteRectangleAsset, 0, 0, 
                    whenUsernameClicked, whenTrashClicked);
                interfaces.Add(interfaceToAdd);
                UpdatePagesToInterfaces();
        }
    }
}

这是更新方法:

public void Update(args...)
{
    for (int i = 0; i < pages.Count; i++)
    {
        if (pages[i].Count == 0)
        {
            pages.RemoveAt(i);
        }
    }

    while (page > pages.Count - 1)
    {
        page--;
    }

    if (interfaces.Count != interfaces.Distinct().Count())
    {
        interfaces = interfaces.Distinct().ToList();
        UpdatePagesToInterfaces();
    }
    if (pages.Count > 0)
    {
        for (int i = 0; i < pages[page].Count; i++)
        {
            pages[page][i].Update();
        }
    }
    // More updating, and code to update the next and previous page buttons
}

这里是私有方法。

private void UpdatePagesToInterfaces()
{
    // This method is very inefficient
    pages.Clear();
    foreach (UserInterface ui in interfaces)
    {
        AddUser(ui);
    }
}

private void AddUser(UserInterface userInterface)
{
    // This method makes sure that the new interface is added to the correct
    // page.
    UserInterface interfaceToAdd = userInterface;

    // This gets the currently used page and adds to it. 

    if (pages.Count > 0)
    {
        for (int i = 0; i < pages.Count; i++)
        {
            if (pages[i].Count < INTERFACES_PER_PAGE)
            {
                pages[i].Add(interfaceToAdd);
            }
            else
            {
                pages.Add(new List<UserInterface>());
                pages[i + 1].Add(interfaceToAdd);
            }
        }
    }
    else // pages.Count <= 0
    {
        pages.Add(new List<UserInterface>());
        pages[pages.Count - 1].Add(interfaceToAdd);
    }
}

如您所见,UpdatePagesToInterfaces 方法效率很低;我在这里要做的是找到重复项,然后删除它们。但是,我只想完全防止重复。有什么想法吗?

注意:我今年 13 岁,所以我可能不理解成人可能使用的一些高级术语。请确保答案不太难理解。

提前致谢!

 for (int i = 0; i < pages.Count; i++)
        {
            if (pages[i].Count < INTERFACES_PER_PAGE)
            {
                pages[i].Add(interfaceToAdd);
            }
            else
            {
                pages.Add(new List<UserInterface>());
                pages[i + 1].Add(interfaceToAdd);
            }
        }

假设 I=0 并且页面 I=0 已满而页面 I=1 中没有任何元素,那么我们将向 I=0+1=1 页面添加用户。 OK完成。现在页面 I=0 已满,而 I=1 有一个用户。 在循环的下一步中,我们将查看页面(现在 I=1)是否有空闲位置。它有!所以我们将再次添加相同的用户。

怎么会变成这样?!

你看,ListT.Count是一个属性。因此它将被重新计算以检查循环的每个步骤。所以在 pages.Add(...) pages.Count 之后将是 2,而不是 1 我们将进入下一步。

这是我亲眼所见

也没有冒犯,但请使用调试器(并使您的代码示例更短)。我想您可以在逐步执行的帮助下轻松找到它。

你的循环逻辑也有问题。当你发现我的页面已满时,你会自动将元素添加到下一页。但是也有可能满了,你需要检查一下。