I'm currently programming my own 2d engine with monogame and can't get any further because I want to create a list of sprite pointers. 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. 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. My new idea is to make a list of pointers that point to the respective sprites.So that when you render you have access to the variable and not to a reference.Or maybe there is also a list object that does the work for me? Thanks in advance!
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.
The need for having common objects that need to be updated and drawn along with the Game
object is very frequent. You can have multiple approaches for implementing it. Monogame even has it's own implementation of it using the abstract class GameComponents
and I have mentioned it in the end.
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.
I believe this problem is due to the fact that the objects in your list are value types and not reference types (equivalent to pointers in C#). In this case, you have the following approaches to try:
List<T>
, use a LinkedList<T>
in System.Collections.Generic
, and you should use it as follows: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
}
...
}
}
Here, the ValueRef
property of LinkedListNode<T>
(Here returned by list.First
property) will give you exactly what you need: A reference to your object.
struct
, you need to change it to class
.In case you are using method 2 given above, you might want to check out the GameComponents
class, which is Monogame's in-built approach to this problem. GameComponents
is an abstract class, so it goes without saying you need to change your type from struct
to class
.
Let's say you have your custom class as shown
public class MyCustomClass: Microsoft.Xna.Framework.GameComponent
{
public MyCustomClass(Game game)
: base(game)
{
}
}
The LoadContent()
, Initialize()
, and Update()
methods are inherited and can be overridden to your liking.
You can create an instance of this class in your Game
class, and add this object to the Components
property of the Game
object as shown
var MyCustomObject = new MyCustomClass(this);
Components.Add(MyCustomObject);
By doing this, The base class Game
calls the Update()
, Draw()
, LoadContent()
methods on its own respective calls.
You can iterate through your required objects using the following approach
foreach (var item in Components)
{
if(item is MyCustomClass)
{
var myitem = item as MyCustomClass;
...
}
}