controller module

The Controller in the Model-View-Controller paradigm.

controller.USE_FANCY_GRAPHICS = True

Some students have been having trouble with the splash messages, I suspect the Qt graphics effects are the cause. By setting this to False, only a text-message between lives is displayed, instead of the splash image.

class controller.LostFocusFilter(controller, parent=None)[source]

Bases: PyQt4.QtCore.QObject

A simple filter to signal to the Controller that the moving flags of the CitizenPac actor needs to be reset. Without this filter, if you hold one of the directional keys w, a, s, or d and then move focus away from the application (e.g. sloppy mouse focus, or alt + tab), the CitizenPac actor would continue moving on its own because the key released event is never received. This filter simply detects when the focus is no longer on the game, and signals to the Controller, which in turn resets the CitizenPac actor.

Attributes:
controller (controller.CitizenPac)

The Controller instance to signal when the application has lost focus.

eventFilter(obj, event)[source]

An event filter to signal to the Controller that the application has lost focus. The event issued is ApplicationDeactivate from the PyQt4.QtCore.QEvent class, upon detection the controller.CitizenPac.appLostFocus() method is called.

Parameters:
obj (PyQt4.QtCore.QObject)

The object that signaled the event. Irrelevant for the purposes of this method since we always want to handle this event regardless of where it came from.

event (PyQt4.QtCore.QEvent)

The event that needs to be checked for filtering.

Return:
bool

True if the event is being handled (prevents propagation to the rest of the objects), False if not handled. For this filter, the return will be True if and only if event.type() == QtCore.QEvent.ApplicationDeactivate.

class controller.CitizenPac(app, cpMainWindow)[source]

Bases: object

The main controller. This class is responsible for creating, configuring, and driving the Model and View portions of the Model-View-Controller paradigm.

Parameters:
app (PyQt4.QtGui.QApplication)

The main QtApplication instance, instantiated in __main__.py.

cpMainWindow (view.display.CitizenPacMainWindow)

The main window associated with this game. Must be created after the app (Qt internally associates them).

Danger

The names of the widgets in the view/qt_configs/citizen_pac.ui design file are exceptionally important. The name of each widget causes the UI Converter to name the attributes of the class it generates based off these labels, and the names are hard-coded in this file. In short: do not rename widgets without updating this file!

Attributes:
Qt Wrappers
app (PyQt4.QtGui.QApplication)

Reference to the main application. It is only stored so that we can install the controller.LostFocusFilter event filter.

cpMainWindow (view.display.CitizenPacMainWindow)

The UI generated wrapper class that represents the Game GUI Layout.

State Variables
gameRunning (bool)

Whether or not the game is currently running.

gameFinished (bool)

Whether or not the game has been completed (all food consumed, or have run out of lives).

livesLeft (int)

The number of lives left.

speedIncr (float)

The game speed increment for the given game. Refer to the documentation for constants.USE_SPEED_BOOST.

Mechanics Variables
view (PyQt4.QtGui.QGraphicsView)

The View portion of the Model-View-Controller paradigm. Also a convenience rename of self.cpMainWindow.citizenPacGraphicsView as was named by the Ui generator from PyQt.

scene (model.Scene)

The Model portion of the Model-View-Controller paradigm.

gameTimer (PyQt4.QtCore.QTimer)

The game timer used to trigger updates to all actors in the scene, connected directly to the model.Scene.advance() method. Its (and therefore the game’s) refresh rate is defined by constants.GAME_REFRESH_RATE.

Display Related Variables
gameStats (view.display.GameStats)

The wrapper for the game running checkbox, speed boost progress bar, and lives remaining and score lcd scores.

splashImage (PyQt4.QtGui.QPixmap)

The pixel map representation of the splash image. Only declared / used when controller.USE_FANCY_GRAPHICS is True.

splashBrush (PyQt4.QtGui.QBrush)

The brush used to paint when the game is not running, it paints a repeated pattern of the splashImage. Only declared / used when controller.USE_FANCY_GRAPHICS is True.

viewEffect (PyQt4.QtGui.QGraphicsOpacityEffect)

Applied to the splash image to blend it a little with the background so it is not so intensely bright orange. Only declared / used when controller.USE_FANCY_GRAPHICS is True.

gMessage (PyQt4.QtGui.QGraphicsSimpleTextItem)

The game message, displays how many lives are left.

dMessage (PyQt4.QtGui.QGraphicsSimpleTextItem)

The directions message, indicating Press <space> to Play, or that the game has been won or lost.

appLostFocus()[source]

When the application has lost focus, make sure to force CitizenPac to stop moving. This is called from the controller.LostFocusFilter instance created in the constructor of this class. Without this, because of how the movement is being represented, CitizenPac would keep moving on their own! For example, if you hold the w key and then switch to a different application, the w released event was never sent so CitizenPac keeps moving North.

errorOut()[source]

Convenience method for students to be able to see slightly more pretty error messages. Since some of the code they are writing happens after the full Qt Context is initialized, the error message would keep printing over and over in the console. This method changes the central widget of the cpMainWindow to be a “text editor” (read only) that displays the error message.

Note

Calling this method should only ever be done from within an except clause. Example:

try:
    call_some_functions()
except:
    self.controller.errorOut()

This method extracts the traceback on its own. So if you call it and there is no actual traceback, it will be more confusing than helpful. If anything, raise an exception yourself.

foodConsumed()[source]

This method computes the current score and (if constants.USE_SPEED_BOOST is set to True) current game speed. The score and speed are computed using the model.Scene.numFoodEaten() method. This method is also called by controller.CitizenPac.lostLife() to reset the score and speed boost since the food have all been reinitialized.

gameWon()[source]

When the game is won, this method triggers the game won message to be displayed by setting self.gameFinished = True and calling the controller.CitizenPac.gameRunningSwitched() method.

gameRunningSwitched()[source]

The game running state can be switched when one of three events occur:

  1. The user hit the space bar, to pause or resume the game.
  2. A life was lost (controller.CitizenPac.lostLife())
  3. The game was won (controller.CitizenPac.gameWon())

The method then propagates to the scene whether or not the game is running, starts / stops the game timer, and triggers the pause / game won / game lost screen to be displayed if the game is not running.

lostLife()[source]

When CitizenPac collides with a ghost in the model.Scene.advance() method, this method is called to update the scoreboards. It proceeds by performing

  1. Updating the number of lives left on the scoreboard and switching the game running state via controller.CitizenPac.gameRunningSwitched().
  2. Resetting the entire scene via model.Scene.reset().
  3. Resetting the score and speed boost via controller.CitizenPac.foodConsumed().
replay()[source]

Allows the game to to be reset. No action will occur if self.gameFinished is not True. That is, the game can only be replayed once it has either been lost or won.

The number of lives the player started with is restored, and the scene is fully reset and set to the paused state that the game originally starts in.

class controller.Highlighter(parent=None)[source]

Bases: PyQt4.QtGui.QSyntaxHighlighter

This class is part of the PyQt4 example code distributed under the BSD license. It comes from the syntaxhighlighter example. The license:

Copyright (C) 2010 Riverbank Computing Limited. Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.

This file is part of the examples of PyQt.

$QT_BEGIN_LICENSE:BSD$

You may use this file under the terms of the BSD license as follows:

“Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”

$QT_END_LICENSE$

highlightBlock(text)[source]

Highlights the text based off the rules defined in the constructor.