The Model in the Model-View-Controller paradigm.
model.
generateFoodGrid
(width, height)[source]¶This method returns a list
of tuples containing all of the coordinates and
colors for the view.actors.Food
actors in the scene, given the specified
width
and height
of the game board in conjunction with some of the constants
defined in constants
. No Food
objects are to be instantiated directly
in this method. Rather, this method is queried from elsewhere in the framework
when it is the “appropriate” time to instantiate the Food
objects. That is,
given the width
and height
of the game board, this method computes
Food
objects that can fit in both the horizontal and
vertical directions.width
, height
, and the constants
constants.FOOD_RADIUS
and constants.FOOD_SPARSITY
constants.FOOD_SPARSITY
to 1.0
?
If you set it to 2.0
? What if you set constants.FOOD_RADIUS
to
be 23.32
?Food
items that can fit in the \(x\) and \(y\)
directions are nx
and ny
, respectively. That is, as a sanity check,
the total length of the list you return
at the end of the method should
be exactly nx * ny
, representing \(N = n_x \cdot n_y\) total Food
objects based on the constraints of the problem.Food
object,
taking into account when constants.FOOD_RADIUS
does not evenly divide
width
or height
respectively.dx
and dy
in the code correspond to the change in
position \(\Delta x\) and \(\Delta y\), respectively.tx
and ty
in the code correspond to the global
translation \(t_x\) and \(t_y\), respectively.Todo
Food
coordinate centers,
and create a random color using view.display.randomColor()
. At the stage
that this method is called in the framework, this is all that can be computed.constants.FULL_GAME_MODE
to True
,
otherwise your hard work will never even be called by the framework!!!Warning
As a reminder, you should not create any Food
objects in this method!
Parameters: |
|
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Preconditions: |
|
||||||||||||
Return: |
|
model.
Scene
(controller, view)[source]¶Bases: PyQt4.QtGui.QGraphicsScene
The main model of the game, responsible for creating and maintaining the state of
the actors in the game. By inheriting from PyQt4.QtGui.QGraphicsScene
,
an instance of this class will be receiving the update notifications coming from the
View indirectly. That is, though this class maintains the locations of the
different Actors, because it is part of the PyQt4
View framework, it receives
communication directly from the View in certain portions.
For example, the controller.CitizenPac
class maintains a gameTimer
that
indirectly controls all of the Actors in the scene. At the end of the constructor
for that class, the timer is connect
ed to the model.Scene.advance()
method
in this class. In essence, this is an indirect “loop”, but since the timer is
officially managed by the View, the impact is that the View technically communicates
directly with the Model (this class). This relationship is instigated and
controlled by the Controller, but we wanted to clarify by example that the
relationships between the Model, View, and Controller in this framework have blurred
boundary lines. If you decide to make your own Model-View-Controller one day, you
may find yourself in a similar scenario – the limitations of the PyQt4
framework in the sense that technically the Model is “directly managed by the View,
which is indirectly managed by the Controller” are confusing. However, though the
relationships between these items become less translucent, its benefits (for
technical reasons not explained here) are worthy. The short version: PyQt4
has a sophisticated backend framework developed over decades by one of the industry
leaders. The framework excels at maintaining consistent internal state, and so we
lean on these features at the expense of “blurred Model-View-Controller”
relationships.
Attributes: |
|
---|
generate
(width, height)[source]¶Responsible for creating the initial conditions of the game, including where
CitizenPac and the Ghosts start, and the location of all the Food. This method
calls the model.generateFoodGrid()
method using the width and height of
the PyQt4.QtGui.QGraphicsView
instance that this (self
) instance
is bound to.
All instances created are registered using the model.Scene.registerActor()
method, which is in turn responsible for storing the the generated actors in the
related attributes of this instance (i.e. self.citizenPac
or self.food
).
If you want to extend the game to add more types of actors, this is where you should create them.
Parameters: |
|
---|
Warning
Do not call this method from the constructor. The
controller.CitizenPac
class is responsible for calling this method.
Because of the “blurred Model-View-Controller” relationships, the Scene
must be instantiated before the View has completed initialization. In order
to use the correct width
and height
, initialization of the actors
in the scene must be deferred until after the View’s Layout has been
performed (this is controlled by PyQt4
).
registerActor
(actor, cx, cy)[source]¶Registers an view.actors.Actor
with this Scene. This method must
be called for the game mechanics (e.g. collisions) to be detected. It is
assumed that the actor being registered has already been added to the
PyQt4
side of the scene by construction. That is, the
model.Scene.generate()
function will instantiate an actor passing self
as the first parameter. Since each actor extends the
PyQt4.QtGui.QGraphicsItem
class, the item is automatically added to the
Scene. Alternatively, you can call the addItem
method (inherited from the
PyQt4.QtGui.QGraphicsScene
class) to associated the item with the
graphics backend.
After construction, the PyQt4.QGraphicsItem class has not had its position
set. The setPos
function is called at the end of this method, assuming it
was an instance of a class we are currently tracking.
Parameters: |
|
---|---|
Preconditions: |
|
numFoodEaten
()[source]¶Returns the number of food items that have been eaten in this round of the game.
Return: |
|
---|
setRunning
(running)[source]¶Pass-through method for the Controller to toggle whether or not the game is
currently-running, used to avoid processing collisions before the game is
resumed. Simply sets self.gameRunning
to the value of running
.
Parameters: |
|
---|
reset
()[source]¶This method resets the game state for all actors in the scene, and ensures
that all food becomes edible again. This method should not modify any instances
directly — call the view.actors.Actor.reset()
for the appropriate
entities of this instance.
Tip
You are encouraged to refer to the
implementation of
model.Scene.advance()
, in addition to the parent class
documentation of view.actors.Actor
, to complete making food edible.
wrapActor
(actor, width, height)[source]¶This method is responsible for adjusting the position of an Actor so that it remains within the confines of the game grid.
Tip
Refer to the 3.2 Coordinate system and actor coordinates section of the writeup
Parameters: |
|
---|---|
Preconditions: |
|
wrapRelevantActors
()[source]¶Confines all relevant actors to remain within the bounds of the game grid
by calling model.Scene.wrapActor()
for every actor that can move in
the game. If you desired to have food moving, you would need to update this
method to do this as well!
advance
()[source]¶This method is what the controller.CitizenPac
hooks its gameTimer
to. It is responsible for processing three things:
self.gameRunning
and
constants.FULL_GAME_MODE
are both True
.model.Scene.wrapRelevantActors()
.super
class advance
, which will propagate to the Actors.The third point there is particularly important not to omit, otherwise the animations on the food, decisions about moving, etc will not occur.
keyPressEvent
(e)[source]¶If the key pressed is one of w
, s
, d
, or a
, call the
view.actors.CitizenPacActor.queueMove()
actor with the appropriate move
direction and True
to signal that the user requested CitizenPac to move in
this direction.
If it is not one of these keys, call the super
class keyPressEvent
to
allow other keys to be applied elsewhere in the framework.
Parameters: |
|
---|
keyReleaseEvent
(e)[source]¶If the key released is one of w
, s
, d
, or a
, call the
view.actors.CitizenPacActor.queueMove()
actor with the appropriate move
direction and False
to signal that the user has stopped requesting that
CitizenPac move in this direction.
If the space
key is released, then the user has requested to pause or resume
the game, call the controller.CitizenPac.gameRunningSwitched()
function.
If the r
key is released, then the controller.CitizenPac.replay()
method is called. Note this method does not reset the game unless it has been
won or lost, so the r
key only has an effect at the end of the game.
If it is not one of these keys, call the super
class keyPressEvent
to
allow other keys to be applied elsewhere in the framework.
Parameters: |
|
---|