Yesterday I came across Craig Reynolds' Boids, and subsequently figured that I'd give implementing a simple 2D version in Java a go.
I've put together a fairly basic setup based closely on Conrad Parker's notes.
However, I'm getting some rather bizarre (in my opinion) behaviour. Currently, my boids move reasonably quickly into a rough grid or lattice, and proceed to twitch on the spot. By that I mean they move around a little and rotate very frequently.
Currently, I have implemented:
Alignment
Cohesion
Separation
Velocity limiting
Initially, my boids are randomly distributed across the screen area (slightly different to Parker's method), and their velocities are all directed towards the centre of the screen area (note that randomly initialised velocities give the same result). Changing the velocity limit value only changes how quickly the boids move into this pattern, not formation of the pattern.
As I see it, this could be:
A consequence of the parameters I'm using (right now my code is as described in Parker's pseudocode; I have not yet tried areas of influence defined by an angle and a radius as described by Reynolds.)
Something I need to implement but am not aware of.
Something I am doing wrong.
The expected behaviour would be something more along the lines of a two dimensional version of what happens in the applet on Reynolds' boids page, although right now I haven't implemented any way to keep the boids on screen.
Has anyone encountered this before? Any ideas about the cause and/or how to fix it? I can post a .gif of the behaviour in question if it helps.
Perhaps your weighting for the separation rule is too strong, causing all the boids to move as far away from all neighboring boids as they can. There are various constants in my pseudocode which act as weights: /100 in rule 1 and /8 in rule 3 (and an implicit *1 in rule 2); these can be tweaked, which is often useful for modelling different behaviors such as closely-swarming insects or gliding birds.
Also the arbitrary |distance| < 100 in the separation rule should be modified to match the units of your simulation; this rule should only apply to boids within close proximity, basically to avoid collisions.
Have fun!
If they see everyone, they will all try to move with average velocity. If they see only some there can be some separated groups.
And if they are randomly distributed, it will be close to zero.
If you limit them by rectangle and either repulse them from walls or teleport them to other side when they got close) and have too high separation, they will be pushed from walls (from walls itself or from other who just were teleported, who will then be pushed to other side (and push and be pushed again)).
So try tighter cohesion, limited sight, more space and distribute them clustered (pick random point and place multiple of them small random distance from there), not uniformly or normaly.
I encountered this problem as well. I solved it by making sure that the method for updating each boid's velocity added the new velocity onto the old, instead of resetting it. Essentially, what's happening is this: The boids are trying to move away from each other but can't accelerate (because their velocities are being reset instead of increasing, as they should), thus the "twitching". Your method for updating velocities should look like
def set_velocity(self, dxdy):
self.velocity = (self.velocity[0] + dxdy[0], self.velocity[1] + dxdy[1])
where velocity and dxdy are 2-tuples.
I wonder if you have a problem with collision rectangles. If you implemented something based on overlapping rectangles (like, say, this), you can end up with the behaviour you describe when two rectangles are close enough that any movement causes them to intersect. (Or even worse if one rectangle can end up totally inside another.)
One solution to this problem is to make sure each boid only looks in a forwards direction. Then you avoid the situation where A cannot move because B is too close in front, but B cannot move because A is too close behind.
A quick check is to actually paint all of your collision rectangles and colour any intersecting ones a different colour. It often gives a clue as to the cause of the stopping and twitching.
Related
I have about six dynamic bodies which have collision masks set so that they do not collide, however when they all overlap on screen for any length of time the frame-rate is dropping noticably. is this to be expected? I presumed that if the mask were set then they would not be checked for collisions and did not think this would happen? none of the bodies have bullet enabled.
I'm running the game on a samsung S3
If the bodies have a lot of fixtures and they are moving around, it might be due to the dynamic tree being restructured frequently. Although this particular group of fixtures may be set to not collide with each other, the tree still gets updated to let them collide with other things in the world. If the fixtures never ever need to collide with anything then it would be possible to optimize this by setting their mask bits to zero and not including them in the dynamic tree at all, but I guess this was not done because there is no point having a fixture that never collides with anything.
I have a flame ParticleEffect as the exhaust from a rocket. While the rocket moves slowly, the flame looks nice, but when the rocket starts moving very fast the flame can't really keep up because its particle speed is relative to the world and not the rocket. The result is blips that disappear from screen in parts of a second.
Can I update the emitter velocity during runtime, or can I set some kind of velocity point of reference to the particle effect (also during runtime)?
Thanks for any help!
It'd be a nice idea to encapsulate your particle effect inside an actor (like here).
Unfortunately the documentation is currently somewhat lacking, but you can always look at the source.
Now looking at that, the velocity value seems read only. So the answer to your question seems to be no.
But to fulfill your requirements, I'd suggest you to create 2 or 3 (or more) particle effects suitable for different velocities. (Much easy). Now you can change the entire effect during runtime.
Hope this helps.
So I'm doing the project of an introduction to Java course and it seems that I chose something that goes way beyond what I'm able to do. :P
Any help would be greatly appreciated. This is what I'm having problems with:
You have a cursor that is controlled by a player (goes forward or
turns 90°) which leaves a colored line as it goes. If you manage to go
over your own line and close a polygon of any shape (only right angles
though), its surface changes color into the color of your line.
I can detect when this situation arises but I am kind of lost as how to actually fill the correct polygon just closed. I can't seem to imagine an algorithm that would cover any case possible.
I looked at the Scanline fill algorithm but I think it would start having problems by the time there are already some polygons already filled in the map.
The Floodfill algorithm would be perfect if I had a way of finding a point inside the polygon, but, as there are many different possibilities, I can't think of a general rule for this.
I'm using an array 2x2 of integers where each color is represented by a number.
Does anyone have an idea on how to approach this problem?
If you can detect the situation then this can be solved in very simple manner. The question is which point to choose as start point for floodfill. The simple answer is: try all of them. Of course it makes a sense to start only with points adjacent to the one where your cursor is located. In this case you will have at most 8 points to check. Even better - at least 2 of them are definitely painted already if current point forms a polygon.
So you have 8 points to check. Launch floodfill 8 times starting from each of those points.
Two things which you probably should keep in mind:
You should try filling the area in cloned version of your field in order to be able to get back if floodfill will not find a polygon.
Launching floodfill second time and later you should reuse this cloned version of your field to see whether it was filled there. This will allow you to check every point at most once and this will make your 8 floodfills almost as fast as 1 floodfill.
Check this question, using Graphics2 and Polygon to fill an arbitrary polygon: java swing : Polygon fill color problem
Finding out whether a point is inside or outside a polygon: http://en.wikipedia.org/wiki/Point_in_polygon
Make sure you use double buffering. If you set individual pixels and don't use double buffering the component may redraw after every pixel was set.
I made a program in Java where circles can bounce into each other and gravitate towards each other.
For the most part (few circles on the screen), there are no noticeable bugs. The problem starts to happen when there is a large amount of circles on screen. Sometimes, the circles will overlap if it gets too crowded. It's as if the weight of all the other circles are crushing the circles together, causing them to overlap. Of course, there program doesn't know anything about how much a circle weighs, so it's not really crushing. Most likely, the piece of logic that handles resolving collisions is not able to handle crowded situations.
Circles are stored in an array, and each circle goes through the array using a for loop, comparing itself to the other circles. If the distance between the center of this circle and the center of the other circle is less than the sum of their radii, then the circles are colliding. The velocities of both circles are updated using an equation for collisions.
I think the problem occurs because if a circle is surrounded, it might receive an updated velocity into the circle behind it, while the circle behind it also receives an updated velocity into the former circle. In other words, the two circles get told to move toward each other, even though they are already touching. Once they overlap this way, I don't know why they don't undo their overlap.
I've tried restoring touching scenario if they are overlapping by finding the distance they are overlapped, then moving them apart from each other; each moves half the overlap distance apart. This doesn't change the circle's velocity, only their position.
This still doesn't solve the problem. If the circle is surrounded, and it overlaps with one of it's neighboring circles, its position is changed so they aren't overlapping, but this new position may cause it to overlap with another circle. Same problem.
If there was no gravity pushing the circles together, they would eventually spread out and resolve their overlapping issues, but the gravity prevents this from happening.
Further information:
Gravity is not taken into account when calculating new velocities after a collision.
Sounds like your hunches about what is causing the problem are correct in both cases.
Unfortunately, there's no easy way to fix this issue - it pretty much means rewriting your whole collision detection & resolution code from scratch. You have to work out the exact timing of the first collision, update everything only that far, resolve the collision (do your velocity update) then work out the exact timing of the next collision, then repeat...
Writing a good physics engine is hard, there's a good reason that there are many textbooks on the market about this subject!
The cheap 'fix' for your problem is to reduce the time interval for updates - e.g. instead of updating the physics in 33ms steps (~30fps), try updating in 16ms steps (~60fps). This won't prevent the problem, but it will make it much less likely to occur. Halving the time step will also double the time the processor has to spend doing physics updates!
If you use the cheap fix, the time step which will work best for you will be determined by how frequently collisions occur - more collisions means smaller time steps. How frequently collisions occur basically depends on how fast the circles tend to move and their population density (how much of a given area is filled by circles).
UPDATE: A little more info on the 'proper' approach.
The update would go something like this:
Start updating a frame. Let's say we want to update as far as time tF.
For every pair of circles, work out when you would expect a collision to occur (ignoring all the other circles). Let's call this time tC.
Find the smallest value of tC. Let's say this is for the collision between circles A and B, and let's call that collision cAB.
If tC <= tF, update all of the circles up to time tC. Otherwise, go to step 6.
Resolve collision cAB. Go back to step 2!
Update all the circles to time tF.
As you might imagine, this can get quite complicated. Step 2 can be quite tricky (and coputationally expensive) for non-circular objects (especially once you include things like angular momentum, etc.) although there are a lot of tricks you can do here to speed it up. It's also basically impossible to know how many times you'll be looping between steps 2 and 5.
Like I said, doing good physics simulation is hard. Doing it in real-time is even harder!
Im making small 2D game and i would like how should, theoretically work jumping and standing on objects.
For jumping should there be some kind of gravity?Should i use collision detection?
Good example of what i want to undestand is jumping in Mario.
I think for jumping it would be best to create some simple model which use "game time". I would personally create some physical model based on gravity, but you can go for whatever you want.
If you want your character to "stand" on object, you will have to create some collision detection. Good start is to approximate object by one or more circles (or lines) compute collision of them and in case the approximation collides determine the final state by some more precise method.
In terms of should there be gravity and collision detection - personally for such a thing I'd say yes and yes! It doesn't have to be complicated but once you have those things in place the pseudocode for the "main loop" becomes relatively simple:
if not colliding with object underneath, apply gravity
if user presses jump key and not colliding with surface //i.e. if we're in the air already, don't jump again
apply upward velocity
That is of course oversimplified and there are other corner cases to deal with (like making sure when you're coming down after jumping, you don't end up embedded or potentially going through the floor.
You might want to take a look at Greenfoot which handles a lot of things like all the Java2d stuff, collision detection etc. for you. Even if you don't stick with it it'd be a good platform for building a prototype or playing around with the ideas talked about.
Standing on objects implies collision detection, you can approximate the characters and the environment objects with primitive shapes (rectangles, circles etc.).
To check if to shapes are colliding, check axis one by one (X and Y axis in your case). Here is an explanation of the "separating axis theorem" (Section 1).