I'm writing a 2d Top-down RPG using the LWJGL alongside with Java 1.6. By now, I have the rendering and input methods working fine and just started to program the game's logic.
So I have a class called World, which holds an ArrayList of Entities. I want to implement simple collision in the game (using intersecting squares), which should be no problem. The only problem I now have is how to access single cells of my List without having to iterate all over it. I have only been able to come up with collision methods which are executed inside each Entity and iterate over all of the entities in my World. That is not fast at all, but I really don't know what to do in order to make it faster.
My game is tile based, but the movement is not tile-to-tile, one can walk smaller portions, which avoids me to simply use a two-dimensional array...
Is there a standard way to handle entities and their collisions? (or maybe a way to handle collision between entities which are located inside an ArrayList?)
The standard way to handle colliding entities is by space partitioning. Your world is a 2 dimensional plane made of discrete points.
Each piece can be located on one of the points. The amount of the points determines the resolution of the plane- the more points, the better visual effect, the more calculations you have to perform. This is the trade off.
You can maintain a map between the location of an entity and the entity itself, where the location is represented by an object that overrides equals and getHashCode. The location object contains two members- the X and Y coordinates.
Note- you have to override in a proper and efficient manner.
So you you can access each entity very quickly if you know its coordinate, reshuffling is simply removing an entity and adding it with new coordinates (this can be optimized for locality) and collision detection is trivial- just check whether the same location is occupied by a certain entity.
I would also refer you to this question on SO.
Related
I'm trying to store a list of different Enemies. Each Enemy has an origin and can only spawn in its Location of origin. Each enemy also has a difficulty and should be stored with enemies of the same difficulty.
I imagined it as a static 3D array of Enemies like this:
Enemy[mountain][2][5] = new Enemy("troll")
Where the fields are (from left to right) Location, difficulty, index.
Each location the player enters will populate an ArrayList of Enemies from this static array.
Is there a more efficient data structure to use in this scenario?
(This list will be hard-coded and should not be altered during the course of the program)
edit-
I was hoping to optimize the access time. This game will generate a number of locations, each one needing to randomly draw Enemies from the list based on their origin and difficulty.
As per request, I will put some more thought into the use case of this program. Once I have a proper solution I will update. (Thanks)
It is conceptually wise not a good idea.
You really do not worry about performance at this point. You worry about creating a useful, helpful object model that allows you to write elegant, easy-to-read and easy-to-enhance code.
Using a 3D-array achieves none of these goals.
In other words: you step back; and think hard about the "use cases" that need to access your Enemy objects. And coming from there, you decide if you should go with different Maps for example; or different Sets, ... instead of using a 3D as central "storage point".
Edit, given your comment: there are two sides here:
Arrays are very inflexible in Java. You can't change their size dynamically. And beyond that, they are really "ugly" to use: this going through "3 dimensions" might be convenient for a certain "ascess path"; but it could make other things very hard (like when searching for a certain enemy, then you have to do this 3-dim iteration stuff ... as said: ugly)
One should try to make designs that are "open" for changes that have a high rate of "taking place". Example: you have a fixed number of enemies today; but assuming your "game" works out for you; you will sooner or later (rather sooner) want to enhance it; for example by allowing dynamic add/removal of enemies. Then a lot of the code you wrote using the 3-D array ... would become a real obstacle.
Beyond that: yes, in a "game world", there should be one component that is responsible for keeping track of all elements in the game. But: how this component internally organizes things is more of an implementation detail. You should focus on putting "helpful" methods on that GameWorld first; or as I put it before: understand the ways how your code will need to access/iterate/search enemies to perform the game itself. And then you look into data structures that support these "use cases".
Finally: assuming that this is a learning exercise - you can still start with a 3d array. It will teach you a lot; I am merely pointing out: you would not do that in a more "real world" application; and if you go for this option, you will soon be confronted with certain limitations/obstacles; just by the nature of your solution.
What comes to mind for me is a map. The location is the key and the value would be a List of objects that represents the enemy and its location - let's call it an EnemyLocation object that contains an Enemy and its location (or you could change Enemy to contain its location which seems like a good idea, but I don't know your code). So, when a player enters the "mountain" region, you do something like enemies.get("mountain") and you get back a List of Enemy objects (or EnemyLocation objects)
Explanation:
EDIT3: MASSIVE CLEAN UP as this was not clearly explained.
I'm trying to build up a 2D level out of tiles and entities. Where the entities are for example trees that can be cut. I need to store the data (how many chops are left for example) for each entity. I want them to have a more dynamic position (doubles) and a more dynamic sprite-width and height. My tiles are 32x32 pixels whilst my trees are not going to be one tile but a sprite with greater height than width.
I want objects that are closer to the top of the level to be drawn before the other objects. In this case a character behind the tree will cannot be rendered in or in front of the tree. This case also applies to other objects of the same kind (like trees).
I think it might be too inefficient to loop through the entities and calculate each entity's position since there may be a LOT of entites in the level.
As I've done some research I found that certain libraries allow the storage of both the object and it's position in a MAP (BiMap in google's Guava).
Questions:
Is this an inefficient manner.. but are there some changes that can
be applied to make the rendering more efficient (if so, what could be
optimized)?
Or is this an inefficient manner to render the entities and is
there a better way (if so, what other methods are there in Java)?
Or is there something else that I haven't listed?
EDIT2: I looked through the link I've posted in the edit below.
It seems that Google's Guava (I think that's all correct) has BiMaps. Is there an equivalent to this in regular Java? Otherwise Google's Library will probably be able to fix this for me. But I'd rather not install such a huge library for this one interface.
At last:
It's very much possible that the answer has been right in front of my nose here on StackOverflow or somewhere else on the internet. I've tried my best searching but found nothing.
If you've got any suggestions for search queries or any relevant links that might be of use to me I would appriciate it if you'd post them in the comments.
Thanks for taking the time to read through this/helping me ;)
EDIT:
I have looked at; Efficient mapping of game entity positions in Java .
I think it's narrowly related to this question. But I think it's just not what I'm looking for. I am going to look through the second answer very closely since that might be able to solve this for me.. but I'm not sure.
SOLUTION
The solution is to have an array, arraylist or another manner to keep track of your entities. Every tick/update you'll take all the object's Y coordinates and store them in another array/arraylist/map/other with the same size as where the entities are stored in. On every equivalent position to the entity you'll store it's Y. Then you'll order it with another loop or using http://www.leepoint.net/notes-java/data/arrays/70sorting.html .
Then when rendering:
for(int i = 0; i < entityArray.length; i++)
entityArray[i].render();
Off course you'll render it more efficiently by rendering only whats on or near your screen.
But that's basically how one does this in 2D top-view/front-view.
In my own 2d game attempts I come up with the following solution:
use an enum to specify different types of objects in game and give them priorities (sample order: grass, rivers, trees, critters, characters, clouds, birds, GUI)
make all visual objects implement interface which allows for getting this DrawPriority enum
use a sorted implementation of list with comparator based on the enum
use the list to draw all elements
That way the order computing is not very expensive, because it is done only on Visual Object insertion (which is in my case done while loading a level).
.. And since you will already using a comparator, do a x/y comparison when the enum priority values are the same. This should solve your y-order draw problem.
I'm trying to make a fully-automated game engine which needs to be working based on the events. The problem I'm facing is that I've made a map class and it's initialized in the game class. It's almost static and only one map exists for a game. New maps are loaded by clearing the objects in the current map and adding new maps. You can see the source of the map class here.
http://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/map/Map.java
The main problems comes in the collision detection, where I'm using the brute-force collision detection where I should not. This slows down the game a lot and I wanna check the collisions only for objects which are nearer to the object. I've been using the MapLoader interface to construct the maps. I'm thinking that calling the collision() method of the objects in another thread might help. How-ever it all the map objects are updated in the Game class.
Here's the game class if in case it might help
http://code.google.com/p/game-engine-for-java/source/browse/src/com/gej/core/Game.java
There's another problem that some-times, the objects aren't destroyed. I'm calling the map's removeObject() method but it takes a 1-second delay and some times wont remove at-all.
It gives me 48-64 fps in a platform game with 158 objects in the game. But in a space-invaders style game, it gives me only 20-30 fps. Any advice on optimization is greatly appreciated...
If anybody could get me a tutorial for binary spacing etc., I would be thankful.
Two suggestions by looking at your code: first thing is that you should try to minimize object allocation in collision detection, don't create new Rectangles, work on data you already have by writing directly the collision detection algorithm.
Second an more important thing: a collision detection engine should work by using two levels:
a coarse level of collision already excludes objects that are surely too far to collide (you can use many techniques here, like a binary spatial partition algorithm of big colliding blobs, or hierarchical structure of objects)
a fine level which will compute specific details for the collision that can occur, with more precise algorithms
I'm being really ambitious and working on a 2D Shoot 'em Up game that will have, hopefully, hundreds of entities running around.
What I'm having trouble wrapping my brain around, is how the bullet will detect when it makes a collision with an object, without it checking for every object on the map. The reason is that I feel that if I have four dozen bullets on the screen, each checking for collision with every entity on the map, every cycle, I will see some fairly significant performance loss.
So what would be the best way to detect for collisions without checking every single entity?
I can handle the collision algorithm when I have my two objects, I just can't seem to find a way to get those two object to see each other without checking everyone else first.
I'm working in Java and OpenGL with (soon to be textured) QUADS.
You should investigate quadtrees; they're often used for efficient 2D lookup.
I'm very new to Java and am not sure if I'm even allowed to ask questions of this nature here but I'll give it a shot. I want/need practice programming Java so I've decided on a rather large project that should be within my capabilities I've started building it and have created a player object with some properties like level,name,xp,health and items. The items are and array of 5 object objects (bear with me XD) now I'd like to know if I should create the rooms as objects as well or as seperate classes or functions?
The rooms will be only rooms in an abstract sense the game is fully text-based they will need to contain puzzles and objects a user can pick up or examine as well as enemies and such the narrative will also be contained in each one. The player will be able to "pick up" items in the room and add them to their inventory. As well as participate in textual comabt with enemies like : you hit monster for 2 damage, monster hits back for 3 etc.
Remember that this isn't going to be pretty it's for practice and I need to do it within Java.
Thanks in advance.
Your problem is related to the OOP concepts not to being a beginner in java, you should know more about OOP to think correctly before starting coding to put the correct OOP design for your program. since you are building this program in java you can start here.
For what I've understand from you question, you may want to have a Room Class, Containing the Room Properties and Functions.
From a high level, a good idea would be having a "Room" class, this would contain the Room Title, Description and any other room specific information (such as terrain type etc).
You could then create a multidimensional array of Room objects. One dimension being your X coordinate while the other your Y coordinate.
This way to "move" around all you need to do is track your location and either increment/decrement your X or Y based on the direction you moved.
You could extend it further doing something like generating a map of your surroundings as well. Each terrain type could be displayed as a different symbol (# for forest, ~ for water etc). It would be a simple approach to add something like this because all you need to do is get your top right/bottom left coordinate and loop through those coordinates building your map.