The idea
In this lab we are going to design
an class representing a pumpkin and use it with
the Processing PApplet
to design a spooky application.
We are not going to use the Processing IDE in this assignment, though I don’t
see any reason why this could not be done with Processing
by a determined person.
A couple of Processing caveats
Processing programs are transformed into Java before being interpreted by the Java Virtual Machine. (Interpretation by JavaScript is also possible.) However, Processing IDE does a few significant syntactic transformations before passing the code on to Java which surprise experienced programmers.
In Java the literal 3.14
is of type double
.
But, when the Processing IDE sees 3.14
,
it transforms 3.14
into a float
, in particular
3.14f
.
Many of the arguments to PApplet
methods, such as
ellipse
,
are float
’s.
In the Processing IDE you can invoke the
ellipse
method
as ellipse(5.0, 5.0, 5.0, 5.0)
;
but, if you try
this in Java, the compiler will
report a compilation error because you are passing a double
argument
to a float
parameter.
However,
ellipse(5.0f, 5.0f, 5.0f, 5.0f)
or even ellipse(5, 5, 5, 5)
work fine.
Processing allows literals, such as #FFA500
, to be used as
colors.
While this syntax is familiar to HTML coders, it is not part of the Java standard,
In Java, you need to use 0xFFFFA500
in this situation.
(The extra FF
is the alpha value for the color.)
By the way, Processing colors are really just 32-bit int
values.
Processing allows some type names,
such as int
, to be used a prefix
operators for converting data types.
This means that int(3.14)
is 3
in Processing.
In Java, int(3.14)
is a syntax error.
You need to use the more traditional C/C++/Java casting operators, for example
(int)(3.14)
.
Finally, be warned that the PApplet
class has lots of public
fields and that you will be using them in your program. Because public fields are
discouraged in object-oriented programming, you may find this to be a
little disconcerting.
Getting started
In this section, we show you how to get Java working with Processing libraries.
Getting the library
Before starting you will need to download the Processing system to get a copy of the Processing library. Be sure to remember where you installed Processing.
This step should not to be done in the RRO223 lab.
Starting the sketch
Next, you need a class
that starts the Processing “sketch.”
The main
method of this class
must call the main
method of
the PApplet
class with the name of your sketch.
I suggest you accomplish this
with a class that performs only this single activity,
as shown in the following example:
package edu.unca.cs.csci202; import processing.core.* ; // add core.java in the core/library subdirectory of processing public class Boo { /** * @param args the command line arguments */ public static void main(String[] args) { PApplet.main(new String[]{"edu.unca.cs.csci202.Halloween"}) ; } }
NetBeans will complain that it has no knowledge of the
processing
classes.
To fix this problem
go to the Properties tab for
NetBeans and right-click on your project’s name.
This will raise a Projects window.
Go to the Libraries
category and add a jar file
core.jar that contains the needed Processing
libraries.
This library file is located in
the core/library subdirectory
of your Processing distribution.
If you want to distribute your system,
you should copy this library into your project’s
src
folder.
Writing the sketch
Your sketch is similar to an ordinary Processing sketch
but it must follow the class
syntax of Java,
and it must extend PApplet
.
Also, the name of your class, prefixed with its package name,
must match the String
passed
to PApplet.main
in your launcher program.
In our preceding example that was
"edu.unca.cs.csci202.Halloween"
.
Here is a class that satisfies these requirements.
package edu.unca.cs.csci202; import processing.core.* ; public class Halloween extends PApplet{ int pumpkinXPosition ; @Override public void setup() { size(800, 600) ; pumpkinXPosition = 0 ; } @Override public void draw() { clear() ; fill(255, 165, 0) ; // fill(0xFFFFA500) ; ++pumpkinXPosition ; if (pumpkinXPosition==width) { // width is a public field of PApplet pumpkinXPosition=0 ; } ellipse(pumpkinXPosition, height/2, width/8, height/8) ; } }
Use the two programs show above along with the core.jar file from the Processing distribution to run the sketch from NetBeans. On the RRO 223 workstations, the jar file is located at /opt/lib/processing-2.0.1/core/library/core.jar .
Also, take a look at the documentation for
the Processing PApplet
class.
That is a lot of methods and fields.
Doing OOP
Let’s get you started in adding some objects to your program.
Do this by creating a Pumpkin
class that represents a pumpkin.
The Pumpkin
class should “know” its position and size.
Later it may even learn a little about its eye color and the
direction in which it is moving.
Once the Pumpkin
knows who to keep up with itself,
we can create many Pumpkin
’s and leave the details
of being a pumpkin to a Pumpkin
.
Making a model of the pumpkin
Create a new class called Pumpkin
in your project.
At a minimum, do the following:
- Create private
float
fieldsx
,y
,width
, andheight
for yourPumpkin
class. - Create appropriate accessor and mutator methods for these four fields.
- Create a method
draw
that takes a single parameter, aProcessing.core.PApplet
object. Thedraw
method will use the methods ofPApplet
to draw a pumpkin centered atx
andy
.
If you want to make absoultely sure you have the right methods;
you can start with an outline of a Pumpkin
class, or
you can place a
ProcessingDrawable2D
interface in your project and
add
implements ProcessingDrawable2D
to the
header of your own Pumpkin
class.
Complete the accessor and mutator methods.
Postpone work on the draw
method.
It would also be a good idea to add some constructors.
Now the class provides a model of a pumpkin.
Using the pumpkin model
The ultimate result of this next effort will look unimpressive,
but it will start the objectification of our pumpkin:
We are going to use an instance of the Pumpkin
class
in our Halloween
sketch class.
Declare a single Pumpkin
object in your
Halloween
class.
In the setup
method initialize your Pumpkin
object by calling the appropriate mutator methods of
the Pumpkin
class.
In the draw
method of Halloween
,
read and update the x position
of your Pumpkin
using the getX
and setX
methods.
You will need to use the accessor methods of Pumpkin
to
generate arguments to PApplet
’s
ellipse
method.
Run your updated code. It should look the same.
Making and using a view of the pumpkin
It would be very tedious to call ellipse
with
all those arguments every time we need to draw a pumpkin.
We are going to give Pumpkin
the responsibility of
drawing itself. It particular, we are going to make the draw
method provide a view of the pumpkin.
In a real application of the Model-View-Controller
(MVC) paradigm, the view would be handled by a separate class; but
that just seems a big too much for our pumpkin. We are
just going to assign this task to
the draw
method of Pumpkin
.
There is one twist to this.
Normally, Processing sketches are extensions of the
PApplet
class. This means that a call such as
fill(255, 165, 0)
is really
an invocation of a method of the PApplet
superclass, in particular
super.fill(255, 165, 0)
.
Halloween
is a subclass of
PApplet
, but
Pumpkin
is not; so super.fill
is not available.
This means you’ll need method calls like
pa.fill(255, 165, 0)
inside your Pumpkin
draw
method.
Complete the draw
method of Pumpkin
so that it
invokes PApplet
methods to draw a pumpkin.
Modify the draw
method of Halloween
to
call the draw
method of Pumpkin
.
At this point, there should be no fill
or
ellipse
calls in Halloween
.
Your pumpkin needs to be nothing more than a single oval.
Getting fancy
Improving the view
Once the draw
of Pumpkin
is working
good enough to show a orange oval,
add some more features to your pumpkin such
as a pair of eyes or a nose or a disturbing grin.
More pumpkins
Create an array of several pumpkins inside the Halloween
class. Have the draw
method of Halloween
call the draw
method of Pumpkin
for each
element of the array.
This is a natural place to use the enhanced for loop.
Saving the environment
Your program is probably making many side effects on
PApplet
’s environment. It is certainly
changing the fill color, and it may be modifying more obscure settings
like the color mode and ellipse mode.
I started my draw
method with a few statements to
save these settings.
public void draw(processing.core.PApplet pa) { int oldColorMode = pa.g.colorMode ; int oldEllipseMode = pa.g.ellipseMode ; boolean oldFill = pa.g.fill ; int oldFillColor = pa.g.fillColor ;
And I ended my draw
with a few statements to restore
these settings.
pa.g.fillColor = oldFillColor ; pa.g.fill = oldFill ; pa.g.ellipseMode = oldEllipseMode ; pa.g.colorMode = oldColorMode ; }
Perhaps this is excessive, but it doesn’t do any harm.
Swapping pumpkins
If you have created the suggested set of methods for the pumpkin,
you should be able to drop your Pumpkin
into
someone else’s project.
You can try this, but it would be easier if everyone was extending a common class or interface so that we could be displaying several different pumpkins at the same time. That sounds like the next lab to me.
Adding control
Right now our MVC implementation doesn’t have much C (control).
We could ask the Halloween
class to provide control
by adding variables to keep up with, for example, trajectory information
to each Pumpkin
.
Alternatively, we could add trajectory to each pumpkin.
This might (or should) be done in new classes of pumpkins created by
extension or aggregation.
You can think start working on this today if time permits.