I love you guys !!! ;D
Here’s what I’ve done till now:
http://www.martialartsmovies.net/2dballer/2DBaller.rar
java -cp . render.Baller
Ok, so here’s the full history:
-
First I had a normal gravity environment with balls bouncing of the floor and of the walls with full force.
-
Then I wanted to display a background Image (2000x600) that would also define the world size. The area displayed would be limited to 800600.
Here comes my FIRST MISTAKE: I used a DoubleBuffer System with a BufferedImage of size 2000600 and then only displayed the small part on the actual Panel. This gave me horrendous performance. The mistake was the entire background beeing drawn on the bufferedimage at each repaint() even if the bufferedimage was actually never entirely drawn onto the panel. I then changed the size of the bufferedImage to the size of the screen (800, 600) and only draw the part of the background that was displayed onto this bufferedimage. This made my CPU go from 70% to 10% on a Pentium 4 - 2,8 GHz
-
Then I added the actual Map. I wanted it to be a normal graphic with magic Pink (255,0,255) and the magic pink would be replaced by transparency. This went quite well, the only mistake was that at first, I used:
BufferedImage buffi = ImageIO.read(sth);
and believed this would be a good Type of BufferedImage. I quickly detected the mistake and created the BufferedImage first with type BITMASK (thanks to oNyx) and draw the picture loaded into a temporary bufferedimage onto the buff created. Then i used some per pixel manipulations to replace it with 0,0,0,0. I also had some problems with the JPG format which always had an alpha of -1 … now I use .gif but I don’t see why JPG wouldn’t work now. Just need to pay attention to the order alpha, r,g,b or r,g,b,alpha. (Question: does JPG have 32 bits so does it contain the alpha or does it encode with 24 bits ?)
-
At the same time, I created a boolean[][] for the collision map and loaded true or false into it depending on magic pink found or not. (Question: is boolean 1 bit or why do people often use int[][] instead of boolean[][] for collision map?)
-
Now I wanted my terrain to explode. I used a MouseListener and wrote a method addDetonation(x,y,radius) and draw an Oval on the Map bufferedImage as well as changed the values in the collision map. This went really good and I progressed really well.
-
Now came the hard part…It took me and my friend 4 hours +/- to complete and we are very proud of it. We know that it contains still bugs but we don’t care. It is really more than we expected and for the worms clone I want to create, is more than enough.
We actually wrote a collision detection system that maked the balls bounce on the map surface, regardless of it’s form, in the correct physical way (with angles and stuff).
It would be really hard to explain what we did but if someone wants to read the code (it is well documented), we don’t mind. What we did is, when we detect a collision, we backtrace the curve until we find the exact collision point, then approximate the angle of the wall, we calculate the angle between the wall and the speed vector, we translate the speed vector to the origin 0,0 then we use a rotation matrice to rotate the vector with an angle of what we found. Then we retranslate to the collision point, place the ball on the collision point, set the new speed vector and here we go.
- If someone has read to this point: I use for the render loop the following method to get the sleep() value:
while (IS_RUNNING) {
// get the current Time in nanos
oldTime = System.nanoTime();
// update the world objects position
updateWorld();
// update the Background (if scrolling)
updateBackground();
// call the render() function of each object and then repaint
render();
// get the current Time in nanos
newTime = System.nanoTime();
long duration = newTime - oldTime;
// calculate the time a frame should last minus the time it actually lasted
// this will give us the time we need to wait in order to make it last exactly
// the time we want it to.
long waitTime = 1000000000/FRAME_PER_SECOND - duration;
try {
if (waitTime <= 0){
// the frame took longer then the maximum time we wanted it to last
// don't wait at all (CPU => 100%)
//System.out.println("not ok");
Thread.sleep(1);
} else {
// the frame took less then the maximum time, wait for the rest
//System.out.println("ok");
Thread.sleep(waitTime/1000000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This runs really good on my PC and I wanted to know what you think about this and how it runs on your PC.
THANKS FOR ALL YOUR HELP !!!