Introduction to Computer Programming

Lab B: Graphics Game

event-driven programming

(timers, mouse clicks and key presses)


Instructions


Goal

Your goal is to implement a very simple graphical game that uses key-press events to control a player; timer events to animate an “enemy” and limit game time; and mouse-click events to allow for the construction of walls which can thwart enemy (and player) movement. The “story” for the game: the player aims to acquire the gold treasure quickly before colliding with the enemy, before the enemy acquires the gold, and before time runs out. The player moves in the four cardinal directions using the arrow keys. The player builds impassible walls with mouse clicks. The enemy moves randomly, several times per second.


Exercises

  1. Download and unzip the starter archive. Use IDLE to open whacka_whatever.py in the labB folder. Review and experiment with playing and modifying (slightly, in any way you choose) the “whacka-whatever” game (the example that we developed recently in class). Ask questions about any parts of the code you do not understand.

  2. Rename the starter code (labB_starter.py) and read it over. Experiment with running the starter code as is and contrast that with the runnable solution:

     >>> import labBx
     >>> labBx.play()

    Experiment with the solution version to understand the gist of the game and see what it takes to win and lose.


    Out of the box, the starter code will draw the player and goal (the “gold treasure”) and the player can quit (‘q’) and move to the right by pressing the right-arrow key.

  3. Add code to key_handler and modify player_move so that the player can move up, down and to the left but not past the edges of the graphics window. (Follow the model used for moving to the right. The relevant key names are 'Up', 'Down' and 'Left'.)

  4. Winning. Modify player_move so that if the player moves onto the same square as the treasure (_gold), the game ends and a suitable message indicating that the player won is printed in the shell. (Call game_over).

  5. Add code to countdown_timer so that, assuming the game is still being played, a message is printed in the IDLE shell indicating how many seconds are remaining (the global variable _time), the timer is decremented by 1, and the function schedules itself to execute again one second later. (Use set_timer.)

  6. Losing - part I. Modify countdown_timer so if the time reaches 0, the game ends with an appropriate message. (Call game_over.) You may wish to adjust the value of GAME_TIME.


    the enemy

  7. Complete enemy_timer so that, assuming the game is still being played, the enemy moves randomly at most one position in both the horizontal and vertical directions. The enemy should move once for every ENEMY_DELAY milliseconds. (So, enemy_timer, like countdown_timer should schedule itself to execute again in the future using set_timer.) Start the enemy moving by scheduling (i.e., also using set_timer) enemy_timer to be started one second after the game begins, in play. You may wish to adjust the value of ENEMY_DELAY.

  8. Add “wrap around” mechanics for the enemy: if it goes just past the left edge it should reappear on the right edge of the graphics window and likewise for moving just past the top edge it should then reappear on the bottom. Prevent the enemy from moving past the bottom or right edges of the graphics window - this will make the enemy much more likely to “go for the gold”.

  9. Losing - part II. Modify player_move and enemy_timer so that if the player moves into the enemy, the enemy moves into the player, or if the enemy moves into the gold, the player loses. (Call game_over.)

  10. Experiment with different values for the countdown clock, the dimensions of the graphics window and the speed of the enemy to make the game suitably difficult. You might also adjust how the enemy chooses to move (for example, making its random selection “weighted” toward moving down and to the right).

Time permitting