2017-03-14 56 views
0

我正在創建一個遊戲,需要一些幫助來處理一堆對象,比如約10000,在我的遊戲中,我生成隨機數量的岩石,在1mil乘1mil地圖,我將這些對象添加到列表中,然後像那樣更新和繪製它們,但運行速度很慢。我認爲在這個問題上的一些幫助會真正幫助很多想要處理許多對象的學習者。 這裏是我輩代碼:C#XNA,處理大量對象,

public void WorldGeneration() 
    { 
     //Random Compatibility 
     Random rdm = new Random(); 

     //Tile Variables 
     int tileType; 
     int tileCount = 0; 
     Rock nearestRock; 

     //Initialize Coordinates 
     Vector2 tileSize = new Vector2(48f, 48f); 
     Vector2 currentGenVector = new Vector2(48f, 48f); 
     int worldTiles = 1000000; 

     //Do tile generation 
     for(int tile = 1; tile <= worldTiles; tile += 1) 
     { 
      //Generate Classes 
      tileType = rdm.Next(0, 42); 
      if (tileType == 1) 
      { 
       if (rocks.Count != 0) 
       { 
        //Check Rock Distance 
        nearestRock = rocks.FirstOrDefault(x => Vector2.Distance(x.Location, currentGenVector) < 128); 
        if (nearestRock == null) 
        { 
         Rock rock = new Rock(rockSprite, currentGenVector); 
         rocks.Add(rock); 
        } 
       } 
       if (rocks.Count == 0) 
       { 
        Rock rock = new Rock(rockSprite, currentGenVector); 
        rocks.Add(rock); 
       } 
      } 

      //Move Generation Tile 
      if (tileCount == worldTiles/1000) 
      { 
       currentGenVector.X = tileSize.X; 
       currentGenVector.Y += tileSize.Y; 
       tileCount = 0; 
      } 
      else 
      { 
       currentGenVector.X += tileSize.X; 
      } 
      //Keep Count of Tiles per layer. 
      tileCount += 1; 
     } 

這裏是我的磐石代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Graphics; 

namespace Game2 
{ 
    class Rock 
    { 
     //Draw Support 
     Texture2D sprite; 
     Rectangle drawRectangle; 

    //Support 
    Vector2 location; 
    bool updating = false; 

    //Active 
    bool active = true; 

    public Rock(Texture2D sprite, Vector2 location) 
    { 
     //Initialize Location/Drawing 
     this.sprite = sprite; 
     this.location = location; 

     drawRectangle.Width = sprite.Width; 
     drawRectangle.Height = sprite.Height; 

     drawRectangle.X = (int)location.X - sprite.Width/2; 
     drawRectangle.Y = (int)location.Y - sprite.Height/2; 
    } 

    public void Update(GameTime gameTime, MouseState mouse) 
    { 
     //Mining 
     if (drawRectangle.Contains(mouse.X, mouse.Y)) 
     { 
      if (mouse.LeftButton == ButtonState.Pressed) 
      { 
       location.X = -800; 
       location.Y = -800; 
      } 
     } 
     drawRectangle.X = (int)location.X; 
     drawRectangle.Y = (int)location.Y; 
    } 

    public void Draw(SpriteBatch spriteBatch) 
    { 
     //Draws The Sprite 
     spriteBatch.Draw(sprite, drawRectangle, Color.White); 
    } 

    //Get Location 
    public Vector2 Location 
    { 
     get { return location; } 
    } 
    public bool Updating 
    { 
     get { return updating; } 
    } 
    public void setUpdating(bool updating) 
    { 
     this.updating = updating; 
    } 
    public Rectangle DrawRectangle 
    { 
     get { return drawRectangle; } 
    } 
} 
} 

我只是問了關於如何處理所有這些對象,一些提示 請幫助表示讚賞

+0

哪個慢?更新循環或繪製循環?您可以忽略不在當前視口中的岩石。 – itsme86

+0

我認爲這是更新循環,但我會試一試,我會怎麼做?對不起,我是XNA和C#的新手,仍然在學習。 – Luny

回答

0

我處理很多對象的方式是我創建一個函數來計算兩個向量之間的距離,然後使用它來檢查當前對象是否足夠接近以便繪製。

//Distance checking code 
public float GetDistance(Vector2 v1, Vector2 v2){ 
    float d = Math.Sqrt(Math.Abs((v1.X * v1.X) - (v2.X * v2.X)) 
    + Math.Abs((v1.Y * v1.Y) - (v2.Y * v2.Y))); 
return d; 
} 

//example of using the Distance Check 
if(GetDistance(player.position, rock.position) < 1280){ 
    rock.Update(); 
} 

雖然這只是我的頭頂,所以代碼可能無法正常工作,但我認爲這足以讓你開始。祝你好運!