Collision detection between ball & maze made dynamically from text file - java

Ok so I am creating a ball tilting game, where you navigate a ball around a maze. The ball works, and is all good in the area however I am having some problems in the maze.
The maze is programmatically created through a .txt file that contains 1's and 0's (1's being walls, and 0's being floor.) I have a for loop that goes through the whole .txt file and places a white(wall) or black(floor) square at the proper coordinates on a canvas. This is similar to the apps-for-android Amazed game if you have seen it link. However, instead of placing wall-type detection on his tiles, he just resets the game and deducts a life point if the user rolls onto a 'void' tile.
However I am looking to have 'walls' and not 'voids'. Where if the ball touches the wall, it doesn't go beyond that point, but can still move freely on the other axis. Unless it hits a corner, of course.
The problem I am having is actually creating this detection. I have tried a number of ways but nothing so far has been successful or useful.
I have tried:
- Have an ArrayList of all of the coordinates of the wall tiles, and every game tick, it checks to see if the ball is touching one. However this just slowed the game down to a crawl and was just extremely terrible.
- Check to see what tile the ball is on, and if it's on a wall tile, to stop it on an axis but let it move freely on the other, however this still didn't work as there were some issues when the ball was to the right of the wall tile, but also under it, it couldnt move up, as the code detected it being under the ball.
And a few other ways but I really cannot remember! It's been a bit hectic.
So, I am asking, if anyone has any experience in this area could they please give me a push in the right direction? Im hoping to have the maze walls sorted by Tuesday however it's looking grim!
If you need any more information, please ask.
Thank you in advance for any and all replies.

Instead of having an ArrayList that you have to iterate over, why not store the maze the same way you do the text file? Use a 2D boolean array filled with true for wall and false for floor, or vice versa.
This simplifies finding a wall considerably. All you have to do is figure out where in your grid the ball is. Then you can just check the cells immediately surrounding it. Even if you include diagonals(which probably isn't necessary for an all-90-degree maze), this equates to checking 8 booleans from an array, basically instant.
As for the axis issue, just stop movement in that direction. No need to freeze a whole axis. For instance, if the wall is right of you, just don't allow x to go higher. No reason to not let it lower unless there's a wall to the left.
This is just a general idea, though. Since it's homework, no code for you ;)
Edit:
The 2D array is just that, a boolean[][] which holds true in each of the spots where you want a wall to be. When you read in your text file, just assign it straight away.
Assuming each line in your text corresponds to an y row, and each 0/1 is the x for that column, when you read a 1, assign map[x][y] = true.
I'm honestly not sure what else you need elaboration on. It's a common format to do simple tile-based maps, though. If you google "2d array tile map", you'll find several resources to help with it.

Related

Java more efficient array searching

I am coding a game using LibGdx and I have an array with all of my wall objects that the player can collide with. For those who don't use LibGdx, I am talking about LibGdx's Array class which provides the same functionality as an ArrayList but it's built with memory efficiency in mind. When I check for collision, I am having to go through every wall in the array and check for collision like this:
for(Wall w : walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
I realized this was inefficient because I am going through every wall even if that wall is off the current view of the map. Obviously, if I am checking for collision with walls currently in the camera's viewport (this means they are currently visible by the player) then there is no point in going through the whole array because the player can't collide with them until they come into view. I was thinking of making my game a bit more efficient by only checking for collision with walls close to the player. In my game, I have all of the walls snapped onto a grid with cells 32x32 px. I really don't know how I could create more efficient searching for collision. Could I use like a map of some sort which uses a vector2 position for its key and then look up the player's position and look through walls within a certain range from the player's position in the map? I am just really lost on how to have code that won't go through all 100+ walls in my game when there are only 10 current possible walls that the player could touch because of where it currently is. Does this make any sense? Could someone explain a good way to do something like this? Thanks so much.
There are lots of collision alghoritms out there, you will need to find one that suits your need.
One solution I can think of on the top of my head is:
Keep your wall list sorted on their coordinates. If you create a new wall, use insertion sort to resort your array. When you want to check for collisions, take the objects coordinates (in this case probably the player that is running) and do a binary search to find the closest wall to the player. Then calculate if the player and this wall collides. If the closest wall isn't causing a collision, you can be pretty confident that no other wall is as well.
Each wall is on one or more of these 32x32px grids. Let the coordinates of a grid be x and y. If a grid contains a wall, enter this into a
HashMap<CoordPair,Set<Wall>> xy2wall
To investigate where a location is in contact with a nearby wall, use the coordinates of the location to determine a small set of grid coordinates, fetch the set or sets of Walls mapped by these CoordPairs. I guess the Player.bounds() can provide a suitable set of coordinates.
If the 32x32 grid results in too many entries, you can always use a coarser grid.
I once came into the same realization that you have while developing a top down rpg.
There are more walls than you can imagine in a top down rpg.
Here is how I solved it:
First: Segment the map into zones ie.) draw your map on paper or something and cut it up into parts.
Second: Record the pixel boundaries for each segmented section of the map.
Third: Check where your players location is with respect to the boundaries.
Finally: Only check the walls within those boundaries.
In a realm of infinite walls this is not any more efficient (speaking about Big O) but for all practical purposes this is effective in cutting down on lookup times
if (boundary1.contains(player1)) {
for(Wall w : Boundary1Walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
}
else if (boundary2.contains(player1)) {
for (Wall w : Boundary2Walls) {
if(w.bounds().contains(player.bounds()) {
// handle collision
}
}
}
....
Continue in this fashion
Take note... I did it like this before going to college for software development, so I did not make use of data structures such as BST which could be used to store walls with respect to their coordinates. Making your lookup time extremely fast.

Let an Enemy follow a path with the same speed

I started programming a game in java. I have Enemys and a Player, a basic 2D game, thats to get experience for the first time.
Now i wanted the Enemys to follow a path, which i can draw in to a "level editor".
I have a JPanel, a mouseMoveListener, and on click the Path2D starts saving the mouseMove Points to a Path2D.Double Object.
After that, i implemented the following method to make the enemys following this path:
public void forward(){
if(!pathIterator.isDone()){
pathIterator.currentSegment(current);
x = current[0];
y = current[1];
pathIterator.next();
}
else {
dead = true;
}
}
I think its clear what happens now: The Enemy is following, but the speed is that i moved the mouse with. So if i move to Mouse to fast, the enemy just.. "jumps" from one point to an other. To slow, its "sneaking" over that points. (And because im not an Robot, i cannot move the Mouse with the same speed ^^)
Talking of Robot: Yes, i could let a awt.Robot move my Mouse. But this isnt really possible too, because i have to draw complicated paths, which dont have any visible mathematics behind.
So, i want let this Enemys to move on this path with the same speed. My Problem: I don't know where to implement a "fix". I have 2 Ideas:
Maybe i could work on the Path creation: Instead of just adding the Points to the Path2D, maybe i could calculate points between the points where i moved to fast, or deleting points which are to near by each other. But: First, I don't know how to calculate this, (Is there any maths logic to achieve this?) And Second, when i do this i probably would'nt be able to change the speed of the enemys ingame, and that would be bad
The second idea i have, is to calculate the points between (oder the points to jump over), this should happen every frame, relative to the actual speed. But here im not experienced enough in maths to.
So, are that ways possible, and if yes, has someone an idea how to calculate this?
And, if not, what other possibilitys i have to achieve this?
Thank you, and sorry for the bad english!
All you need to do is define the speed of movement of the enemy inside the enemy class.
When it works out the next point to move to then create a direction vector by subtracting the current position from the new position.
Normalize the direction vector (so it is length 1) then multiply it by the speed and the tpf (time per frame).
Move by that amount instead of jumping to the next point.
(Note if the points are very close together or the framerate is low this can cause it to overshoot a bit, it should be fine though).

collision & touch + shoot methods for Android

I really need help. I am making a game app for my final year project. It is a simple game where you have to shoot a ball into a target by rebounding of walls or angled blocks. However i need help in 2 areas:
the shooting mechanism is similar to that of stupid zombies. There is a crosshairs where you touch on the screen to indicate which direction you want the ball to be shot at. On release the ball should move into that direction and hopefully gets into the target and if not gravity and friction causes it to come to a stop.
The problem is how do I code something like this?
I need the ball to rebound of the walls and I will have some blocks angled so that the ball has to hit a certain part to get to the target. The ball will eventually come to a stop if the target is not reached.
How can I make a method to create the collisions of the wall and blocks?
I have spent the last weeks trying to find tutorials to help me make the game but have not found much specific to the type of game I am making. It would be great if sample code or template could be provided as this is my first android app and it is for my final year project and i do not have much time left.
Thank you in advance
akkki
Your question is too generic for stack overflow no one is going to do your project for you. Assuming you have basic programming experience if not get books and learn that first.
Assuming you already chose Android because of your tag, and assuming 2d game as it is easier.
Pre requests:
Install java+eclipse+android sdk if you havent already.
Create a new project and use the lunar landar example, make sure it runs on your phone or emulator.
Starting sample:
The lunar landar has a game loop a seperate thread which constantly redraws the whole screen, it does this by constantly calling the doDraw function. You are then supposed to use the canvas to draw lines, circles, boxes, colours and bitmaps to resemble your game. (canvas.draw....) Lunar landar does not use openGL so its slower but much easier to use.
Stripping the sample:
You probably don't want keyevents or the lunar spaceship!
Delete everything in the onDraw function
Delete the onKeyUp, onKeyDown
Delete any errors what happen
Create a new
#Override
public boolean onTouchEvent(MotionEvent event){
return false;
}
Run it you should get a blank screen, this is your canvas to start making your game... You mentioned balls, break it down to what a ball is: A position and direction, create variables for the balls x,y direction_x and direction_y the touch event will want to change the balls direction, the draw event will want to move the ball (adding the direction x,y to the ball x,y) and draw the ball (canvas.drawCircle(x,y,radius,new Paint())) want more balls search and read about arrays. Most importantly start simple and experiment.
2 collisions
Collisions can be done in the dodraw function and broken down to: moving an object, checking if that object has passed where it is supposed to go and if so move it back before anyone notices.... There are many differently techniques of collision detection:
If your walls are all horizontal and vertical (easiest) then box collisions checks the balls new x,y+-radius against a walls x,y,width and height its one big if statement and google has billions of examples.
If your walls are angled then your need line collision detection, you basically have a line (vector) of where your ball is heading a vector of your wall create a function to check where two lines collide and check if that point is both on the wall and within the radius of your ball (google line intersection functions)
or you can use colour picking, you draw the scene knowing all your walls are red for example, then check if the dot where the new ball x,y is, is red and know you hit
Good luck, hope this helped a little, keep it simple and trial and error hopefully this gets you started and your next questions can be more specific.

Efficient algorithm for collisions in 2D game?

I'm programming a Bomberman in Java following a tutorial (this is my first game).
The tutorial suggests the following code for detecting collisions.
for (int p=0; p<entities.size(); p++) {
for (int s=p+1; s<entities.size(); s++) {
Entity me = (Entity) entities.get(p);
Entity him = (Entity) entities.get(s);
if (me.collidesWith(him)) {
me.collidedWith(him);
him.collidedWith(me);
}
}
By now, entities is an array list containing the enemies and the player.
As I want to also detect the player collides with walls, should I put every single wall or bricks tile in the level into the entities arraylist? If so, isn't this algorithm very inefficient? These tiles aren't going to collide with other tiles, so I was thinking to manage game entities in different lists. What do you suggest? Is there a more efficient algorithm to do it?
Note: I already read other questions related to collisions in 2D games.
Thanks a lot.
I suggest reading this excellent article about how ghost movement and collision detection works in PacMan.
Then I would suggest logically modeling your Bomberman levels as a collection of tiles. Each tile represents a discrete position in your level, and it is not logically possible to ever be "between" tiles or occupying two tiles at the same time. Each tile can track what sort of terrain feature is currently on it, and whether or not it is a valid destination tile for the player (and the enemies, potentially with different rules for each if the enemies are allowed to traverse terrain that is normally impassable for the player).
Then you don't need a collision detection algorithm for every object in the world. When it comes time for an enemy to move, or when the user tries to move their character, all you have to do is check all the tiles that are adjacent to their current tile (4, or 8 max if you allow diagonal movement), see if each tile represents a valid movement direction, and block the movement if it is not in a valid direction.
And to answer your question, yes, iterating every object in the world on every position update will be very inefficient.
There is another way to use grids for collision system. I'm using more complex version of the Aroth's suggestion and using this to fix collision bugs.
Theoretically this system is the fastest(assuming you are doing this check if(Grid[x][y] ==true)) because it only uses a single Boolean check for each entity(the things that can move).
Note: In the above grid check example, I've used a 2 dimensional array of booleans that sets the coordinates of impassable grids to false.`
If you are not worried about physics like bouncing from a wall you can use this:
1- Divide the map into grids.
2- Making every entity only fill a tile would be better but not necessary.
3- Store the previous position or the grid of the entities.
4- Whenever an entity moves, before visually updating their location (also before
doing other calculations) check the grids they are in. If they are in grid
that is not empty or simply in a grid that they are not supposed to
be, return their position back to the previous position (which you have stored).
If you want to allow entities to move freely inside the grids(the grids are bigger than the minimum distance they can move) then you need to put them adjacent to the grids they've entered and they weren't supposed to. Otherwise just return them back to the previous grid.
If you want them to bounce from the wall you can still use this but I'm not sure how many features can be added to a collision system like this.
May I recommend my own project. But it's still wip.
https://github.com/YagaoDirac/Dirac-2d-collision-detection-for-games
It's based on quad-tree which handles sparse pretty well.
It supplies collision group. This conception is also used in both UE and Unity.
It support only circle vs circle and overlapping only for now(2022 feb 22).
I plan to make at least AABB, and collision which at least stop your pawn from leaving the map.
I may also provide another system based on fixed grid.

Pacman maze in Java

So I'm building the pacman game in Java to teach myself game programming.
I have the basic game window with the pacman sprite and the ghost sprites drawn, the pacman moves with the arrow keys, doesn't move beyond the walls of the window, etc. Now I'm trying to build the maze, as in this picture:
Without giving me the direct/complete solution to this, can someone guide me as to how this can be built? I'm talking only about the boundaries and the pipes('T' marks) here which you can't go through and you have to go around. Not the dots which the pacman eats yet.
Here are my questions:
1) What's the most efficient algorithm/method for creating this maze? Will it have to be drawn each time the paint() method is called or is there a way to draw it only at the start of the game and never again?
2) How will this actually be drawn to the screen? I assume the fillRect() will be used?
3) Any hints on collision detection (so the pacman/ghosts can't go through the walls) would be helpful.
4) Any hints on how the vacant space between the pipes will be calculated so the dots can be filled between them will also be very helpful.
Thanks
I wouldn't do it that way.
I'd draw the graphical map and then create a 2D data array which represents the map. The data map would be responsible for determining collisions, eating dots, where candy is and where the ghosts are. Once all the logic for everything is handled just use the 2D array to display everything in their proper pixel coordinates over the graphical map.
For example the user is pressing the left key. First you determine that pacman is at element 3, 3. Element 3, 2 contains information denoting a wall so you can implement the code to make him ignore the command.
EDIT:
Each element would represent about where a dot could be. For example:
No, looking at the board I would say the array would look something like this.
d,d,d,d,d,d,d,d,d,d,d,d,w,w,d,d,d,d,d,d,d,d,d,d,d,d
d,w,w,w,w,d,w,w,w,w,w,d,w,w,d,w,w,w,w,w,d,w,w,w,w,d
p,w,w,w,w,d,w,w,w,w,w,d,w,w,d,w,w,w,w,w,d,w,w,w,w,p
d,w,w,w,w,d,w,w,w,w,w,d,w,w,d,w,w,w,w,w,d,w,w,w,w,d
d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d,d
And so on. You might want to pick a more flexible data structure than just characters however since some areas need to contain a bunch of different information. IE even though the ghost spawning area is blank, pacman isn't allowed in there. The movement of the ghosts and pacman is different for the side escapes, the candy spawn point is a blank spot but if you want to remain flexible you'll want to denote where this is on a per map basis.
Another thing you'll want to remember is that pacman and the ghosts are often inbetween points so containing information that represents a percentage of a space they're taking up between 1,2 and 1,3 is important for collision detection as well as determining when you want to remove dots, powerups and candy from the board.
You can paint the map into a BufferedImage and just drawImage that on every paint(). You'll get quite reasonable performance this way.
If you are happy with the walls being solid, you can draw each square wall block with fillRect. If you wish to get the same look as in the picture, you need to figure how to draw the lines in the right way and use arcs for corners.
The Pacman game map is made of squares and Pacman and the ghosts always move from one square to the neighbouring square in an animated step (i.e. you press right, the pacman moves one square to the right). That means that collision detection is easy: simply don't allow moves to squares that are not empty.
I do not understand what you are trying to ask here.
1) Just to give my advice on redrawing. Something that you can do if you find redrawing the entire image is slow, is determine only the elements that have changed on the screen and redraw those. An approach for this would be the following: Determine the sprites that have moved. Determine (approximate) a rectangle around those sprites. Redraw those rectangles only. This way you are only refreshing parts of the screen and not the whole screen. This should result in an increase in performance over redrawing the entire screen.
The other answers have been reasonable for the other questions you have asked.

Categories

Resources