102. Simulating an asteroid field in 3D
This post duplicated the last post – creating asteroids coming towards us – but in 3D.
You won’t understand all of this if you’ve never read anything about 3D before. If that’s the case, please read a couple of my posts on this, starting here.
When we drew in 2D, we had to guess the size of objects in the distance and how they would fan out around us as they got closer (or at least, I had to guess because I didn’t want to do hard math).
If we draw in 3D, then Codea will automatically do these things for us. If we give Codea a “z” value for depth, as well as x and y, it will size and position all our asteroids correctly. So all we need to do is to turn 3D drawing on, with a couple of simple commands in the draw function.
perspective() camera(shipX,shipY,shipZ,shipX,shipY,-startDist)
The perspective command tells Codea what we can see, looking into the distance. The default is that we can see anything that is within 22.5 degrees of straight ahead (a total of 45 degrees). So if 0 degrees is looking straight ahead, then anything that is between -22.5 and+22.5 degrees can be seen on our screen. In real life, of course, we can see much wider than this, perhaps 120 degrees. But 45 degrees works well in computer graphics.
The camera is positioned in the ship, so the first three values in the camera command are the position of the ship (which I will make 0,0,0). The next three values tell Codea where the camera is pointing. We want it to look straight ahead (so x and y will be 0) to where the asteroids first appear,which is startDist. Or rather, -startDist, because if you remember, all the z values are negative (so the further away something is, the more negative z is).
I am not going to actually draw asteroids in 3D. I’ll keep using 2D images, and rotating them helps make them seem a little 3D.
There is one hard problem, though. I want asteroids to appear in the sky ahead, at a distance of exactly startDist (chosen to be the distance at which we can just see the asteroids – there’s no point drawing them further away than that, if we can’t see them!).
If the asteroid is straight in front of me, that’s easy. x=0, y=0, z= -startDist.
But if the asteroid is in the top left corner of the screen, the x, y and z values are much harder to calculate because they depend on the viewing angle (up/down, left/right). In the end, I found a webpage which explained how to calculate x,y and if you know the distance, and two angles. I’ve explained a little in my code, because I didn’t really want to get into complicated trigonometry that I hardly understand. But I got it working.
The odd thing is that the results look less realistic than my 2D version, because many of the 3D asteroids appear for the first time when they are bigger than dots, so they seem to jump out as you. Also, they seem to bunch together in the middle of the screen, after a while. I have to think about whether that is correct.
See what you think. The code is here, and below is a video.
I going to try again at it. Nothing is going to be perfect. It’s part of learning.