J'ai travaillé sur un moteur de jeu similaire à Terraria , principalement sous forme de défi. Bien que j'aie compris l'essentiel, je n'arrive pas vraiment à comprendre comment ils gèrent les millions de tuiles interactives / récupérables. le jeu a à la fois. Créer environ 500 000 tuiles, soit 1 / 20e de ce qui est possible dans Terraria , dans mon moteur, le débit d'images passe de 60 à environ 20, même si je ne fais que restituer les tuiles en vue. Remarquez, je ne fais rien avec les carreaux, je les garde seulement en mémoire.
Mise à jour : code ajouté pour montrer comment je fais les choses.
Cela fait partie d'une classe qui gère les carreaux et les dessine. Je suppose que le coupable est la partie "foreach", qui itère tout, même les index vides.
...
public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
foreach (Tile tile in this.Tiles)
{
if (tile != null)
{
if (tile.Position.X < -this.Offset.X + 32)
continue;
if (tile.Position.X > -this.Offset.X + 1024 - 48)
continue;
if (tile.Position.Y < -this.Offset.Y + 32)
continue;
if (tile.Position.Y > -this.Offset.Y + 768 - 48)
continue;
tile.Draw(spriteBatch, gameTime);
}
}
}
...
Voici également la méthode Tile.Draw, qui pourrait également être mise à jour, chaque mosaïque utilisant quatre appels à la méthode SpriteBatch.Draw. Cela fait partie de mon système de notation automatique, ce qui signifie que chaque coin doit être dessiné en fonction des tuiles voisines. texture_ * sont des rectangles, sont définis une fois à la création du niveau, pas à chaque mise à jour.
...
public virtual void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
if (this.type == TileType.TileSet)
{
spriteBatch.Draw(this.texture, this.realm.Offset + this.Position, texture_tl, this.BlendColor);
spriteBatch.Draw(this.texture, this.realm.Offset + this.Position + new Vector2(8, 0), texture_tr, this.BlendColor);
spriteBatch.Draw(this.texture, this.realm.Offset + this.Position + new Vector2(0, 8), texture_bl, this.BlendColor);
spriteBatch.Draw(this.texture, this.realm.Offset + this.Position + new Vector2(8, 8), texture_br, this.BlendColor);
}
}
...
Toute critique ou suggestion à mon code est la bienvenue.
Mise à jour : solution ajoutée.
Voici la dernière méthode Level.Draw. La méthode Level.TileAt vérifie simplement les valeurs entrées pour éviter les exceptions OutOfRange.
...
public void Draw(SpriteBatch spriteBatch, GameTime gameTime)
{
Int32 startx = (Int32)Math.Floor((-this.Offset.X - 32) / 16);
Int32 endx = (Int32)Math.Ceiling((-this.Offset.X + 1024 + 32) / 16);
Int32 starty = (Int32)Math.Floor((-this.Offset.Y - 32) / 16);
Int32 endy = (Int32)Math.Ceiling((-this.Offset.Y + 768 + 32) / 16);
for (Int32 x = startx; x < endx; x += 1)
{
for (Int32 y = starty; y < endy; y += 1)
{
Tile tile = this.TileAt(x, y);
if (tile != null)
tile.Draw(spriteBatch, gameTime);
}
}
}
...