2013-05-28 42 views
1

我正在用Java製作2D物理遊戲,並且最近決定徹底重新開始,以便該程序的基礎具有靈活性和線程性。我的問題是找到一種方法來存儲我的遊戲數據在程序的持續時間內記住線程。創建一個靈活的臨時遊戲數據存儲系統

我的用於存儲數據前段庫看上去像這樣

public float[] sphereX = new float[sphereNum]; 
public float[] sphereY = new float[sphereNum]; 
public float[] sphereXMem = new float[sphereNum]; 
public float[] sphereYMem = new float[sphereNum]; 
public float[] sphereVX = new float[sphereNum]; // X Velocity 
public float[] sphereVY = new float[sphereNum]; // Y Velocity 

// Misc Variables 
public float[] sphereMass = new float[sphereNum]; 
public float[] sphereRadius = new float[sphereNum]; 

雖然這是很好的,不必穿線和較少的功能程序,我目前的計劃將有一些新的要求,這之前的版本並沒有解決。這些包括:

  • 球體的量是不斷變化的
  • 球體具有更的數據類型。 (布爾,int和float)
  • 該遊戲數據被不斷地訪問和多線程修改

我擔心鎖螺紋出的數據,直到鎖定鍵變爲可用將拖慢了程序顯著自在計算所有物理數據時,大約有1-4個線程將被拖拽。

我目前的解決方案的想法是有一個對象的Arraylist包含該對象的參數數組,但我不知道如何使線程工作的線索。正如你可能猜到的,我在線程方面有點新,但知道波動和基本同步的基本概念。另外,如果您想知道,我正在使用線程來希望允許我的程序利用多個內核。

編輯:經過考慮我已經提出了這個意見。這是正確的嗎?我並不打算在開始時創建一個單獨的課程,但它可能是最好的。我覺得這很愚蠢,但是如果我把它放在一個單獨的文件中,它會保留它的信息嗎?從這裏,我只是添加多個項目(項目是新的球體)到我的ArrayList在主類?

enter code here`public class Item 
{ 
    private Object lockActive = new Object(); 
    private Object lockType = new Object(); 
    private Object lockMass = new Object(); 
    private Object lockLocation = new Object(); 
    private Object lockLocationMemory = new Object(); 
    private Object lockVelocity = new Object(); 

    private boolean active; 
    private int type; 
    private float mass; 
    private float[] location; 
    private float[] locationMemory; 
    private float[] velocity; 

    public Item(boolean active, int type, float mass, float[] location, float[] locationMemory, float[] velocity) 
    { 
     this.active = active; 
     this.type = type; 
     this.mass = mass; 
     this.location = location; 
     this.locationMemory = locationMemory; 
     this.velocity = velocity; 
    } 

    public boolean GetActive() 
    { 
     synchronized (lockActive) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return active; 
     } 
    } 

    public synchronized int GetType() 
    { 
     synchronized (lockType) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return type; 
     } 
    } 

    public synchronized float GetMass() 
    { 
     synchronized (lockMass) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return mass; 
     } 
    } 

    public synchronized float[] GetLocation() 
    { 
     synchronized (lockLocation) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return location; 
     } 
    } 

    public synchronized float[] GetLocationMemory() 
    { 
     synchronized (lockLocationMemory) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return locationMemory; 
     } 
    } 

    public synchronized float[] GetVelocity() 
    { 
     synchronized (lockVelocity) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      return velocity; 
     } 
    } 

    public void SetActive() 
    { 
     synchronized (lockActive) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.active = active; 
     } 
    } 

    public void SetType(int type) 
    { 
     synchronized (lockType) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.type = type; 
     } 
    } 

    public void SetMass(float mass) 
    { 
     synchronized (lockMass) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.mass = mass; 
     } 
    } 

    public void SetLocation(float[] location) 
    { 
     synchronized (lockLocation) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.location = location; 
     } 
    } 

    public void SetLocationMemory(float[] locationMemory) 
    { 
     synchronized (lockLocationMemory) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.locationMemory = locationMemory; 
     } 
    } 

    public void SetVelocity(float[] velocity) 
    { 
     synchronized (lockVelocity) 
     { 
      try 
      { 
       Thread.sleep(1); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      this.velocity = velocity; 
     } 
    } 

} 

回答

4

不要這樣對自己。定義一個球體對象來保存球體的所有屬性,而不是爲每個屬性創建一個數據結構。編寫同步的方法,以便多個線程不會一次更改單個球體。

這裏有一個快速和骯髒的開始:

//Sphere.java 
public class Sphere { 
    private float[] position; 
    private float[] mem; 
    private float[] velocity; 

    public Sphere(float[] position, float[] mem, float[] velocity) { 
     this.position = position; 
     this.mem = mem; 
     this.velocity = velocity; 
    } 

    public synchronized float[] getPosition() { 
     return position; 
    } 
    public synchronized float[] getVelocity() { 
     return velocity; 
    } 

    public synchronized void move() { 
     position[0]+=velocity[0]; 
     position[1]+=velocity[1]; 
    } 
} 

這時,你可能在其他地方初始化數據:

int sphereCount = 30; 
    List<Sphere> spheres = new ArrayList<Sphere>(); 
    Random rand = new Random(); 
    for(int i = 0; i < sphereCount; i++) { 
     spheres.add(
      new Sphere(
       new float[]{20*rand.nextFloat(), 20*rand.nextFloat()}, //position 
       new float[]{20*rand.nextFloat(), 20*rand.nextFloat()}, //mem 
       new float[]{2*rand.nextFloat(), 2*rand.nextFloat()} //velocity 
      ) 
     ); 
    } 

再次,這只是粗略的,模糊的代碼,我沒有給它想得很多。這裏的主要想法是使用對象來描述'事物',以便您可以將所有基本代碼在這些對象中進行操作,並將其用於代碼的其餘部分。

關於​​關鍵字,這意味着該方法中的所有內容都發生在該同一對象上的任何其他同步方法調用完全之前或完全之後。

+0

我確實想擺脫上面所展示的內容,但我不完全確定如何去做你所說的話。 – Walden95

+1

進一步的改進可能是使用'Position'和'Velocity'類。使這些對象不可變。利用'volatile'並消除'synchronized'。 –

+0

好的,我現在跟着編輯。該技術看起來可能有效。我仍然感到有點困惑,但也許這是因爲我需要離開這一點。編輯:蒂姆本德,感謝您的建議。 – Walden95