简体   繁体   中英

Java better way to store procedural Information

I was wondering how I can optimize storing procedural information and acessing specific elements within a list of data..

For example when I'm creating vegetation in my world I tell my system to starts at 0 an makes a line of 10 element, then it goes back to 0 and increases the z position to create another line.

To keep track of any object by storing data such as position, rotation, texture and model in ArrayLists to access them elsewhere when needed, in collision detection for example:

public void collision_ForestTree001() { 
    int modelID = 0;

    while(treeXArray.size() != modelID && treeZArray.size() != modelID) {

// player and object bounds
        float playerX = 0.15f;
        float playerZ = 0.15f;

        float objectX = 0.2f;
        float objectZ = 0.2f;

// collision check

        if((PlayerX)+playerX < treeXArray.get(modelID)-objectX ||
                (PlayerX)-playerX > treeXArray.get(modelID)+objectX) {
            collisionX = false;
            } else {                
                collisionX = true;  
            }

        if((PlayerZ)+playerZ < treeZArray.get(modelID)-objectZ ||
                (PlayerZ)-playerZ > treeZArray.get(modelID)+objectZ) {
            collisionZ = false;
            } else {
                collisionZ = true;  
            }

        modelID++;
    }
}

I was wondering if there's a better way to store and acess data like that because acessing the information with ArrayLists seems kind of stupid because I have to go through the elements one by one in order to find the desired data.. thanks for any help!

If each forest is independant in its behavior, your solution seems not so bad. If you want to optimize the CPU and reduce the iteration count of your list, you could use some maps which associates screen regions and forests. So, according to the position of your player, you will check only collision with forests in the screen region.

Edit for the sub question :

You are welcome. I love game programming too. Enjoy :)

As said in my initial message, if each tree is independant in its behavior, it's a good way to go. What I mean by independant is when your player touches one tree, THIS tree must react by doing something such as a little move, you have not the choice : you must check each tree in the region where the player is in order to do the reaction for THE touched tree.

However, if when your player touches one tree, the tree does not react, just player reacts (for example by stopping him), you can factorize the collision detection. So you can consider that the collision should be calculated not on the region where the user is, but on the whole region where trees are located. So, you can use one or multiple rectangles to cover the tree collision detection and you have not forced to iterate on the lists.

For storing data like that i would suggest you make a class to represent each vegetation object that will store all your data. This object is called a entity.

public class Entity {

    private double xCord;
    private double yCord;
    private double zCord;

    //or in opengl you can use Vector3f() depending on your library

    private double rotX;
    private double rotY;
    private double rotZ;

    private Texture texture;

    //assuming your model is represented by a class object
    private Model model;

    public Entity(double xC, double yC, double zC, double rX,
         double rY, double rZ, Texture t, Model m) {

        xCord = xC;
        yCord = yC;
        zCord = zC;
        rotX = rX;
        rotY = rY;
        rotZ = rZ;
        texture = t;
        model = m;
    }

    public double getX(){
        return xCord;
    }

    public double getY(){
        return yCord;
    }

    public double getZ(){
        return zCord;
    }

    public double getRotX(){
        return rotX;
    }

    public double getRotY(){
        return rotY;
    }

    public double getRotZ(){
        return rotZ;
    }

    public Texture getTexture(){
        return texture;
   }

    public Model getModel(){
        return model;
    }

}

Then you can store all of your entitys in a arraylist which you will iterate through to render each of them. Also, you can add mutator methods to edit your Entitys like changing rotation or position. Also for maximum efficiency you can use the distance formula to determine which entitys are in render distance and only render and test those for collisions. This can speed up a program a good bit since rendering is the heaviest task in almost any program.

Since you're asking about how to do this better, here's a couple pointers.

  1. Work on your encapsulation. I'm assuming that you're calling this method every frame to change the values of collisionX and collisionZ (which should be immutable by outside methods). This is bad OOP. You should be passing this method the arguments it needs to determine collision, then returning the states of collisionX and collisionZ.

  2. Initialize playerX/Z, object X/Z outside of the scope of your while loop. No need to create new variables every time you loop.

  3. Abstract your objects further. Store the coordinates of the total area of the object on the 2d plane in a Map/Hashmap.

  4. Reduce computational strain by defining larger less intensive checks for collision. Eg only check collision with objects in screen region as suggested above, in grid regions, or if you have complex object shapes, determine the smallest circle that wraps around the entire collision object, do the same for your player character, then do a distance check between their respective circle centers. If the distance check returns a high enough value, simply skip the collision check, if not, use a more accurate collision check.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM