如何在 C# 中创建指针列表?

How can I make a list of pointers in c#?

我目前正在用 monogame 编写我自己的 2d 引擎,但无法继续,因为我想创建一个精灵指针列表。我的想法是,每次初始化一个精灵时,它都会被添加到列表中,当调用 draw 函数时,列表中的每个精灵都用一个 foreach 循环渲染。 问题是如果我改变精灵的属性,比如位置或颜色,那么我必须刷新列表,这不是最好的方法。我的新想法是制作一个指向相应 sprites.So 的指针列表,当您渲染时,您可以访问变量而不是 reference.Or 也许还有一个列表对象可以完成工作为了我?提前致谢!

My idea is that every time a sprite is initialized it is added to the list and when the draw function is called, every sprite in the list is rendered with a foreach loop.

需要与 Game 对象一起更新和绘制的公共对象的需求非常频繁。您可以有多种方法来实现它。 Monogame 甚至有它自己的使用抽象 class GameComponents 的实现,我在最后提到了它。

The problem is if I change the properties of the sprite, like position or color, then I have to refresh the list, and that's not the best way.

我认为这个问题是由于您的列表中的对象是值类型而不是引用类型(相当于 C# 中的指针)。在这种情况下,您可以尝试以下方法:

  1. 不要使用通用类型 List<T>,而是使用 System.Collections.Generic 中的 LinkedList<T>,您应该按如下方式使用它:
class Game1:Game
{
    LinkedList<MyCustomClass> list;
    
    ...
    
    void LoadContent()
    {
        list = new LinkedList<MyCustomClass>();

        ...

        list.AddLast(myobject);
    }
    void Update(GameTime gameTime)
    {
        //Do not use a foreach loop. Instead, do this:
        for (var node = list.First; node != null; node = node.Next)
        {
            node.ValueRef.Update(); 
        //Important to use ValueRef, as it returns the reference of the object
        }

        ...


    }
}

此处,LinkedListNode<T>ValueRef 属性(此处由 list.First 属性 返回)将为您提供您所需要的:参考你的对象。

  1. 就算你用List也应该没问题,但是你的Type必须是Reference类型。这意味着您需要将其更改为 class.
  2. ,而不是将您的自定义类型设为 struct

如果您使用上面给出的方法 2,您可能需要查看 GameComponents class,这是 Monogame 解决此问题的内置方法。 GameComponents 是一个抽象的 class,所以不用说,您需要将类型从 struct 更改为 class

假设您有如图所示的自定义 class

public class MyCustomClass: Microsoft.Xna.Framework.GameComponent
{
    public MyCustomClass(Game game)
        : base(game)
    {

    }
}

LoadContent()Initialize()Update() 方法是继承的,可以根据需要覆盖。

您可以在 Game class 中创建此 class 的实例,并将此对象添加到 Components 属性 的 Game 对象如图所示

    var MyCustomObject = new MyCustomClass(this);
    Components.Add(MyCustomObject);

通过这样做,基础 class Game 在其各自的调用中调用 Update()Draw()LoadContent() 方法。

您可以使用以下方法遍历所需的对象

    foreach (var item in Components)
    {
        if(item is MyCustomClass)
        {
            var myitem = item as MyCustomClass;
            ...
        }
    }