CS594 -- Lab 7
Sokoban Reimplementation in Silhouette
Lab Objective
This lab is designed to give you further experience with using:
- a retained object model,
- the interactors model, and
- constraints
Sokoban Reimplementation
You should re-implement the sokoban game from lab 5 using Silhouette
objects to display all the graphics, Silhouette interactors to implement
all the different behaviors, and Silhouette constraints to perform
certain alignment and data fetching operations. If you have separated
the model and the views correctly, you should not have to change your
model code for this lab.
Designing Your Views Using Silhouette
Since you do not have a great deal of experience designing applications
using a retained object model, the following hints might help:
- Create visual gameboard pieces for every square of the gameboard,
including forbidden squares. Forbidden squares can be represented
by rectangular gameboard pieces that are drawn in the background
color. Each gameboard piece should have a row and column property
indicating its position on the board.
- Calculate the left and top position of each game piece using constraints.
The constraints should use the piece's row and column property to
calculate the left and top position.
- When the character or a ball moves onto a regular space, do not
remove the regular space from the gameboard. Instead, simply let
the character or ball move on top of the space object. Since
Silhouette redraws overlapping objects correctly, the character or
ball will be drawn on top of the space object. By adding the ball
and character after the squares/goal squares, you can
ensure that the ball/character pieces are always on top. Do not
try to use depth numbers, because as explained in another item,
you should add the game pieces to a composite object rather than
directly to the game canvas. In the text view, the game pieces will
all be text objects. To ensure that the ball/character pieces are
drawn opaquely, you should make sure they are filled and drawn in
the background color.
- Make each wall object be a composite object that consists of five
objects, a rectangle and four lines. Give the composite object
four properties, such as northBoundary, eastBoundary, westBoundary,
and southBoundary, that indicate whether each of the four lines
should be drawn. Each of the four lines should have a constraint
on the visible property that consults the appropriate boundary
variable to determine if that line should be visible.
- The character can be moved in a variety of ways, including by pressing
a key or by dragging with a mouse. Each different move behavior should
be implemented as a different interactor that is attached to the
character game piece. You can decide for yourself whether the four
key presses are bundled into a single interactor or put in four separate
interactors.
- You can also move a character to an open square by pressing with the
left mouse button on that square. You can implement this behavior
by creating a single interactor and attaching the interactor to
all squares and goal squares.
- You should add all the game pieces to a composite shape.
That way you can center the composite shape in the game canvas using
constraints. It will also simplify the constraints that calculate
the game piece's position, since they can simply multiply the row
or column numbers by the piece's width and height.
- The scoreboard should have at least two objects representing the
number of pushes and moves. The two objects should extend the
TextShape class and should have an integer value field that
holds their current value. The text fields should have constraints
that convert the integer value to a string. If you want, you can
have two text objects representing the labels and two text objects
representing the numbers. Alternatively, you can add a second
field to a text object that represents its label, and then have
the constraint concatenate the label field with the integer field
to create the text that gets displayed.
- The gameboard editor should use Silhouette rectangles for the initial
squares. Like the pieces in the gameboard, they must use constraints
to calculate their position.
You can attach interactors to the squares and to the
game pieces to implement the various editing and selection operations.
The Use of Constraints
Although I want you to have flexibility in your design, I also want
to ensure that you get experience using constraints. Therefore you
will be required to use constraints to:
- Calculate the x/y positions of your game pieces in the game view
and the squares in the gameboard editor.
- Calculate the text string values in the score view.
- Calculate the visibility of the wall borders.
Submission and Grading
You should submit your source
files electronically to the TA using the TA's submit
program. The TA should be able to run your program by typing the command:
java sokoban
In this lab points will again be deducted if you do not implement all
of the required functionality. As with the first implementation, undo
and character dragging with the mouse will count for less so you should
focus on the other operations first.
Hints
- Your interactors will often not work correctly until you
get your constraints to work properly. Hence,
if you're having trouble getting your interactors to work, make
sure that your constraints are working before you start doing serious
debugging work on your interactors.
- If your constraints do not seem to be evaluating when one of
the variables they reference is changed, make sure that the
variable is declared to be a Silhouette property. If the
variable is a regular Java type, such as an int, then the
constraint will not be notified of the change to the variable
and the constraint will not re-evaluate itself.