Tôi đã làm việc với một công cụ trò chơi tương tự như Terraria , chủ yếu là một thử thách và trong khi tôi đã tìm ra hầu hết trong số đó, tôi dường như không thể quấn đầu xung quanh cách họ xử lý hàng triệu viên gạch có thể tương tác / thu hoạch được Trò chơi đã có lúc. Tạo khoảng 500.000 ô, tức là 1/20 so với Terraria , trong công cụ của tôi khiến tốc độ khung hình giảm từ 60 xuống còn khoảng 20, ngay cả khi tôi vẫn chỉ hiển thị các ô trong chế độ xem. Nhắc bạn, tôi không làm gì với gạch, chỉ giữ chúng trong bộ nhớ.
Cập nhật : Mã được thêm vào để hiển thị cách tôi làm mọi thứ.
Đây là một phần của lớp, xử lý các ô và vẽ chúng. Tôi đoán thủ phạm là phần "foreach", nó lặp đi lặp lại mọi thứ, thậm chí cả các chỉ mục trống.
...
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);
}
}
}
...
Ngoài ra, đây là phương thức Tile.Draw, cũng có thể thực hiện với một bản cập nhật, vì mỗi Ngói sử dụng bốn lệnh gọi đến phương thức SpriteBatch.Draw. Đây là một phần của hệ thống tự động điền của tôi, có nghĩa là vẽ từng góc tùy thuộc vào các ô lân cận. texture_ * là hình chữ nhật, được đặt một lần ở mức tạo, không phải mỗi lần cập nhật.
...
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);
}
}
...
Bất kỳ phê bình hoặc đề xuất cho mã của tôi đều được chào đón.
Cập nhật : Đã thêm giải pháp.
Đây là phương thức Level.Draw cuối cùng. Phương thức Level.TileAt chỉ cần kiểm tra các giá trị được nhập, để tránh các ngoại lệ 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);
}
}
}
...