JavaFX Online Game Prototype: Wish Tree (2)

Posted: under JavaFX Games, Wish Tree.
Tags: , , ,

Last week, I introduced a JavaFX prototype of an online game. Readers have been leaving all kinds of wishes on my Wish Tree. It is interesting to see there are more than 20 lucky stars hanging on the Wish Tree now. If you have not tried the program yet, you are encouraged to click on the screenshot on the right to take a look or make an online wish.

Let’s come back to the technical part of the program again. In part 1, we introduced the architecture of this online application and the JavaFX rich client. In this post, I will explain the details of the data exchange between the client and the server. For your convenience, I bring back the architectural figure as shown below:

click to start wish tree online program


Like any client/server system, the server provides data services to the client. Based on the requirement of the Wish Tree, we define two services provided by the server: getAllStars and saveStar.

Service name Parameters Notes
getAllStars none  
saveStar location, name, content, time, color, email for create, returns id
id, content, email for update


The first one getAllStars is for the client to retrieve the data of all the stars(wishes) in the database. The data of a star contains its (x,y) coordinates on the screen and its color. The wish information associated with a star is also returned. Such information includes the wisher’s name, email address, content of the wish and the time when the wish was made. Based on this data, the client restores the stars at the exact location where people hung them on the tree. In this way, every time you start the wish tree client, you always see your star staying at the same place.


The second service is saveStar. When a user creates a star on the tree, the data of the star is sent to the server and saved into the database. The id of the star is returned to the client for later update purpose. The id is nothing more than a unique identifier of each wish stored in the database. You can think of it as the primary key of a database table. We will re-use this service to update a wish. This is due to the fact that most of the handling logic is the same for create and update action. The service first checks whether the client has sent in an id as a request parameter. If id is included, then it is a request of update; otherwise, it is a request of create.


The sequence diagram of these services are depicted as below:




Now that we have a high level design of services, we can elaborate on the protocol between the client and the server. Since our application is stateless, a RESTful style of request and response should be good enough. Therefore, we use HTTP GET request for the getAllStars service and POST for the saveStar service. The format of the response data could be HTML, XML or JSON. Because JavaFX provides a PullParser class which can parse XML or JSON data, we choose JSON in our application. Below is a sample of the JSON response of the getAllStars service:

{
 "Star": {
   "id" : "102",
   "name" : "John Smith",
   "content" : "My first wish",
   "location" : "388.0_248.0",
   "email" : "j.smith@example.com",
   "time": "2009-08-21 16:38:37",
   "color": 3
 },
 "Star": {
   "id" : "108",
   "name" : "Homer Simpson",
   "content" : "This is another wish.",
   "location" : "188.0_228.0",
   "email" : "homer@simpson.com",
   "time": "2009-08-28 18:28:48",
   "color": 4
 }
}


Once we finalize the protocol between the client and the server, we can start to implement the code on both sides. In a large scale project, this usually results in two teams concurrently working on the code of the client and the server respectively. At the client side, the code to parse the above JSON data is in Main.fx :

var parser = PullParser {
    documentType: PullParser.JSON;

    onEvent: function(event: Event) {
      var content: String;
      var name: String;
      var id: String;
      var email: String;
      var color: Integer;
      var time: String;
      var location: String;

      // parse the JSON data and populate the object
      if(event.type == PullParser.END_VALUE) {

        if(event.name == "name") {
          star.name = event.text;
        }
        else if ( event.name == "content" ){
          star.wish = event.text;
        }
        else if ( event.name == "id" ){
          star.id = event.text;
         }
        else if ( event.name == "color" ){
          star.whichColor = event.integerValue;
        }
        else if ( event.name == "time" ){
          star.time = event.text;
        }
        else if ( event.name == "location" ) {
          var pos = event.text.indexOf( "_" );
          var x = event.text.substring(0,pos);
          var y = event.text.substring( pos+1 );

          star.translateX = Float.parseFloat(x);
          star.translateY = Float.parseFloat(y);
        }
        else if ( event.name == "Star" ){
          star.changeStatus();
          star.onMousePressed = handleClick;

          insert star after stage.scene.content[currentIndex++];
          star = Star {};
        }
      }
    }
  }


The JavaFX client uses the class HttpRequest to communicate with the server. HttpRequest allows us to use GET and POST method to send requests to the server. Usually, we only need to override some methods of this class. As shown in ServerConnector.fx below, we rewrote the onOutput and onInput functions to invoke the saveStar service from the server.

/*
 * ServerConnector.fx
 * @author Henry Zhang   http://www.javafxgame.com
 */
package wishtree;
import java.net.URLEncoder;
import java.io.*;
import javafx.io.http.*;

var baseURL = "http://localhost:8888/wishtree/";

public var serverURL1 = "{baseURL}getallstar.php";
var serverURL2 = "{baseURL}savestar.php";

public class ServerConnector extends HttpRequest {
  var star : Star = null;
  var paramString : String ;

  override var onOutput = function( os: java.io.OutputStream): Void {
        try {
            os.write(paramString.getBytes());
        } finally {
            os.close();
        }
    };

  override var onInput = function(is: java.io.InputStream) {
     try {
           var br = new BufferedReader( new InputStreamReader( is ) );
           var line: String;

           while ( ( line=br.readLine() ) != null )
           {
             if ( (star != null) and (star.id == "")  )
                star.id = line;
            }
        } finally {
            is.close();
        }
  };

public function saveStar( s: Star ) {
  if ( s.id.length() == 0 )
    star = s;

  paramString = encode("name", s.name);
  paramString += "&{encode("id", s.id)}&" ;
  paramString += encode("location", "{s.translateX}_{s.translateY}" );
  paramString += "&{encode("content", s.wish )}";
  paramString += "&{encode("email", s.email)}" ;
  paramString += "&{encode("time", s.time)}&" ;
  paramString += encode("color", "{s.whichColor}" );

  headers = [
        HttpHeader {
            name: HttpHeader.CONTENT_LENGTH;
            value: "{paramString.getBytes().length}";
        }
       ];

  method = POST;
  location = serverURL2;
  start();
 }
}

function encode( k: String, v:String): String {
    var result = URLEncoder.encode( k, "UTF-8");
    var value = URLEncoder.encode( v, "UTF-8");
    result += "={value}"
}


On the server side, the PHP code is quite straightforward. Basically, it gets the parameters from the request and convert them into SQL statement for MySQL database. After getting the data from MySQL, it returns the data in JSON format.


Finally, I would discuss how to tie up all the components together. First, we build the JavaFX client in NetBeans. The products are a jar file and a JNLP file. We modify attributes in the JNLP file to match the deployment environment. The most important is to set the correct value of the “codebase” attribute. Then we upload the jar and JNLP files to a folder on a web server. This folder should match the one specified in the codebase attribute. The next step is to deploy the PHP scripts, for simplicity, we just upload the scripts under the same folder where we put the jar. In the scripts, be sure to change the user name and password of the database. In your MySQL database, create a table to store the wish data. The last thing would be putting a link in a web page which contains the web start link to your JNLP file.


For source code, you can get it from the download page of this site. As shown in the architectural figure, there are codes of server side(Mysql and PHP) and client side(JavaFX), respectively. Be sure to read the file README.txt before you try the code.


If you have any questions, please leave comments.



Other JavaFX articles:

JavaFX Online Game Prototype: Wish Tree (1)

JavaFX Menu       Java Code Calls JavaFX APIs


Comments (3) Aug 28 2009

JavaFX Online Game Prototype: Wish Tree (1)

Posted: under JavaFX Technology, Wish Tree.
Tags: , , , ,

 

I finished a JavaFX prototype of an online game, it is called “Wish Tree”. Strictly speaking, this prototype is not a game. Instead, it is an online multi-user application of fun (esp. for kids). However, it embodys all the essential elements of an online game: a JavaFX rich client for user interaction, a server handling communication among multiple clients, and a database for data persistence. Though it is still relatively simple, it lays a foundation of building an online multi-user game. I am going to demostrate in two posts how to design and write such an application in JavaFX, PHP and MySQL .

 

  Not long ago, I wrote a JavaFX program for fun. You may have heard of the song “Tie a Yellow Ribon on an Old Oak Tree”, my program was called “Hang a Lucky Star on a Wish Tree“. It allowed people hang colorful stars on a tree to keep their wishes. These wishes could be about absolutely anything. Usually it was used by children, who might wish for exciting birthday presents or good results at school, but there were often stars hung by adults wishing to do well in a game of online bingo or hoping to be successful in a job interview. The program appealed to people from all walks of life that were keen to share their wishes for the future. The program was running as a standalone application. Recently, I added in some code to make it an online version. People all over the world now can share their wishes on the same tree. 

This online version is a true RIA(Rich Internet Application) now. After a person leaves a lucky star on the tree, he/she can see the star next time she/he runs the program. People can see others’ wishes as well ( sorry, no privacy for now ^_^ ). However, an email address is needed to modify an existing wish.

 

The main architecture of the whole system is depicted in the below figure. First, the program gets started from a browser by Java Web Start technology. Then the program connects back to the server to obtain data and draws the wish tree hanging with stars. The server component retrieves data from the database and returns to the client. If the client makes a new wish, the data of the wish is sent to the server for persistence.

 

The requirements of the system are listed below:

 

1) On the client side, we need a browser that supports JavaFX 1.2. Basically, on our client machine we need JRE 1.5 +, or better with JRE 1.6 U13 later.

2) On the server side, we need a web server that supports PHP and MySQL. We can choose the popular “LAMP” stack (Linux, Apache web server, MySQL and PHP), but the two required things are ‘MySQL’ and ‘PHP’ only. In fact, in my development environment, I use Windows XP, Sun Java Web Server 7.0, MySQL and PHP plugin for JWS.

 

Before we get into any technical details, you can click on the below screenshot to start the JavaFX
client to see how it works. You can click on existing stars to see others’ wishes, or click on the tree
to leave your wish. Be sure to leave your email address so that you can modify your wish later. After you save your wish, you can check your wish next time you start the program. For testing purpose, please do not leave more than 2 wishes(stars).
click to start wish tree online program

 

Since this is a typical client/server application, let’s look at the JavaFX client first. A GUI is presented to the user for interaction. The Main.fx contains the main Windows(a Stage instance) of the application. We put in some images of trees and clouds on the stage. To make them look more realistic, the clouds are applied with the GaussianBlur effect.

 

The Bubble.fx defines a Bubble class which draws a bubble rising from the bottom of the stage. Animation is used to let the bubble eventually vanish into the tree. The Main class has a few instances of Bubble to create a boiling effect.

 

When the tree is clicked, a star is shown and a dialog is popup for the user to enter a wish. The
Star is a subclass of the Polyon class. It has a few pre-defined color schemes. The part of drawing a star is achieved by the following few lines, a little bit of geometry knowledge here:

def r1 : Double = 15; def r2 : Double = r1 / 1.6; var r = [r1, r2]; … … points = for ( i in [0..9] ) [ r[i mod 2] * cos( toRadians(i*36) ), r[i mod 2] * sin( toRadians(i*36) ) ];

 

The Dialog is a subclass of CustomNode which contains a few buttons and text fields. When the “OK” button of the dialog is pressed, the user’s wish is saved on the server. The user can also click on a star that’s already on the tree to view its content. If the user is the owner of the wish( based on the email address), the user can modify the content of the wish and then save it.

 

Finally, the class ServerConnector uses HttpRequest to communicate with the server and store wishes in the server’s database. We will walk through the server code next week and illustrate the data interaction between the server and the client.

 

If you are interested in the source code, you can visit the download page of this site. As shown in the architectural figure, there are source code of server side(Mysql and PHP) and client side(JavaFX), respectively. Be sure to read the file README.txt before you try the code.

 

If you have any questions, please leave your comments.

 

Next Article: JavaFX Online Game Prototype: Wish Tree (2)
 

 
Other articles on JavaFX:

JavaFX Scene in Swing       JavaFX API for Java

JavaFX Menu       How Java Code Calls JavaFX APIs ?

Review on Book “Essential JavaFX”

Comments (3) Aug 16 2009

Hang a Lucky Star on a Wish Tree

Posted: under JavaFX Games, Wish Tree.
Tags: , , ,

It is a game like program for my kids, or say it is some fun for everyone. You can make a wish and place it on a Wish Tree. Hopefully, it will come true some time later. A star hanging on the tree denotes a wish. For phase I, I am building this wish tree as a standalone version. In Phase II, I will make an internet version, so that everyone can place wishes on the same tree.


Wish tree: http://www.javafxgame.com


When you click on the wish tree, a wish star appears and a dialog is shown to allow you to enter your name and your wish. Later on, if you click on the same star, you have a chance to modify your wish. My daughter likes it very much, she places all kinds of wishes( such as I want a Barbie) on the tree and really hope they will come true soon. You can have some fun by clicking on the below image to place your wish too. JDK1.5+ is required, JDK 1.6 U13+ is better:


Wish tree: http://www.javafxgame.com

click to start Wish Tree


The program utilizes the features of JavaFX effect classes. The source code can be downloaded here. I will write a few articles to explain how to create such an application.

Comments (1) Jun 18 2009