JavaFX Frozen Bubble Game

Posted: April 9th, 2009 under JavaFX Games.
Tags: , ,

Bookmark and Share

Liu Xuan, a Chinese programmer, had written a Frozen Bubble game in JavaFX. He is kind to allow me to share his code here. The game was originally developed in Perl/SDL. A java port is available too. Liu’s program implemented a simplified version of the Frozen Bubble game in JavaFX.


Click on the below button to start the game, use left/right arrow key to aim and space button to fire.








The key handling code is accomplished in the class Container:

public class Container extends CustomNode{
    public var bubbles = new HashMap();
    public var fadeBubbles: Bubble[];
    public var fallBubbles: Bubble[];
    public var gun: Gun = Gun{};
    public var shootAngle: Number;
    public var group: Group = Group {
        content: [
            // backgroud
            Rectangle {
                width: 320
                height: 480
                strokeWidth: 1
                stroke: Color.BLACK
                fill: LinearGradient {
                    startX: 0.0,
                    startY: 0.0,
                    endX: 0.0,
                    endY: 1.0
                    proportional: true
                    stops: [ Stop {
                            offset: 0.0
                            color: Color.YELLOWGREEN },
                        Stop {
                            offset: 1.0
                        color: Color.LIGHTBLUE } ]
                }
                onKeyPressed: function(e: KeyEvent):Void {
                      .......   // keyboard event handling
             }
            }
            gun
            //warning line
            Line {
                startX: 0,
                startY: Config.RED_LINE
                endX: 320
                endY: Config.RED_LINE
                strokeWidth: 1
                stroke: Color.RED
            }
            ImageView {
                  .......
            }
        ]
    };   

    public var inverseX = 1;   

    //semi-transparent layer for game over screen
    var layer = Rectangle {
        width: 320
        height: 480
        fill: Color.BLACK
        opacity: .4
    }
    var text = Text {
        content: "Press Enter To Start"
        font: Font {
            size: 20
        }
        x: 60
        y: 250
    }   

    // status of the game
    // 0 - game start and wait for shooting
    // 1 - bubble is moving
    // 2 - game over, the animation timeLine instanc
   // will stop at this value
    public var state = 2 on replace {
        if(state == 2) {
            timeline.stop();
            insert layer into group.content;
            insert text into group.content;
        }
    }   

    override public function create(): Node {
        group
    }   

   public function getLocation(row: Integer, col: Integer) : Point{
        var locationY = Config.ROW_SPACE * row;
        var locationX;
        if(row mod 2 == 0) {
            locationX = Config.BUBBLE_DIAMETER * col
        } else {
            locationX =
            Config.BUBBLE_DIAMETER * (col + .5) as Integer
        }
        return new Point(locationX, locationY)
    }   

   public function getAround(row: Integer, col: Integer): Bubble[] {
        var bArray: Bubble[] = [];
        var flag: Integer = 0;
        if(row mod 2 == 0) {
            flag = -1;
        }
        var bubble0 = getBubble(row, col - 1);
        var bubble1 = getBubble(row - 1, col + flag);
        var bubble2 = getBubble(row - 1, col + 1 + flag);
        var bubble3 = getBubble(row, col + 1);
        var bubble4 = getBubble(row + 1, col + flag);
        var bubble5 = getBubble(row + 1, col + 1 + flag);
        insert bubble0 into bArray;
        insert bubble1 into bArray;
        insert bubble2 into bArray;
        insert bubble3 into bArray;
        insert bubble4 into bArray;
        insert bubble5 into bArray;
        return bArray;
    }   

    public function getAround(bubble: Bubble): Bubble[] {
        var row: Integer = bubble.index.x;
        var col: Integer = bubble.index.y;
        return getAround(row, col);
    }

   public function getSameBubble(bubble: Bubble): Vector {
     var vector: Vector = new Vector();
     vector.add(bubble);
     var cursor = 0;
     while(
      cursor < vector.size()) {
        var bubbleInVector: Bubble =
        vector.get(cursor++) as Bubble;
        var aroundBubbles:Bubble[]=getAround(bubbleInVector);
        for(aroundBubble in aroundBubbles) {
          if ( aroundBubble != null
               and aroundBubble.color == bubble.color
               and vector.indexOf(aroundBubble) == - 1) {
               vector.add(aroundBubble);
                }
            }
        }
        return vector;
    }   

    public function getConnected(bubble: Bubble): Vector {
      var vector: Vector = new Vector();
      vector.add(bubble);
      var cursor = 0;
      while(cursor < vector.size()) {
        var bubbleInVector: Bubble =
        vector.get(cursor++) as Bubble;
        var aroundBubbles:Bubble[]=getAround(bubbleInVector);
        for(aroundBubble in aroundBubbles) {
            if ( aroundBubble != null
              and vector.indexOf(aroundBubble) == - 1) {
              vector.add(aroundBubble);
              }
            }
        }
        return vector;
    }   

  public function getIsolatedBubble(vector: Vector): Vector {
    var islatedBubble: Vector = new Vector();
      for(object in vector) {
        var sameBubble: Bubble = object as Bubble;
        var aroundBubbles:Bubble[] = getAround(sameBubble);
        for(aroundBubble in aroundBubbles) {
          if(aroundBubble != null) {
            var connectedBubble:Vector=getConnected(aroundBubble);
            var islate = true;
            for(col in [0..= 3) {
              for(object in vector) {
                var sameBubble: Bubble = object as Bubble;
                bubbles.remove(sameBubble.index);
                insert sameBubble into fadeBubbles;
              }
              for(object in getIsolatedBubble(vector)) {
                var islatedBubble: Bubble = object as Bubble;
                bubbles.remove(islatedBubble.index);
                insert islatedBubble into fallBubbles;
              }
            }
            state = 0;
            checkGameOver();
        }
    }   

    var timeCount = 0;   

    //moving, erasing, dropping the bubbles
    def timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames:[
            KeyFrame {
                time: 0.005s
                action: function() {
                    ......
                    checkGameOver();
                    .......
            //reduce the transparency to erase the bubbles
            for(fadeBubble in fadeBubbles) {
                fadeBubble.opacity -= .02;
                if(fadeBubble.opacity <= 0) {
                   fadeBubble.visible = false;
                   delete fadeBubble from fadeBubbles;
                   delete fadeBubble from group.content;
                   }
              }
              //drop those isolated bubbles
              for(fallBubble in fallBubbles) {
                fallBubble.locationY += 5;
                if(fallBubble.locationY >= 428) {
                   fallBubble.visible = false;
                   delete fallBubble from fallBubbles;
                   delete fallBubble from group.content;
                   }
                 }   

                if(state == 1) {
                        ......
                //rebounce and collision handling
                checkCollision(bubble);
                }
              }
            }
        ]
    }   

    // initialization
    public function gameStart():Void {
          .....
          timeline.play();
    }
}


Source code can be downloaded here. Please note that Liu Xuan has the copyright of the code.

Bookmark and Share

No Comments

No comments yet.

RSS feed for comments on this post.