Как мне связать пользовательский интерфейс игры с игровым шлейфом в JavaFx? - PullRequest
0 голосов
/ 25 июня 2018

Я новичок. Я делаю простую 2D-игру, используя JavaFx. У меня есть код основной игровой петли. Теперь я хочу создать полноценную игру, в которой я могу открыть стартовое окно, в котором есть новая игра, настройки и т.д. Я могу сделать простое окно интерфейса. Но у меня проблемы с запуском и закрытием игры, используя ее. я полностью запутался ... нужна помощь сейчас: (

Мой код:

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ColorRun extends Application {

private static final double KEYBOARD_MOVEMENT_DELTA = 5;
private static final double RECT_WIDTH = 200;
private static final double RECT_HEIGHT = 70;
private static final double RECT_MAX_Y = 800;

private static Rectangle createRectangle(double x) {
Rectangle rect = new Rectangle(x, 0, RECT_WIDTH, RECT_HEIGHT);
rect.setStroke(Color.BLACK);
rect.setArcWidth(10);
rect.setArcHeight(10);
return rect;
}

private final Random random = new Random();

private void randomizeColors(Rectangle[] rects, Circle circle, List<Color> 
colors) {
Collections.shuffle(colors, random);
for (int i = 0; i < rects.length; i++) {
    rects[i].setFill(colors.get(i));
}
circle.setFill(colors.get(random.nextInt(colors.size())));
}

@Override
public void start(Stage primaryStage) {
List<Color> colors = Arrays.asList(Color.RED, Color.GREEN, Color.BLUE, 
Color.YELLOW, Color.GREY);

Circle circle = new Circle(650, 700, 20);
Rectangle[] rectangles = new Rectangle[5];
for (int i = 0; i < rectangles.length; i++) {
    rectangles[i] = createRectangle(RECT_WIDTH * i);
}

Pane root = new Pane();
root.setPrefHeight(RECT_MAX_Y);
for (Rectangle rect : rectangles) {
    root.getChildren().add(rect);
}
root.getChildren().add(circle);

final double frameDuration = 16;
final double iterationDuration = 4000;
final int framesPerIteration = (int) (iterationDuration / frameDuration + 1);
randomizeColors(rectangles, circle, colors);

Timeline timeline = new Timeline();

class FrameHandler implements EventHandler<ActionEvent> {

    KeyCode code;
    private int frame = 1;

    @Override
    public void handle(ActionEvent event) {
        if (frame == 0) {
            randomizeColors(rectangles, circle, colors); // change colors 
when iteration is done
        }

        // move circle, if key is pressed
        if (code != null) {
            switch (code) {
                case RIGHT:
                    circle.setCenterX(circle.getCenterX() + 
KEYBOARD_MOVEMENT_DELTA);
                    break;
                case LEFT:
                    circle.setCenterX(circle.getCenterX() - 
KEYBOARD_MOVEMENT_DELTA);
                    break;
            }
        }

        // move rects & check intersection
        final Paint color = circle.getFill();
        final double cx = circle.getCenterX();
        final double cy = circle.getCenterY();
        final double r2 = circle.getRadius() * circle.getRadius();
        boolean lost = false;
        for (Rectangle rect : rectangles) {
            rect.setY(frame * RECT_MAX_Y / framesPerIteration);
            // check for intersections with rects of wrong color
            if (rect.getFill() != color) {

                double dy = Math.min(Math.abs(rect.getY() - cy),
                        Math.abs(rect.getY() + rect.getHeight() - cy));
                dy = dy * dy;

                if (dy > r2) {
                    continue; // y-distance too great for intersection
                }
                if (cx >= rect.getX() && cx <= rect.getX() + rect.getWidth()) 
{
                    lost = true;
                } else {
                    double dx = Math.min(Math.abs(rect.getX() - cx),
                            Math.abs(rect.getX() + rect.getWidth() - cx));
                    if (dx * dx + dy <= r2) {
                        lost = true;
                    }
                }
            }
        }
        frame = (frame + 1) % framesPerIteration;
        if (lost) {
            timeline.stop();
        }

    }
}

FrameHandler frameHandler = new FrameHandler();

Scene scene = new Scene(root);

// keep track of the state of the arrow keys
scene.setOnKeyPressed(evt -> {
    KeyCode code = evt.getCode();
    switch (code) {
        case RIGHT:
        case LEFT:
            frameHandler.code = code;
            break;
    }
});
scene.setOnKeyReleased(evt -> {
    KeyCode code = evt.getCode();
    if (frameHandler.code == code) {
        frameHandler.code = null;
    }
});

primaryStage.setScene(scene);

timeline.getKeyFrames()
        .add(new KeyFrame(Duration.millis(frameDuration), frameHandler));
timeline.setCycleCount(Timeline.INDEFINITE);

timeline.play();

primaryStage.show();
}


public static void main(String[] args) {
    launch(args);

}
}

1 Ответ

0 голосов
/ 25 июня 2018

Итак, я протестировал приложение (было очень круто для начинающего приложения), подумал, что я бы настроил несколько кнопок, чтобы помочь вам начать, вы должны проверить некоторые учебники о более продвинутых играх, на которые я бы обратил внимание (как в учебниках)кроме всего прочего, настройте их главные экраны, и на ваш вопрос можно ответить очень широко, но я не хотел, чтобы вы расстраивались и прекратили кодировать.Когда вы приходите к переполнению стека, попробуйте придумать точный вопрос о том, что пошло не так, кроме того, что я не могу запустить и закрыть игру, попробуйте решить некоторые проблемы в вашем собственном Google для примеров кода и посмотреть, что другие сделали и какони решили это, или как учебники сделали это. Также посмотрите вокруг Google некоторые вещи о приложениях для начинающих игр, и вы скоро поймете, что это может быть структурировано намного лучше. Я не собирался, чтобы эти кнопки выглядели хорошо, но только для того, чтобы функционировать удачи и счастьякодирование

PS мои комментарии внутри того, что я добавил

private static final double KEYBOARD_MOVEMENT_DELTA = 5;
private static final double RECT_WIDTH = 200;
private static final double RECT_HEIGHT = 70;
private static final double RECT_MAX_Y = 800;

private static Rectangle createRectangle(double x) {
    Rectangle rect = new Rectangle(x, 0, RECT_WIDTH, RECT_HEIGHT);
    rect.setStroke(Color.BLACK);
    rect.setArcWidth(10);
    rect.setArcHeight(10);
    return rect;
}

private final Random random = new Random();

private void randomizeColors(Rectangle[] rects, Circle circle, List<Color> colors) {
    Collections.shuffle(colors, random);
    for (int i = 0; i < rects.length; i++) {
        rects[i].setFill(colors.get(i));
    }
    circle.setFill(colors.get(random.nextInt(colors.size())));
}

@Override
public void start(Stage primaryStage) {
    List<Color> colors = Arrays.asList(Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.GREY);

    Circle circle = new Circle(650, 700, 20);
    Rectangle[] rectangles = new Rectangle[5];
    for (int i = 0; i < rectangles.length; i++) {
        rectangles[i] = createRectangle(RECT_WIDTH * i);
    }

    Pane root = new Pane();
    root.setPrefHeight(RECT_MAX_Y);
    for (Rectangle rect : rectangles) {
        root.getChildren().add(rect);
    }
    root.getChildren().add(circle);

//Here is where I added 2 buttons
    //Added Restart Button
    Button restartButton = new Button("Restart");
    restartButton.setVisible(false); //set to false so you cannot see them when playing
    //Added Quit button
    Button quitButton = new Button("Quit");
    quitButton.setVisible(false);
    restartButton.setLayoutY(30);

    final double frameDuration = 16;
    final double iterationDuration = 4000;
    final int framesPerIteration = (int) (iterationDuration / frameDuration + 1);
    randomizeColors(rectangles, circle, colors);

    Timeline timeline = new Timeline();

    class FrameHandler implements EventHandler<ActionEvent> {
        private KeyCode code;
        private int frame = 1;
        public boolean lost = false;
//Here I created a lost action which will run when you lose
        private void lostAction(){
            timeline.stop();
            restartButton.setVisible(true);
            quitButton.setVisible(true);
        }
        @Override
        public void handle(ActionEvent event) {
            if (frame == 0) {
                randomizeColors(rectangles, circle, colors); // change colors when iteration is done
            }

            // move circle, if key is pressed
            if (code != null) {
                switch (code) {
                    case RIGHT:
                        circle.setCenterX(circle.getCenterX() +
                                KEYBOARD_MOVEMENT_DELTA);
                        break;
                    case LEFT:
                        circle.setCenterX(circle.getCenterX() -
                                KEYBOARD_MOVEMENT_DELTA);
                        break;
                }
            }

            // move rects & check intersection
            final Paint color = circle.getFill();
            final double cx = circle.getCenterX();
            final double cy = circle.getCenterY();
            final double r2 = circle.getRadius() * circle.getRadius();
            for (Rectangle rect : rectangles) {
                rect.setY(frame * RECT_MAX_Y / framesPerIteration);
                // check for intersections with rects of wrong color
                if (rect.getFill() != color) {

                    double dy = Math.min(Math.abs(rect.getY() - cy),
                            Math.abs(rect.getY() + rect.getHeight() - cy));
                    dy = dy * dy;

                    if (dy > r2) {
                        continue; // y-distance too great for intersection
                    }
                    if (cx >= rect.getX() && cx <= rect.getX() + rect.getWidth())
                    {
                        lost = true;
                    } else {
                        double dx = Math.min(Math.abs(rect.getX() - cx),
                                Math.abs(rect.getX() + rect.getWidth() - cx));
                        if (dx * dx + dy <= r2) {
                            lost = true;
                        }
                    }
                }
            }
            frame = (frame + 1) % framesPerIteration;
            if (lost) {
                lostAction();//This was altered to point at lost function
            }
        }
    }

    FrameHandler frameHandler = new FrameHandler();

    Scene scene = new Scene(root);// keep track of the state of the arrow keys
    scene.setOnKeyPressed(evt -> {
        KeyCode code = evt.getCode();
        switch (code) {
            case RIGHT:
            case LEFT:
                frameHandler.code = code;
                break;
        }
    });
    scene.setOnKeyReleased(evt -> {
        KeyCode code = evt.getCode();
        if (frameHandler.code == code) {
            frameHandler.code = null;
        }
    });
//Here is where I added the actions of the buttons
    //Resets variables in order to keep playing
    restartButton.setOnAction(event -> {
        frameHandler.lost = !frameHandler.lost;
        frameHandler.frame=0;
        timeline.play();
        restartButton.setVisible(false);
        quitButton.setVisible(false);
    });
    //This will let you leave without it you will play forever
    quitButton.setOnAction(event -> {
        System.exit(0);
    });
    root.getChildren().addAll(restartButton, quitButton);

    primaryStage.setScene(scene);

    timeline.getKeyFrames().add(new KeyFrame(Duration.millis(frameDuration), frameHandler));
    timeline.setCycleCount(Timeline.INDEFINITE);
    timeline.play();

    primaryStage.show();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...