Surprisingly simple but great game! Well done!
As to why it is slow, there're two causes:
1) in JAVA2D renderer operations rect() ellipse() and even point() are extremely slow. So when you draw about 100 rectangles on the screen) and this happens every frame: you slow down your sketch by up to 10 times! (yeah)
Solution for you would be to draw your rectangles via
pixels[] array.
I have tried to make a blog post explaining the performance of the pixels[] array over rect() or point() operations here:
1a) Another solution would be to draw once all the squares to the off-screen PGraphics and then each frame you don't have to redraw 100 rectangles.
Then on every frame you ONLY will have to do this:
- add to the offscreen surface maybe 5-7 new rectangles.
- draw the offscreen surface onto screen.
So now your game instead of performing 100 drawing operations per frame will
only perform 8 drawing operations per frame( 1 surface drawing and 7 drawings of rectangles)
2) Every time you create an object with
new operator, eg.:
..
For these objects chunks of memory will be allocated in what is known as "java memory heap".
Because you perform those new operations inside of draw(), the memory on the heap is allocated almost 30 times per second.
Then when you remove your Misil object from the arraylist, like this:
Java realizes that you will not use it anymore, and decides to "clean up the memory heap" meaning it wants to remove all unused Misil objects from the heap. This process is known as
Garbage Collection . (as in "collection of unused objects"). The problem is that java will do that only once in a while (let's say once per 10-20 seconds) by the time there're few hundreds of the unused objects on the heap. To clean up 300-400 unused objects it may take java let's say 100 milliseconds, which means that your game screen will freeze (you will get dropped frames) for visible by the naked eye time. Which will be seen by the player as "lag".
The rule of thumb in game programming: do not allocate anyting with the "new" operator from draw() method. Which means that inside of setup() you need to initialize all possible missiles and when they are out of the screen, you shouldn't remove() them, but you should what's callled "recycle" them: give them new coordinates (as you would give to new Misil objects.
.