Pursuit of a User Controlled Space Ship
through a field of moving asteroids
A few short months ago a giant heap of planetary rock raced through the solar system. Drifting dangerously close to the planet Mars, it was caught by the gravity of the planet, creating an impact unlike any seen before. Solid rock debris the size of cities and mountains was hurled beyond the Martian orbit, some on a course of collision with planet Earth.
In light of imminent devastation, the people of Earth generously pooled their resources, working together to build the fastest and most maneuverable ship technology could provide, equipping it with a laser capable of pulverizing the roughest and toughest surfaces known to man, yet harmless to the hull of another ship--in accordance with the principles of nonviolence. This is your ship, and to save the Earth from the terror of incoming asteroids is your mission.
Meanwhile, an alliance of corporations, knowing they stood to profit greatly from the impending destruction of parts of the planet, invested in the development of a second ship, sending it forth with one goal... to stop you from destroying the asteroids. Your adversary is equipped with an impenetrable hull and state-of-the-art asteroid evasion technology. But even this super advanced technology can't predict the future to 100% accuracy. Moreover, time was short and there was no time for a laser. Yet this ship boasts armor so tough it will smash through anything on impact--your ship included. Avoid it at all costs.
Good luck Space Ship Pilot,
Our project is based on the simple asteroids game, which implements a user controlled ship, a pursuer ship, and a field of asteroids. The pursuer ship calculates a path towards the user controlled ship--a moving goal! So it must continuously recalculate its path.
Like the typical asteroids game, the user controlled ship wins by destroying all the asteroids without running into any, while evading the pursuer ship. Firing range is limited to 1/4 the length of the screen. The ship is moved with thrusters, forward (UP arrow key) or backward (DOWN arrow key), taking into account proper Newtonian Mechanics, with the magnitude of thrust equal to 1 pixel. Rotations clockwise (RIGHT arrow key) or counterclockwise (LEFT arrow key) are allowed at PI/16 radians each.
The asteroid field consists of anywhere from 20 to 40 randomly positioned asteroids. Asteroids have anywhere from 4 to 9 edges. Very large asteroids split when fired at. Smaller asteroids shrink. Tiny asteroids disappear completely, as they no longer pose a threat to the Earth. Each asteroid has its own velocity. Currently, we allow asteroids to pass through each other.
The pursuer follows the user controlled ship on a path around the asteroids. Ideally, the pursuer would implement a full RRT planning algorithm, but on account of requiring fast computations, we use a variation of RRT, limited by depth and biased towards a moving goal.
When a ship or asteroid leaves one side of the screen, it reappears on the opposite side. We decide when an polygon has left the boundary of the screen by looking to see if its center point is outside the boundary of the screen.
The Asteroid Field The asteroid field class uses an array to keep track of all the asteroids at a given moment in time. We have defined procedures to allow us to see into the future in order to accurately predict future collisions with asteroids. This field also is updated if an asteroid is shrunk, split, or destroyed by a ship.
Collision Detection Optimization
Firing into a Field of Asteroids
Limited Timeframe RRT
Each RRT node contains a possible configuration of the pursuer ship at timeframe equal to the depth of that node. From the closest node to the target ship, we calculate a path back to the root, giving a sequence of the commands needed at each step to navigate the pursuer ship to that point. The RRT tree is recalculated only when necessary: when the asteroid field changes due to being fired at, or when we have followed nearly all the commands along the path towards the goal. The RRT is not recalculated when the user accelerates even though this changes the goal configuration. This is done to improve performance, since even though the goal will be slightly off within that depth limit, the pursuer will still avoid the obstacles.
Another optimization in planning is taking advantage of a low obstacle-space-to-free-space ratio. The RRT begins with a series of "extend"s directly to the goal, accounting for the quite common case when no asteroids are nearby for much of the path. This idea was taken from class.
When following the new path, we are careful not to follow it to completion. Even assuming our future predictions remain accurate, our depth limit does not allow us to take into account configurations at or beyond time = depth + 1. If we follow the path to completion, we may find ourselves stuck with collisions imminent no matter what we do. A limited path becomes less safe as we get closer to the depth limit. Therefore, we allot the four time frames at the end of each path to look-ahead only, starting a new path when we reach this point.
Predicting Future Positions
The Physics of Extend
Given the fact the a ship often has a non-zero current velocity, we cannot simply apply thrust in the direction of the goal. Instead we must apply thrust so as to cause the ship to move in the direction of the goal, if possible. If this is not possible, we must apply a thrust that causes the ship to move at a lesser rate away from the goal.
The first observation is that for a goal configuration, the rotation of the ship does not matter--a collision at any angle is still a collision. Secondly, it is always best to apply the maximum thrust if this does not cause us to exceed the maximum speed. Thirdly, when applying the maximum thrust in combination with the current velocity vector, two resultant vectors are possible along the line through the current ship and goal. We must then choose whichever of these brings us closer to the goal.
But sometimes, v is larger than maximum thrust, and there is no resultant vector possible along the line from current position to goal. In this case, we apply maximum thrust along the perpendicular to the line from current position to goal, in order to bring the ship closer to achieving a velocity towards the goal.
Note that you may need to click on the applet area once started to activate it for receiving keyboard input. Also, the applet can be very slow on networked unix machines in the lab. You may want to download it (including the game.html file) and run it on your own machine.
Maneuvering the User-Controlled Ship
Cheating: For the sake of testing, you may turn invincibility on/off by pressing "i".
Our project is written in Java, using object oriented development. The code is logically separated into the following nine classes.
See readme.txt for information on how to compile and run. If your machine and browser are powerful enough, you will also be able to run our project off this web page. See the previous section for details.
Reading the code you will likely notice (and be annoyed with) our lack of proper Java coding conventions, specifically, accessor functions. This was necessary for performance reasons.
Why the Pursuer Ship Jitters
When no thrust is being applied, we make the pursuer ship point towards the goal. We did this because without adjustments of rotation after a thrust, the pursuer ship looks as if it is flying sideways. Thus we point it at the goal when thrust is zero. That way it points towards the goal as it flies towards it. This also may cause a lot of wild rotations if alternating frames have thrust/no thrust.
Pursuing the User Ship