How to Write Pac-Man Game in JavaFX(5)

Posted: under JavaFX Technology, pac-man.
Tags: , , ,

Yesterday, my last article of a series, “Writing the Pac-Man Game in JavaFX Part 5“, had been published on insiderRIA.com. This final article detailed the chasing algorithms of the ghosts. I think it is probably one of the most interesting things in the code.


When writing the game, there are a few points we need to consider before designing an algorithm of the ghosts, such as effectiveness, randomness, simplicity. You can refer to the article about considerations on these aspects. An excerpt from the article is listed below in blue text. It discussed the choice of a proper algorithm. This algorithm not only serves as the chasing logic, it can also control the escaping behavior of the ghosts.


. . . . . .
After some thinking, I found that the distance between a ghost and the Pac-Man is a good ranking metric. The shorter the distance is, the higher the score is given to a particular choice. The advantages of using the distance as a metric are obvious. It is very simple and can be caculated easily. Besides, this algorithm makes a ghost move in the direction that has the shortest distance to thePac-Man. To illustrate this algorithm, let’s look at the below figure.

In the figure, the ghost Blinky is moving into an intersection from the right to the left. When it reaches the intersection, it has three possible choices of its next movement: to go up, to go down and to continue heading left. Going down is not a valid move because it hits the border of the maze. So we need to compare the other two options. The below table shows the computation of the distance of the two possible moves:

Choice X distance Y distance Total
Intersection 3 10 13
Up 3 9 12
Left 4 10 14

As shown in the table, the distance from the intersection to the Pac-Man character is 13 (The distance between two adjacent dots is 1). If Blinky goes up, the distance is reduced to 12. If it heads left, the distance becomes 14. Therefore, going up seems a better choice for Blinky. In this way, Blinky should be able to get closer and closer to the Pac-Man and eventually catches him.


Of course, this simple algorithm does not take into consideration for the walls in the maze. For this reason, sometimes the calculated score does not in fact represent the shortest path. However, this inaccuracy makes the ghosts appear “stupid” in the game, which is the randomness we want to achieve in the behavior. So we are going to implement it in our code. We rewrite the class MoveDecision. When the function evaluate() calculates a score, it takes in two arguments: the reference to Pac-Man instance and whether the ghost is in a hollow state. The variable distance is used to compute the score. If the ghost is going after the Pac-Man character, the score is 500-distance, which means a shorter distance yields a higher score. If the Pac-Man is hunting the ghosts(when they are hollow), the score is caculated as 500+distance. This makes the ghosts running away from the Pac-Man.
. . . . . .


Now that all the articles had been published and I hope you enjoyed reading them. The game was originally written in JavaFX 1.0, and was compatible with JavaFX 1.1. Because multi-inheritance has been removed in JavaFX 1.2, I made some minor changes to the code. The abstract class MovingObject had been changed to mixin class. The code for JavaFX 1.2 can be download from JavaFX Game Download Page.


You can now click on the below image to play the completed Pac-Man game, it is based on the newly released JavaFX 1.2 . With the improved performance, the game runs very smoothly.


click to run

click to run

Related Articles:

Develop Games in JavaFX

JavaFX MineSweeper Demo Game

JavaFX Demo Game: LinkUP

WidgetFX Game Widgets: Pac-Man

My First JavaFX Game Demo

JavaFX Discussion Blogs

JavaFX Game Article

The Featured Articles on insideRIA.com:

May 14, 2009: Writing the Pac-Man Game in JavaFX - Part 1

May 21, 2009: Writing the Pac-Man Game in JavaFX - Part 2

May 28, 2009: Writing the Pac-Man Game in JavaFX - Part 3

June 4, 2009: Writing the Pac-Man Game in JavaFX - Part 4

June 11, 2009:Writing the Pac-Man Game in JavaFX - Part 5

Comments (0) Jun 13 2009

Pac-Man Widget for WidgetFX 1.2

Posted: under JavaFX News, JavaFX Technology, pac-man.
Tags: , , ,

To fully take advantage of the power of JavaFX 1.2, Stephen Chin just released the WidgetFX 1.2 API beta version. There is even a widget contest running until the end of July. [Update: Steve had released the WidgetFX 1.2 version on June 29. ]


Just before the JavaOne 2009, Jim Weaver asked me to write a widget for my JavaFX Pac-man game. The WidgetFX API was quite simple to use, so I finished it pretty soon. The game widget later got demo-ed on Jim and Steve’s JavaOne sessions. There was a small problem of the pac-man widget: it run relatively slow due to the performance issue of JavaFX 1.1. Since JavaFX 1.2 and WidgetFX 1.2 are ready now, I am modifying the code to see the improvement on performance.


First, the JavaFX code of the Pac-Man game needs to be modified a little bit for JavaFX 1.2. Since multi inheritance is gone, we need to use mixin classes now. You can refer to my articles on insideRIA.com for details of the code. Changes for JavaFX 1.2 were given on comments of Article 4 by Patrick Webster. I also added in a pausing key(”P” button) handling for the game. I compiled the game into a pacman.jar file.


The next step is to write the widget. Actually, the code is quite simple if you do not have stuffs like configuartion etc. Let’s look at the code below:

/*
 * PacManWidget.fx
 * http://www.javafxgame.com
 */

package pacmanwidget;

import org.widgetfx.Widget;

/**
 * @author Henry Zhang
 */

def defaultWidth = 528.0;
def defaultHeight = 576.0;

def maze =  pacman.Maze {};

var widget:Widget = Widget {
    width: defaultWidth
    height: defaultHeight
    aspectRatio: defaultWidth / defaultHeight
    content: maze
    resizable: false

    onDock: function():Void {
       maze.pauseGame();
    }
}

return widget;

In the standalone game, an instance of the Maze class was put into the content variable of a Stage. Now, instead of putting it into a Stage, we add it into a Widget. To do this, we can just set the content variable of a Widget instance. Other attributes of the Widget class are quite straightforward, mostly for resizing purposes. The next thing is to write a onDock() function to pause the game when the widget gets docked. The game can be resumed after pressing the “p” button when it is undocked.


The last thing is to deploy it on a web server. We need a JNLP file. Be sure to write the jnlp file of the JavaFX 1.2 style. Netbeans can generate the JNLP file which we can modify for deployment. I listed below part of my jnlp file. Besides the widget code PacManWidget.jar, there are supporting jar files( pacman.jar and WidgetFX-API.jar) under the /lib folder as well. Notice that there is a bug in the generated JNLP file by NetBeans 6.5.1: the <update> tag is missing a slash(/) at the end of the tag.


 . . . . . .
 <resources>
     <j2se version="1.5+" />
     <extension name="JavaFX Runtime"
        href="http://dl.javafx.com/1.2/javafx-rt.jnlp"/>
     <jar href="PacManWidget.jar" main="true"/>
     <jar href="lib/pacman.jar"/>
     <jar href="lib/WidgetFX-API.jar"/>
 </resources>
 <application-desc main-class="com.sun.javafx.runtime.main.Main">
    <argument>MainJavaFXScript=pacmanwidget.PacManWidget</argument>
 </application-desc>
 <update check="background" />
 . . . . . .


Now, you can click on the below button to start the Pac-man widget for JavaFX 1.2. Enjoy!


Pac-Man Widget 1.2



Comments (3) Jun 08 2009

How to Write a Pac-Man Game in JavaFX (4)

Posted: under pac-man.
Tags: , , ,

My latest article of the series, “Writing the Pac-Man Game in JavaFX Part 4“, was out on June 4.


In this article, the interaction between Pac-Man character and the ghosts was introduced in detail. The article showed how to determine whether the Pac-man character and a ghost touched each other. A simplified formla was applied to achieve better performance. When Pac-man touches a ghost, he can eat it if the ghost is hollow. The ghost then is thrown back to the cage again. Otherwise, the ghost eats the Pac-man. An animation of showing a dying Pac-Man appears at this moment. This is in fact a shrinking circle(Arc) which disappears at the end of the animation. The animation is accomplished by the DyingPacMan class.


The below figure depicts the animation process of the dying Pac-man character.

shriking pac-man


The code of DyingPacMan.fx is listed below:

/*
 * DyingPacMan.fx
 *
 * Created on 2009-2-6, 17:52:42
 */
package pacman;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.shape.Arc;

/**
 * @author Henry Zhang
 */
public class DyingPacMan extends Arc {
   public var maze : Maze;

   var timeline = Timeline {
      repeatCount: 1
      keyFrames: [
        KeyFrame {
           time: 600ms
           action: function() {
             // hide the pacMan character and ghosts before the animation
              maze.pacMan.visible = false;

              for ( g in maze.ghosts ) {
                 g.hide();
               }

              visible = true;
            }
           values: [ startAngle => 90, length=>360 ];
         },
        KeyFrame {
           time: 1800ms
           action: function() {
              visible = false;
            }
           values: [ startAngle => 270 tween Interpolator.LINEAR,
                     length => 0 tween Interpolator.LINEAR ]
         },
      ]
    }

   public function startAnimation(x: Number, y: Number) : Void {
      startAngle = 90;
      centerX = x;
      centerY = y;

      timeline.play();
    }
}

Interpolations of two variables, startAngle and length, are involved during the animation. To better illustrate this process, the below figure shows the change of the shape against a timeline.

timeline pac-man


Hope you enjoy reading the articles. You can use arrow keys to play the current version of the game. The ghosts are moving randomly which makes the game less challenging. In the next article, I will introduced a better algorithm. Try it by clicking the below screenshot:


click to run

click to run


Related Articles:

Develop Games in JavaFX

My JavaFX Demo Game: Pac-Man

Comments (0) Jun 06 2009

Challenge on Pac-Man Game Widget

Posted: under JavaFX Games, pac-man.
Tags: , , ,

During the weekend, JavaFX expert Jim Weaver had laid a challenge on me to create a WidgetFX widget of the Pac-Man Game, a JavaFX demo game that I introduced in insiderRIA.com. The author of WidgetFX, Stephen Chin even offered to show it in JavaOne if I can finished in time(before June 2-3). With about one week to go, I think it is interesting and fun to give it a try. I will keep track of my progress in this post.


I have installed the WidgetFX package before, but to get a clean start, I re-downloaded the source code from Widgetfx.org. Here is my progress: (updated continuously)



May 24:
Downloaded source code from http://code.google.com/p/widgetfx/downloads/list. Clicked on the Launch Dock link on the front page of widgetfx.org and it run successfully on my computer(Windows XP, with JDK 1.6U13). Read some document from project home. Try to look at some WidgetFX samples, but couldn’t find most of the source code. Anyway, it is not bad for the first day.


May 25:
Got Steve’s response with a tutorial on Calendar widget. This tutorial is quite helpful. From that example, I learnt that the widget container is fundamentally a Stage Class. That’s great! We can put everything into an instance of Group and then put the Group into the Widget class. Because in my Pac-Man Game, I only have a Maze instance in the Stage class, this becomes quite simple now. I quickly modified the Calendar example and put my Maze instance into the Widget. After adjusting the width and height, it was just simply working! (see the image on the left)

Further testing showed that I needed to write some code to handle the docking and resizing events. I will read some more documents and find out more details tomorrow.


May 26:

Steve provided some useful hints on how to deal with the resizing of the widget. It looks like the WidgetFX API is quite intelligent on resizing the window. What I need to do is to define default width/height and aspectRatio and everything else will be taken care of. I modified my original Pac-Man code to allow the game to be paused. Now the game is fully working as a widget. When it is docked, the game will be automatically paused. When it is undocked, it zooms to its original size and the player can press ‘P’ button to continue playing. Click on the below button to see how the Pac-Man widget looks like:


Pac-Man Widget (JavaFX 1.1)


or try widget for WidgetFX 1.2 version

Pac-Man Widget 1.2


Some issues remains: the game is kind of slow on my laptop(single core, 1.6Ghz Intel, WinXP). I am checking with Steve to see if he has any suggestions.



Comments (5) May 25 2009

How to Write a Pac-Man Game in JavaFX (2)

Posted: under JavaFX Games, pac-man.
Tags: , ,

The 2nd article of the series, “Writing the Pac-Man Game in JavaFX“, is published today.

The first article introduced a data model in Java and the JavaFX drawing logic of the maze. In the 2nd article, the animation part of the Pac-Man character is detailed. When you are reading, you can click on the java web start links to see the Pac-Man opening and closing mouths, and gradually moving inside the maze. The keyboard handling code is illustrated as well.

Some JavaFX features demostrated in these two articles include:

. shapes
. keyboard handling
. animation timeline
. java code integration
. Transfromation

Hope you can enjoy reading the articles. You can use arrow keys to play a no-ghost version of the game. The Pac-Man character now can move around and gobble dots. Try it by clicking the below screenshot:

click to run

click to run
Related Articles:

Develop Games in JavaFX

My JavaFX Demo Game: Pac-Man

Comments (0) May 22 2009

How to Write the Pac-Man Game with JavaFX

Posted: under JavaFX Games, JavaFX Technology, pac-man.
Tags: ,

After the official announcement of JavaFX 1.0, I wrote a JavaFX program for the Pac-Man game. People were interested in the game. They either enjoyed playing or asked me for the details fo the JavaFX code. JavaFX expert Jim Weaver asked me to write some articles about the process of building the game. After a few weeks’ hard work, with Jim’s constructive ideas and great help in proofreading, I finished the articles. Now they are published on nsideRIA.com, an O’Reilly’s web site, as featured articles. There will be 5 articles in total and they will run through the coming 5 weeks.

In each of the articles, there are web start links that you can click to start a JavaFX program to see how it works. If you follow the 5 articles, you will find out how the game is written bit by bit. I hope the articles can help people who want to learn JavaFX or want to develop games in JavaFX. Thanks Jim for making these articles possible.

Here are the links for the articles:

May 14, 2009:
Writing the Pac-Man Game in JavaFX - Part 1
May 21, 2009:
Writing the Pac-Man Game in JavaFX - Part 2
May 28, 2009:
Writing the Pac-Man Game in JavaFX - Part 3
June 4, 2009:
Writing the Pac-Man Game in JavaFX - Part 4
June 11, 2009:
Writing the Pac-Man Game in JavaFX - Part 5

Related Posts:
First JavaFX Demo Game: PACMAN

Articles on Writing JavaFX Pac-Man Game

JavaFX Demo Game: PAC-MAN

Comments (1) May 17 2009