Owl









SourceForge Logo

Getting the latest source code

The latest source code is held on Sourceforge in a CVS (concurrent versions system) repository. You can get the source and libraries from the downloads page or from the cvs repository. Here we deal with the CVS method. Using the download page's links are simpler but it is more difficult to keep your local copy synchronised with the code under development.

CVS vs zipped source file

There are two options for getting the source code. The simplest is to download the zipped source file. Winzip can be used to extract the files. The zipped source file can be obtained from the download page.

The second option is to do a cvs checkout of the source code and then to do updates. The advantage of using cvs is that it is more up to date and it is simpler to merge updates from the cvs repository into your local source files. The zipped source file is a brute force overwrite of what you have, whereas the cvs method merges only the changes into your files and also gives you tools to sync individual files that you have changed that have also been changed in the cvs.

What you need

To be able to compile the freeplay code you will need the libraries from the download page as well as the source from this page.

Setting up a CVS client

If you are like me and had never used a CVS before you are probably daunted by this 'barrier'. Don't worry, I will show you the easy steps needed to get the code, it is no more difficult than using a gui ftp client. I have kept the code tree simple, for my own sanity. There are no branches and other complications.

There are several options here, from a hard core command line client to native code gui options (WinCVS/MacCVS) to pure Java clients (jCVS). I looked at a few and have settled for SmartCVS. It is a free, pure java client, that in my limited experience seemed to have the best feel. Even though it is pure java, on my windows box it installed, is launched, and runs like a native code program.

I will only explain how to use SmartCVS, other programs should be similar. Once you have downloaded SmartCvs and installed it, go to Project->Checkout...

Fill in the dialog box as below.

You need to change the 'Checkout into' field.You will be prompted for a password, there is no need to enter one, just keep clicking. My directory structure looks like this.

/
   freeplay
            :
            :
           src
                freeplay
                    runtime
                    editor
                    images
                    library
                         :
                com
                    cg
                        theater
                        utilities
            :
            :
Put the path to the freeplay directory when you checkout the 'src' module. Everything in the src directory and below will be installed.

Code submission

Because you have checked the code out of the cvs as an anonymous user you will not be allowed to commit any changes you make back into the cvs. Please email them to me and I will merge them into the code base.

If it becomes clear that you are providing regular updates then I will set you up as a member of the Chrongears project on Sourceforge and you can then commit changes directly to the cvs. Unfortunately it is necessary to take these basic precautions to prevent malicious submission of buggy code.

Software overview

The big picture

Freeplay consists of two main sections, the game/lesson authoring program (Freeplay) and the runtime code (runtime). The metaphor used by Freeplay is that of a stage performance. There are scenes, actors, props, directors, scripts and so on. Creating a lesson consists of defining these components and how they interact. Eventually there will be a comprehensive library of components and new lessons can be quickly constructed by selecting the appropriate items from the library.

A Freeplay lesson is structured as a tree of nodes where each node has a corresponding java class. This tree structure is what the lesson author works with and it is shown in the Freeplay GUI. The root node represents the play itself. Below that are nodes for each scene, which in turn have nodes representing the props in the scene, the scripts used to control the action in the scene and so on. Below the root node are other nodes that hold global items, such as the actors (who may appear in a number of scenes), sounds and music, messages and the startup script.

I'm only going to deal with how Freeplay is extended using java. The jython scripting language can subclass the java classes and and so create new nodes as well, but that is a document for another time.

Extending Freeplay consists mainly of creating new nodes that can be placed in the tree. The most common type of node is a 'prop', that is, an object that is added to a scene. A prop is pretty much self contained. It is typically a java class that exposes its properties through getter and setter methods (e.g. getName() and setName()). It may also have other methods for performing actions, such as move(). As the author of a prop class you do not have to worry how it interacts with other props or actors, the jython scripts tie everything together and they are written by the play's author.

Freeplay uses the Chronogears package to provide the low level services. These are mainly the sprite based graphics, sound capability and some utility functions, such as a simple image editor.

A sprite is the basic graphic object. For example, a chair in a scene would ultimately be represented by a sprite. Sprites are often, but not always, a bitmapped graphic image. Each sprite has its own renderer which determains how it appears. Chronogears defines various renderers each with their own capabilities. For example, static images, animated images, starwars text scrollers etc.

Writing a prop

Note:This information a little vague, on purpose. Some of the details will change and there will be extra requirements, which are not yet specified. Unfortunately this is the disadvantage of using pre-alpha code.

Like other nodes in the play's tree a prop has three modes of operation. a) It may be present in the tree but essentially idle, b) the user can double click the node in the tree which possibly displays the cusomization editor for the prop, and c) the prop is in runtime mode. The runtime actions are contained in a separate class.

Typically a prop is written by creating two files in the freeplay.library.props directory/package. For example to create a blackboard prop that can be used in a classroom.

BlackboardNode.java
This has the edit time code.
BlackboardProp.java
Holds the runtime code and extends Prop

BlackboardNode.java

This should extend PropNode. For a very simplistic prop the only methods that must be implemented are

  • A null constructor
  • getSprite
  • getRuntime
The constructor should set up any defaults needed. In our blackboard example, these would be a reasonable size, fonts and colors.

The getSprite method must return a CgSprite object that is shown at edit time. If the Chronogears package already has a suitable sprite/renderer combination then you are in luck. If it does not then you are even luckier, cos later you will get a chance to get acquainted with java's graphics capabilities! A sprite is a object that is displayed on a scene. Exactly what is displayed is determined by the CgRenderer that is attached to the sprite.There are various standard renderers available, such as image renderer, animated image renderers, scrolling text renderers, and so on.

In our example there is a suitable renderer for edit time, ie the CgRectangleRenderer. But no renderer is suitable for the run time display of a blackboard. It is a design decision whether the getSprite method of the BlackboardNode class returns a sprite with a CgRectangleRenderer, or the (not yet written) graphics canvas renderer.

The getRuntime method must return an instance of the class that implements the runtime actions of the blackboard prop. In our example it would return an instance of BlackboardNode. The default properties of the blackboard, such as font and colors will be set in this instance. The object will be packaged up into the runtime jar file.

BlackboardProp.java

This class should extend Prop. Beside the constructor the only method that must be written is setScene. For this example we will provide a few other methods so that scripts can manipulate the text on the blackboard.

The setScene method is invoked when the prop is placed in a scene. Typically a sprite is added to the CgDirector that is managing the scene. In our case there is no suitable renderer for the blackboard, so one must be written.

It seems that Chronogears could do with a new renderer that is a graphics canvas. The blackboard prop can then simply write onto this canvas to emulate a blackboard. Props in the future could use this renderer as well, for example a graphs prop could draw on the canvas. It could be considered to be a mini screen. An interesting extension would be to show an entire play on the canvas, ie, a play within a play, but that is for the future.

Create a new renderer in the com.cg.theater directory. Call it CgCanvasRenderer and it should extend CgRenderer. Only two methods are absolutely required. getSize and paint. The default size can be passed in the constructor. The paint method simply draws the required image.

Easier said than done! Where does the 'required image' come from? One technique would be to create a BufferedImage that is the size of the blackboard. Provide a method getGraphics which simply returns the graphics context of the image ( image.getGraphics()). BlackboardProp can now draw directly onto this image. Have a look at the code for CgStarFieldRenderer, in many ways it is similar in that it also keeps an off screen image. It also shows techniques for creating the bitmap, drawing it to the screen and how to handle resizing.

All that remains now is for BlackboardProp to provide a few useful methods to write to the image. For example a drawText(String str) method would be required. These methods would map almost directly to the methods of the Graphics2D object returned by getGraphics() of the canvas renderer.

The prop needs to be tested. The way I normally do is to modify the Wizard.java class. In the method buildDefaultScene add the new prop to the propsNode variable. Now when the opening scene is shown your prop will be there. A second way to test is to add the prop to the library. Do this from the main menu, Library->addClass. Pick your class name then remember to give the library module a name in the next dialog. Your prop can then be dragged and dropped onto the scene.