|
Now it is time to make this game respond to keyboard input. The game engine already processes keyboard events. So, instead of writing an event handler, we can focus writing game code.
The first thing we need to do is decide on which keys do what. I am fond of using the arrow keys for movement and the shift key for shooting. I prefer not to use the spacebar because the spacebar is noisy and less responsive than other keys. That makes it undersirable as a game button.
For this tutorial, shift will fire bullets. The left and right arrows will rotate the space craft. Up will thrust the space craft forward and down will induce the inertial dampeners (stop any movement). To respond to these five keys in the game, we will need to know their keycodes. To find the keycode for various keys, you could write some code to print the keycode to standard out. However, I made it easier by providing this chart of keycodes.
The Code
boolean shotOk=tr
There is one new global variables to add to the game, shotOk. It is assign true when the fire key is released and false if a bullet was fired. This is help regulate the fire key by allowing one, and only one, bullet per key press. That is, when the fire key is down a bullet is shot but only if shotOk is true. If it is true, then shotOk is set to false, which prevents further shooting until the key is released.
private void doKeyboard()
{ Actor aBull
Like in the last lesson, only one method is added to the class, doKeyboard(). It is where all the game keys will be processed. There is one local variable, aBullet. Normally, I make local variables like these global to prevent unneccessary creation and distruction of the variable during game play. However, keeping my local variables local is making this tutorial easier to write.
if(gEngine.keys[37])
aPlayer.zr += 3f;
if(gEngine.keys[39])
aPlayer.zr -=
These line check to see if either the left or right arrow key is down. If the left arrow key (keycode 37) is down, keys[37] will equal true. The similar is true for the right arrow key (keycode 39). If either key is down, the player's space craft should be rotated. I simple increment or decrement the z rotational value and it works fine. However, this technique is often frowned upon by OpenGL purest. Technically speaking, this code would produce an error if the bounds of the floating point value were exceeded but that would require about 10
36
consecutive rotations of the space craft. Anyone who incures this error while playing has way too much free time...
if(gEngine.keys[38])
{ aPlayer.xs += (float)Math.sin(Math.toRadians(-aPlayer.zr)) * 0.01f;
aPlayer.ys += (float)Math.cos(Math.toRadians(-aPlayer.zr)) * 0.01f;
if(Math.abs(aPlayer.xs)>0.2f)
aPlayer.xs=(aPlayer.xs/Math.abs(aPlayer.xs))*0.2f;
if(Math.abs(aPlayer.ys)>0.2f)
aPlayer.ys=(aPlayer.ys/Math.abs(aPlayer.ys))*0.2
This checks to see if the up arrow key (keycode 38) is down. If it is, the following two lines will accelerate it in the direction that the ship is facing. The remaining four lines are a crude way to limit the ship's speed. I say crude because it limits the speed along the x and y axis, not along the ships speed vector.
if(gEngine.keys[40])
{ aPlayer.xs -= (aPlayer.xs * 0.05f);
aPlayer.ys -= (aPlayer.ys * 0.05f
This checks to see if the down arrow key (keycode 40) is down. If it is, we will use this asymptotic function to reduce the axial speed to something that will approach zero.
if(!gEngine.keys[16])
shotOk=tr
This checks to see if the shift key (keycode 16) is up. If so, shotOk is set to true.
if(gEngine.keys[16])
{ if(shotOk)
{ shotOk=false;
aBullets.add(aBullet =
gEngine.addActor(mBullet, aPlayer.x, aPlayer.y, aPlayer.z));
aBullet.xs = (float)Math.sin(Math.toRadians(-aPlayer.zr)) * 0.5f;
aBullet.ys = (float)Math.cos(Math.toRadians(-aPlayer.zr)) * 0.5f;
aBullet.zrs = 3.1415f;
aBullet.die = 425;
This checks to see if the shift key (keycode 16) is down. If it is down and shotOk is true, a bullet is initialized. To initialize a bullet, we just add an actor that uses the mBullet model and save the reference to it in the aBullets collection. Then, we set its speed to travel in the direction that the player's ship is facing and set it rotating on the z axis for added interest. Notice that die is set to 425. This tells the game engine to destroy the bullet if it has existed for this specific duration when the updateActor() method is used.
while(!stop)
{ doKeyboard(); // *** New Line ***
gEngine.updateActors();
gEngine.sDisplay();
sleep(10
This is a snippet from the run() method. Notice that we need only add a single line to this method and we are done.
Your applet should now displays four rocks moving across the display. The player's space craft is visible, centered in the display. Pressing shift will fire bullets from the space craft. The left and right arrows will rotate the craft. And, the up and down arrows will provide movement and stopping.
|