private void initTimeline() {
        timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        KeyFrame kf = new KeyFrame(Config.ANIMATION_TIME, new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                if (state == STATE_SHOW_TITLE) {
                    stateArg++;
                    int center = Config.SCREEN_WIDTH / 2;
                    int offset = (int)(Math.cos(stateArg / 4.0) * (40 - stateArg) / 40 * center);
                    brick.setTranslateX(center - brick.getImage().getWidth() / 2 + offset);
                    breaker.setTranslateX(center - breaker.getImage().getWidth() / 2 - offset);
                    if (stateArg == 40) {
                        stateArg = 0;
                        state = STATE_SHOW_STRIKE;
                    }
                    return;
                }
                if (state == STATE_SHOW_STRIKE) {
                    if (stateArg == 0) {
                        strike.setTranslateX(breaker.getTranslateX() + brick.getImage().getWidth());
                        strike.setScaleX(0);
                        strike.setScaleY(0);
                        strike.setVisible(true);
                    }
                    stateArg++;
                    double coef = stateArg / 30f;
                    brick.setTranslateX(breaker.getTranslateX() +
                        (breaker.getImage().getWidth() - brick.getImage().getWidth()) / 2f * (1 - coef));
                    strike.setScaleX(coef);
                    strike.setScaleY(coef);
                    strike.setRotate((30 - stateArg) * 2);
                    if (stateArg == 30) {
                        stateArg = 0;
                        state = STATE_SUN;
                    }
                    return;
                }
                // Here state == STATE_SUN
                if (pressanykey.getOpacity() < 1) {
                    pressanykey.setOpacity(pressanykey.getOpacity() + 0.05f);
                }
                stateArg--;
                double x = SUN_AMPLITUDE_X * Math.cos(stateArg / 100.0);
                double y = SUN_AMPLITUDE_Y * Math.sin(stateArg / 100.0);
                if (y < 0) {
                    for (Node node : NODES_SHADOWS) {
                        // Workaround RT-1976
                        node.setTranslateX(-1000);
                    }
                    return;
                }
                double sunX = Config.SCREEN_WIDTH / 2 + x;
                double sunY = Config.SCREEN_HEIGHT / 2 - y;
                sun.setTranslateX(sunX - sun.getImage().getWidth() / 2);
                sun.setTranslateY(sunY - sun.getImage().getHeight() / 2);
                sun.setRotate(-stateArg);
                for (int i = 0; i < NODES.length; i++) {
                    NODES_SHADOWS[i].setOpacity(y / SUN_AMPLITUDE_Y / 2);
                    NODES_SHADOWS[i].setTranslateX(NODES[i].getTranslateX() +
                        (NODES[i].getTranslateX() + NODES[i].getImage().getWidth() / 2 - sunX) / 20);
                    NODES_SHADOWS[i].setTranslateY(NODES[i].getTranslateY() +
                        (NODES[i].getTranslateY() + NODES[i].getImage().getHeight() / 2 - sunY) / 20);
                }
            }
        });
        timeline.getKeyFrames().add(kf);
    }