LibGDX Collision scoring system increases continuosly - java

I am developing a game. When my main character intersects with a star(point), I should get 1 point.
I used Intersector.overlaps but when both are intersected, score is increasing continuosly until they don't touch each other. How can i fix it? I initialized int score = 0, and here my collision code,
(starAvailable = I am removing star from screen after collision. Not an important thing for scoring.)
if (Intersector.overlaps(charCircle,starCircles1[i])) {
starAvailable1=false;
score++;
}
For example, when i intersect with a star, score is becoming like this

(starAvailable = I am removing star from screen after collision. Not an important thing for scoring.)
It is actually important. The easiest and most efficient way you have to do this is to remove (or move away out of the visible field, disable... whatever you are doing to save memory) the star straight before or after changing the score, so make sure you will not trigger further collisions. There is not enough code to know how to do it in your project, but something like...
if (Intersector.overlaps(charCircle,starCircles1[i])) {
//starAvailable1=false;
removeStarFromField(); // we disable the collider, stop rendering,
// or remove the star
score++;
}
As a less effective alternative, but which may be more accessible if you have not a lot of experiece with LibGdx, and if your star has some sort of unique identifier or you can add it to it, is you could store which stars you collided with (or if you already collided with one specific star, if you are caching them). Once you collide with the star, you cache that identifier. You then should check the id fromt he star you hit against your cache, and if it's there, you shouldn't increase the score, something akin to:
// somewhere else...
Set<String> identifiersFromAlreadyHitStars = new HashSet<>();
....
// then your actual collision detection method
if (Intersector.overlaps(charCircle,starCircles1[i])) {
if(!identifiersFromAlreadyHitStars.contains(hitStar.identifier){
score++;
identifiersFromAlreadyHitStars.add(hitStar.identifier)
}
}

I solved it by adding starCircles[i].setX(1500).
if (Intersector.overlaps(charCircle,starCircles1[i])) {
starAvailable1=false;
starCircles1[i].setX(1500);
score++;
}
Stars are coming continuosly and updated in each loop, so circle's setX value is updating again after looping.
Now score is increasing by 1 for each star collision.

Related

How does terraria have so big worlds and still has silky smooth fps?

I was working on my own procedural generator and finished making it.
Here is how I did it,
generate the entire world at the beginning,
store info about spawn positions and tiles positions into arrays and data structures
Now obviously, I have to loop through all the arrays, to render/update stuff,
this is creating problems,
I tried dealing with this problem by applying a condition that if any object is visible, only then render update else don't, but it does not make much of a difference.
my TILE_SIZE is 1 world units
so when my world size was
a)500 by 500,fps was 60
b)2000 by 2000, fps was 50
c)5000 by 5000 fps decreased further and so on
If only I could know how Terraria does it, or any way it done, would really help thanks.
I have to loop through all the arrays, to render/update stuff
You don't have to do that.
For rendering stuff you really only need to consider the blocks that are close to the player. Here is some code(x, y are the player coordinates, width, height are the dimensions of your world, render(x, y) is a placeholder for your rendering functionality, and for simplicity I assumed the player can see 100 blocks in each direction):
for (int i = Math.max(x-100, 0); i ≤ Math.min(x+100, width); i++) {
for (int j = Math.max(y-100, 0); j ≤ Math.min(y+100, height); j++) {
render(i, j);
}
}
The process of updating can also be simplified:
For npcs you only need to check a few blocks around it.
For block updates(liquid flowing, sand falling, corruption spread, …) there are actually two possibilities:
Iterate through a different part of the array each update:
Block updates don't have to be that frequent. For fluid flow it might be good enough to update only every 50th block in each update.
You can store the blocks that might need to be updated in an ArrayList(I suggest storing only the coordinates, not the blocks itself).
Then when the update function is called you go through that list and check wether the block really needs an update. If that's the case, you add the blocks neighbors to the list, which will then get updated in the next iteration.
Make sure to remove the blocks you just updated from the list and avoid adding duplicates!
While the second approach is normally faster(ususally the list is only determined by player actions and even if the player decides to drain the entire ocean the whole list would probably take less than ¹⁄₂₀ of the entire world).
But the first approach is certainly easier to implement and will be faster if for whatever reason you have lots of block updates.
Anything you do not see on screen is stored as values. This means that all tiles that are not visible in your viewbox do not get rendered. They are stored as objects (e.g. {x, y, type}); Make sure you count how many tiles are on screen VS how many you are rendering each loop in your code. Never render something that is not visible to the user as this will eat up your memory.
Any tile groups that cannot be rendered soon (i.e. by moving left/right) are not looped through. So say you are using tile sectors to group your tiles, and you're in sector D. Moving left will put you in C, and moving right will put you in E. So these sectors should be loaded in to arrays (but not rendered) There is no need for you to loop through any other sectors (e.g. A or B). So these can be stored externally (e.g. as text files). So they are available, but not taking up space in your games memory.
Good luck. :)

libgdx how to detect collisions?

I have a Problem to detect collisions. I'm using TiledMap and created a virtual joystick, so that its possible to move in every direction not just left, right, top, bottom. The Point of View is directly 90 degrees from the top.
I don't know if that's the purpose of a TiledMap, but I thought the maps are easy to create. But now I 've got Problems with the collision detection. Since the map is not arranged like a chessboard, for example, I need to check the whole Sprite for collision. Can you please explain me to how that works?
Thank You
First of all I recommend you to checkout this question to clear up some things, and to get a basic Idea how collision detection works with TiledMaps.
Summarized: Using a TileEditor you can add different layers to your TiledMap. One of theese layers can be a object layer which can be used for collision. For how to create and access the layer please checkout the linked question.
For your example there are some central questions which needs to be cleared out first:
Which shape and size do the colliding objects have?
Can the objects move in between two tiles?
What should happen on collision?
Pokemon is a super easy example. The Player has the size of exactly one tile and can not move in between them. If there is a collision the player just can't move.
If that is what you want you can just add a check before moving any object: If the next tile isn't valid just don't move the object. For the collision check you can just adapt the example code from the first answer.
On the other end of the specturm you could have different shaped objects with differnt scales which have a dynamic velocity and should bounce of the objects on the TileMap. In that case it could be clever to use box2d for collision detection like in this answer.
So depending on your needs just try to adapt any of the answers I linked. Maybe just start with a super simple box collision try to extend your code.
use this method
void isCollition(Object x, Object y) {
Boolean collide = false;
if (x.getX() + x.getwidth() < y.getX() + y.getWidth() ||
x.getY() + x.getHeight() < y.getY() + y.getHeight() {
collide = true;
}
return collide;
}

Calculating collisions, taking into account velocity

I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:
I wasn't sure whether this question should be here or in the game dev site.
I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.
Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })
I then multiply the momentum by 0.15. This is so that it slows down.
After this, I multiply the velocity by 0.8.
Then, I add the momentum to the velocity, to increase the velocity, as
this is what actually moves the player.
I then add the velocity to the position of the player.
To apply the gravity, I add a gravity vector (0, -10) to the position of the player.
So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it. But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.
TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?
This answer gives a good overview about the details of collision detection:
https://gamedev.stackexchange.com/a/26506
However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.
That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.
EDIT:
Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like
for (int i = 0; i < 10; i++) {
newPosX += deltaX * 0.1; // 1/10th of the usual update
newPosY += deltaY * 0.1; // 1/10th of the usual update
if (checkCollision(newPosX, newPosY))
{
posX = newPosX;
posY = newPosY;
}
else
{
break; // We hit something, no more mini-updates necessary.
}
}

how to efficiently code the spawning and collision detection of a large amount / multiple enemies in java

I got some difficulties because i dont know how to code efficient.
I'm creating a vertical scrolling shooter & i wanna spawn a large number of enemies.
At certain y-coordinates of the map & give them a certain x coordinate.
If been doing testing this with a couple of enemies and in my Enemy-class the code i'm using now looks like this:
if (Background.bgY == -3972 && active == 0) {
active = 1;
type = 1;
centerX = enemyXstart4;
KnightmareGame.activated = 1;
KnightmareGame.activatedatY = Background.bgY;
}
Which basically looks for if the scrolled background is at coordinate Y, activate an enemy(bomb) of type 1 and give it starting coordinate centerX, activatedatY.
This means that for every single enemy im writing this block of code...
Then in my KnightmareGame Class (which holds the routine where the enemies get drawn on screen) i'm drawing every enemy manually, which looks osmething like this:
g.drawImage(currentBomb, bo1.getCenterX(), bo1.getCenterY(), this);
g.drawImage(currentBomb, bo2.getCenterX(), bo2.getCenterY(), this);
g.drawImage(currentBomb, bo3.getCenterX(), bo3.getCenterY(), this);
And in my collision detection method Im also checking every enemy 1 by 1:
if (projectileRect.intersects(KnightmareGame.bo1.bombRectangle)) {
visible = false;
if (KnightmareGame.bo1.health > 0) {
KnightmareGame.bo1.health -= 1;
}
if (KnightmareGame.bo1.health == 0) {
Enemy.animateFire= true;
etc., etc.
The problem is that the total amount of enemiess i exceeds 50, so if i would continue coding them 1 by 1 the code would get real messy.
What i was thinking of was that I might make an array list of all the y coordinates where i wanna spawn enemies with their subsequent x coordinate.
For example at -3900 i wanna spawn an enemy at x coordinate 200. At -3800 at x coordinate 300, etc. So an array list where every position holds 2 variables (x,y)
I just dont know (first of all) how to code for this array list.
And second. I have got no clue of how to automate my draw method like
g.drawImage(currentBomb, bo1.getCenterX(), bo1.getCenterY(), this);
I'm thinking of a loop, but dont know how the code...
Collision detection: here i also collision detect in ONE block of code for every enemy instead of compare every enemy in a single seperate block of code with my projectile.
Does any1 know how to do this? Or maybe if I should do it differently then what i'm thinking of right now?
Help will be very much appreciated!
Handling multiple enemies
Create an ArrayList<Enemy> enemies;
Then use
for (Enemy bo : enemies) {
// logic for each enemy.
}
Don't forget to remove old enemies after destroying or going out of screen.
Don't keep creating new objects every time. Use a object pool for efficiency.
Improving collision efficiency
For large number of entities to be checked for collision, generally a broadphase algorithm is used.
See if it is required in your case.
You might also try some spatial optimizations like quad-trees.
These might just be wiki links, but I suppose you can search further if you know what to search for.
Hope this helps.
Good luck.

Java Collision Detection Not Working

I have made threads in the past about similar questions but because of my lack of detail the answers have not really been related to what I needed so I am going to try explain my question in as much detail as I can and hopefully it will be easier for you to understand what I require.
I watched Bucky's slick game tutorials on youtube and made a 2D Java game, the game is basically a 2D player viewed from above (birds eye view) can move around a 2D map with user key input (up, down, left, right). The map the player moves around is very small so that meant boundaries had to be set so that the player could not walk off of the map, to give you a better idea of how this was done, here is the tutorial for setting up the voundries:
http://www.youtube.com/watch?v=FgGRHId8Fn8
The video will also show you exactly what the game is like.
The problem is, these boundaries only require one axis meaning that if the player is walking down you say something like "if player gets to the coordinate (number) on the X axis change the player movement to the opposite direction so that he can not go any further."
Now this creates a problem for me because this only requires one axis so it easy to set up and understand but if you look on the video, on the map there is a house and I want my player not to be able to walk over that also but this deals with 2 dimensions, I have looked at things like rectangle collisions and have seen things relating to them in the other posts but I get confused because I am new to Java and havent really done much with it at the moment apart from watching Bucky's tutorials.
My code at the moment for my game class has got the following methods: init, render and update. So to sum it up I really just want to set up a way of not letting my player walk through the house, I will mention also (I should have mentioned it in my other threads) as I am very new to Java, could you please take a step by step method of showing me how to set up the collisions, I mean even the basics of things like making the rectangle if required.
If my code is required please tell me and I will post it as soon as possible.
Thank you in advance.
You can set up the board as a 2x2 grid of a class that has has property such as 'isBlocked'. By default the edges of the board would have this property set to true to prevent the character from walking off the edge. When you add other obstacles such as a house or a wall the grid position(s) the object occupies would also have the property set to true. Then when moving a character you just check if the grid position the character moves to has the property set to false to see if it's an allowable move. This also makes it quite trivial to save the level data so you can just load them from disk later on.
Two possible options:
Extend Shape or Rectangle or the relevant Slick objects (they should exist IMO) and just check for intersect()
Look for (x1,y1) and (x2,y2) values such that it starts outside and ends up inside.
Assuming you have intersect() methods:
//Grab the previous position
prevPosX = movingobject.X;
prevPosY = movingobject.Y;
//Update the position
movingobject.update();
//Test for collision
if(movingobject.intersects(targetobj)) {
//If it collided, move it back
movingobject.X = prevPosX;
movingobject.Y = prevPosY;
//And reverse the direction
//(might want to do other stuff - e.g. just stop the object)
movingobject.speed *= -1; //Reverse the speed
}
in this case your update class should also add one more condition to look for the house. let say the cooridnates of house(assuming rectanglular house here for other shape just change x and y values) are (x1,y1)(x1,y2)(x2,y2)(x3,y1) you have to add a condition to make sure
x value is not between x1 and x2 and at the same time y value cannot between y1 and y2.

Categories