0

Hello my name is Ryan and I'm currently developing my own 2D java game. Currently there are a lot of objects within the game world. Upon a new start of the game, the world loads with 100 tress randomly positioned on it, made with the use of an arraylist and a tree class. My game uses a class called checkcollisions to check if the player is intersecting with any tress. This method is then put within the update method. When this method is not called I get an extra 100 FPS is there away I can still get this 100 fps but still check for collisions? I really need an FPS boost asas my game currently runs at 30-50 fps

here is the checkcollisions code:

public void checkCollisions() {
    for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
        if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
            if (gotAxeOn) {Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);}
        }
        if (Placing_Objects.Small_Trees.get(i).health <= 0) {
            Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Stick");
            Player.exp += rand.nextInt(3);
            challenges.choppedDownTrees += 1;
        }
    }
}
  • The slow down could be caused by any number of function calls made in the checkCollisions function. The interests() function called on the player is a probable culprit. – Stieffers Oct 30 '13 at 17:07
  • Run your game in a profiler. – Cyrille Ka Oct 30 '13 at 17:07
  • possible duplicate of [My Java Game that struggles with fps](http://stackoverflow.com/questions/19683731/my-java-game-that-struggles-with-fps) – Richard Tingle Oct 31 '13 at 08:38
  • @user2876115 A profiler will tell you how much time each method uses; allowing you to find the bottle neck. Most IDEs (for example netbeans) come with profilers – Richard Tingle Oct 31 '13 at 08:44

5 Answers5

3

Only check for collisions with trees that are near to the player, or trees that are within the current visible rectangle. To do this efficiently, hold an array of objects that are visible and iterate only over those.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • how would i check if each individual tree is in the visible rectangle(camera) without using a for loop? –  Oct 30 '13 at 17:14
  • You have to. That is something you cannot avoid. But once you found the visible objects, you can perform *ALL your game logic* on those, instead of everything. That would be a major improvement if you are having lots of objects. – Martijn Courteaux Oct 30 '13 at 17:17
  • could u show me a code sample, java or pseudo would be alright –  Oct 30 '13 at 17:18
2

As Wilbert mentioned a kd-tree would be the perfect solution. For a simple 2d game with a lot of non moving objects you can try a simpler approach:

First, set up all you trees as you have already done it:

enter image description here

Hold all these trees in your ArrayList.

No seperate your game field in x rectangles of the same size (for example 3x5=15) and check which tree intersects with which region. Save these calculations in a suitable data structure. For example:

HashMap<Rectangle, ArrayList<Tree>> fieldSperation;

enter image description here

The white number whithin the trees indicate which Rectangle they intersect. It is possible, that one tree intersects with more than one Rectangle. Then you have to hold a reference in two or more lists (example 6/7 or 7/12).

Last you can adapt your checkCollisions() method as follows:

public void checkCollisions() {
    // 1. check which Rectangle intersects with the player (can be a maximum of 4)
    for (Rectangle r : fieldSeperation.keySet()) {
         if (playerRect.intersect(r)) {
             // 2. do your collision detection with those trees which are intersecting with those
             // trees which are intersecting with the rectangles from 1.)
             for (List<Tree> ts : fieldSeperation.get(r)) {
                 // your old code here
             }
         }
     }
}

I am pretty sure this technique will be enough to fit your perfomance requirements.

trylimits
  • 2,575
  • 1
  • 22
  • 32
  • Could I still use this method if the trees move –  Oct 30 '13 at 18:10
  • If a tree moves, you have to recalcualte its intersecting rectangles. So remove it from all the lists in which it is contained, then add it to the new corresponding lists. – trylimits Oct 30 '13 at 18:32
1

Use a spatial data structure for collision testing. With such a structure, you can reduce the number of tests by a large amount.

Two simple yet efficient structures for 2d would be the quadtree or a kd-tree.

A related question with links to a kd-tree implementation in java can be found here.

Community
  • 1
  • 1
Wilbert
  • 7,251
  • 6
  • 51
  • 91
0

Do not check for collisions in Swing event dispatch thread. Create a concurrent thread that does that and event thread simply assigns them to it. Reduce the amount of checked collisions by max only check on trees that are on screen.

user1633277
  • 510
  • 2
  • 7
  • 14
0

I just rearranged the code and it now works fine! Thank you to everyone who helped, i'm also sorry for posting this question many times...I'm new to this and didn't really know what I was doing. Once again thank you everyone you've helped a developer in need! Here's the new code:

for (int i = 0; i < Placing_Objects.Small_Trees.size(); i++) {
        if (gotAxeOn) {
            if (player.getBounds().intersects(Placing_Objects.getSmall_Tree().get(i).getBounds())) {
                Placing_Objects.Small_Trees.get(i).health -= rand.nextInt(3);
                }
        }
        if (Placing_Objects.Small_Trees.get(i).health <= 0) {
            Placing_Objects.removeSmall_Tree(Placing_Objects.Small_Trees.get(i));
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Wood");
            Inventory.addItemToInv("Stick");
            Player.exp += rand.nextInt(3);
            challenges.choppedDownTrees += 1;
        }
    }