创建灵活的临时游戏数据存储系统

时间:2013-05-28 23:40:51

标签: java arrays multithreading arraylist

我正在使用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];

虽然这对于没有线程和更少功能的程序来说是好的,但我当前的程序将有几个新的要求,而这个以前的版本没有解决。其中包括:

  • 球体的数量在不断变化
  • Spheres拥有更多数据类型。 (boolean,int和float)
  • 此游戏数据正在被多个线程持续访问和修改

我担心在锁定密钥可用之前将数据锁定在数据之外会使程序显着减慢,因为在计算所有物理时,大约有1-4个线程会被扯掉。

我目前对解决方案的想法是让一个包含该对象参数数组的对象的Arraylist,但我不知道如何使用线程进行这项工作。

正如您可能猜到的那样,我对线程有点新,但我知道波动性和基本同步的基本概念。另外,如果你想知道,我正在使用线程来希望我的程序能够利用多个核心。

编辑:经过评论后,我想出了这个。这是正确的吗?我并不打算在一开始就创建一个单独的类,但它可能是最好的。我觉得这很愚蠢,但是如果我将所有信息放在一个单独的文件中,它会保留其信息吗?从这里,我只是在主类中的ArrayList中添加多个Items(Item是新的Sphere)?

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;
        }
    }

}

1 个答案:

答案 0 :(得分: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
            )
        );
    }

同样,这只是粗糙,模糊的代码,我没有多想过。这里的主要思想是使用对象来描述“事物”,这样你就可以将所有细节代码放在那些对象和其他代码中。

对于synchronized关键字,这意味着该方法中的所有内容都在完全在该同一对象上的任何其他同步方法调用之前或完全之后发生。