Saya telah mengerjakan sebuah mesin permainan yang mirip dengan Terraria , sebagian besar sebagai tantangan, dan sementara saya sudah menemukan sebagian besar dari itu, saya tidak bisa benar-benar membungkus kepala saya bagaimana mereka menangani jutaan ubin yang dapat berinteraksi / dapat dipanen permainan memiliki satu waktu. Membuat sekitar 500.000 ubin, yaitu 1/20 dari apa yang mungkin di Terraria , di mesin saya menyebabkan frame-rate turun dari 60 menjadi sekitar 20, bahkan saya masih hanya menampilkan ubin dalam tampilan. Pikiran Anda, saya tidak melakukan apa pun dengan ubin, hanya menyimpannya dalam ingatan.
Pembaruan : Kode ditambahkan untuk menunjukkan bagaimana saya melakukan sesuatu.
Ini adalah bagian dari kelas, yang menangani ubin dan menggambarnya. Saya menduga pelakunya adalah bagian "foreach", yang mengulangi semuanya, bahkan indeks kosong.
...
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);
}
}
}
...
Juga di sini adalah metode Tile.Draw, yang juga bisa dilakukan dengan pembaruan, karena setiap Tile menggunakan empat panggilan ke metode SpriteBatch.Draw. Ini adalah bagian dari sistem autotiling saya, yang berarti menggambar setiap sudut tergantung pada ubin tetangga. tekstur_ * adalah Persegi Panjang, ditetapkan sekali pada level penciptaan, tidak setiap pembaruan.
...
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);
}
}
...
Setiap kritik atau saran untuk kode saya diterima.
Pembaruan : Solusi ditambahkan.
Inilah metode Level.Draw terakhir. Metode Level.TileAt cukup memeriksa nilai yang dimasukkan, untuk menghindari pengecualian 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);
}
}
}
...