License text

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER 
 * Copyright  2008, 2010 Oracle and/or its affiliates.  All rights reserved. 
 * Use is subject to license terms.
 * 
 * This file is available and licensed under the following license:
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 
 *   * Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer. 
 *
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 *   * Neither the name of Oracle Corporation nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software 
 *     without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

    

package brickbreaker;

import javafx.animation.*;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.*;

/**
 * @author Pavel Porvatov
 */

def STATE_SHOW_TITLE = 0;
def STATE_SHOW_STRIKE = 1;
def STATE_SUN = 2;

def SUN_AMPLITUDE_X = bind Config.screenWidth * 2 / 3;
def SUN_AMPLITUDE_Y = bind Config.screenHeight / 2;

public class Splash extends CustomNode {
    public function start() {
        background.requestFocus();

        timeline.play();
    }

    public function stop() {
        timeline.stop();
    }

    def background = ImageView {
        focusTraversable: true
        image: Config.images[Config.IMAGE_BACKGROUND]
        fitWidth: Config.screenWidth
        fitHeight: Config.screenHeight
        onMousePressed: function( e: MouseEvent ):Void {
            Main.mainFrame.startGame();
        }

        onKeyPressed: function( e: KeyEvent ):Void {
            Main.mainFrame.startGame();
        }
    }

    def brick: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BRICK]
        translateX: -1000
        translateY: bind brick.image.height
    }

    def brickShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BRICKSHADOW]
        translateX: -1000
    }

    def breaker = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BREAKER]
        translateX: -1000
        translateY: brick.translateY + brick.image.height * 5 /4
    }

    def breakerShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BREAKERSHADOW]
        translateX: -1000
    }

    def strike: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_STRIKE]
        translateY: bind brick.translateY -
            (strike.image.height - brick.image.height) / 2
        visible: false
    }

    def strikeShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_STRIKESHADOW]
        translateX: -1000
    }

    def pressanykey: ImageView = ImageView {
        def y = breaker.translateY + breaker.image.height;

        image: Config.images[Config.IMAGE_SPLASH_PRESSANYKEY]
        translateX: bind (Config.screenWidth - pressanykey.image.width) / 2
        translateY: y + (Config.screenHeight - y) / 2
        opacity: 0
    }

    def pressanykeyShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_PRESSANYKEYSHADOW]
        translateX: -1000
    }

    def sun: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_SUN]
        translateX: -1000
    }

    def NODES = [
        brick,
        breaker,
        strike,
        pressanykey
    ];

    def NODES_SHADOWS = [
        brickShadow,
        breakerShadow,
        strikeShadow,
        pressanykeyShadow
    ];

    var state = STATE_SHOW_TITLE;

    var stateArg = 0;

    def timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time: Config.ANIMATION_TIME

                action: function () {
                    if (state == STATE_SHOW_TITLE) {
                        stateArg++;

                        var center = Config.screenWidth / 2;
                        var offset = java.lang.Math.cos(stateArg / 4.0) *
                            (40 - stateArg) / 40 * center  as Integer;

                        brick.translateX = center - brick.image.width / 2 + offset;
                        breaker.translateX = center - breaker.image.width / 2 - offset;

                        if (stateArg == 40) {
                            stateArg = 0;
                            state = STATE_SHOW_STRIKE;
                        }

                        return;
                    }

                    if (state == STATE_SHOW_STRIKE) {
                        if (stateArg == 0) {
                            strike.translateX = breaker.translateX +
                                brick.image.width;
                            strike.scaleX = 0;
                            strike.scaleY = 0;
                            strike.visible = true;
                        }

                        stateArg++;

                        var coef = stateArg / 30.0;
                        brick.translateX = breaker.translateX +
                            (breaker.image.width - brick.image.width) / 2.0 *
                            (1 - coef);
                        strike.scaleX = coef;
                        strike.scaleY = coef;
                        strike.rotate = (30 - stateArg) * 2;

                        if (stateArg == 30) {
                            stateArg = 0;
                            state = STATE_SUN;
                        }

                        return;
                    }

                    // Here state == STATE_SUN
                    if (pressanykey.opacity < 1) {
                        pressanykey.opacity += 0.05
                    }

                    stateArg--;

                    var x = SUN_AMPLITUDE_X * java.lang.Math.cos(stateArg / 100.0);
                    var y = SUN_AMPLITUDE_Y * java.lang.Math.sin(stateArg / 100.0);

                    if (y < 0) {
                        for (node in NODES_SHADOWS) {
                            // Workaround RT-1976
                            node.translateX = -1000;
                        }

                        return;
                    }

                    var sunX = Config.screenWidth / 2 + x;
                    var sunY = Config.screenHeight / 2 - y;

                    sun.translateX = sunX - sun.image.width / 2;
                    sun.translateY = sunY - sun.image.height / 2;
                    sun.rotate = -stateArg;

                    for (i in [0..< sizeof NODES]) {
                        NODES_SHADOWS[i].opacity = y / SUN_AMPLITUDE_Y / 2;

                        NODES_SHADOWS[i].translateX = NODES[i].translateX +
                            (NODES[i].translateX + NODES[i].image.width / 2 - sunX) / 20;

                        NODES_SHADOWS[i].translateY = NODES[i].translateY +
                            (NODES[i].translateY + NODES[i].image.height / 2 - sunY) / 20;
                    }
                }
            }
        ]
    }

    override public function create(): Node {
        Group {
            content: [
                background,
                NODES_SHADOWS,
                NODES,
                sun
            ]
        };
    }
}