Integrating Mouse Events with the Main Loop

The first two examples in this chapter have been kept relatively simple to get you familiar with the use of event listeners. They are event-driven programs, where an event occurs and then we update the state of the program accordingly. This is why they are simple (with respect to application programmers, that is), because there is no main game loop handling logic and updating the display on its own periodically. Instead, an event occurs causing an event method to be invoked, which then in turn handles the event and calls a repaint method, updating the display with the new event information. This method is fine when your program is only altered by a user-caused event but not for real-time gaming. The main problem lies in the fact that these events are registered in a separate thread from your main loop thread (the Event Dispatch Thread), interrupting it at random times—whenever an event occurs. This can become a problem when you create another thread (in our case, the main loop thread of execution, like we created in Chapter 9). The problem arises that we cannot predict when the event will occur in terms of where we are in the main loop, similar to problems we discussed with passive rendering in the main loop in Chapter 9.

For example, we could have an object in our game, say a Monster object, that moves about in the game. This movement code could be executed in the main loop, as follows:

while(mainLoopRunning) {     if(myMonster!=null)        myMonster.move();      // Update display }

We may then have a mouse listener method that can lead to the possibility of killing the monster and removing the object completely, as follows:

public void mousePressed(MouseEvent e) {     if(monsterKilledFromEvent())     {        myMonster = null;     } }

Our program could crash, caused by a NullPointerException exception, however unlikely. It is still possible though.

  • First check in the main loop to see if(myMonster!=null). This check is returned true, as myMonster currently references a Monster object.

  • The event listener thread then interrupts the main loop thread, and we press the mouse button, causing an input that kills the monster. We handle the killing of the monster by setting the reference myMonster to null.

  • The main loop thread then continues execution, already passing the check to see if(myMonster!=null), which has already been validated, and then attempts to access the move method of myMonster, which now equals null. This would then cause a NullPointerException exception to be thrown.

We can handle thread synchronization problems such as this in a number of ways, like controlling when code in separate threads executes relative to another.

One way we could handle this problem is by using the keyword synchronized with an object to protect the threads from performing their code at dangerous times relative to one another. We could do this, as follows, in both our main loop and the keyPressed event method:

while(mainLoopRunning) {     synchronized(myMonster)     {        if(myMonster!=null)            myMonster.move();     }          // Update display }           public void mousePressed(MouseEvent e) {     if(monsterKilledFromEvent)     {         synchronized(myMonster)         {             myMonster = null;         }     } }

The synchronized(myMonster) code block acts as a lock for the code in its thread. If we enter the synchronized code block in the main loop, we cannot enter the synchronized block in the mousePressed method at the same time. One thread must wait until the other is no longer executing in the synchronized block, which is controlled using the myMonster object as the lock; hence they are synchronized with one another. This means that our NullPointerException exception can no longer occur. For a detailed explanation on thread synchronization issues, please refer back to Chapter 7, "Threads."



Java 1.4 Game Programming
Java 1.4 Game Programming (Wordware Game and Graphics Library)
ISBN: 1556229631
EAN: 2147483647
Year: 2003
Pages: 237

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net