FXGL attempts
This commit is contained in:
parent
2fbb541790
commit
fd5d3ca2a4
391
src/main/java/com/openeggbert/core/OpenEggbertApp.java
Normal file
391
src/main/java/com/openeggbert/core/OpenEggbertApp.java
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Open Eggbert: Free recreation of the computer game Speedy Eggbert.
|
||||||
|
// Copyright (C) 2024 the original author or authors.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation, either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see
|
||||||
|
// <https://www.gnu.org/licenses/> or write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
package com.openeggbert.core;
|
||||||
|
|
||||||
|
import com.almasb.fxgl.app.ApplicationMode;
|
||||||
|
import com.almasb.fxgl.app.GameApplication;
|
||||||
|
import com.almasb.fxgl.app.GameSettings;
|
||||||
|
import com.almasb.fxgl.core.collection.PropertyMap;
|
||||||
|
import com.almasb.fxgl.dsl.FXGL;
|
||||||
|
import com.almasb.fxgl.entity.Entity;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.almasb.fxgl.dsl.FXGL.*;
|
||||||
|
import com.almasb.fxgl.entity.components.CollidableComponent;
|
||||||
|
import com.almasb.fxgl.physics.CollisionHandler;
|
||||||
|
import com.openeggbert.entity.common.EntityType;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import javafx.geometry.Rectangle2D;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.scene.shape.Circle;
|
||||||
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mail@robertvokac.com">Robert Vokac</a>
|
||||||
|
* @since 0.0.0
|
||||||
|
*/
|
||||||
|
public class OpenEggbertApp extends GameApplication {
|
||||||
|
|
||||||
|
private Entity player;
|
||||||
|
private Entity coin;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initSettings(GameSettings settings) {
|
||||||
|
settings.setWidth(640);
|
||||||
|
settings.setHeight(480);
|
||||||
|
settings.setTitle("Open Eggbert");
|
||||||
|
settings.setVersion("0.0.0-SNAPSHOT");
|
||||||
|
settings.setApplicationMode(ApplicationMode.DEVELOPER);
|
||||||
|
}
|
||||||
|
private static int r = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initInput() {
|
||||||
|
int width = Companion.getAppWidth();
|
||||||
|
int height = Companion.getAppHeight();
|
||||||
|
PropertyMap state = FXGL.getWorldProperties();
|
||||||
|
// if(state.keys().contains("x")) {
|
||||||
|
// int x = state.getInt("x");
|
||||||
|
// int y = state.getInt("y");
|
||||||
|
|
||||||
|
onKey(KeyCode.RIGHT, () -> {
|
||||||
|
checkXAndMovePlayerIfNeeded();
|
||||||
|
player.translateX(move); // move right 5 pixels
|
||||||
|
inc("pixelsMoved", +move);
|
||||||
|
inc("x", +move);
|
||||||
|
r++;
|
||||||
|
System.out.println("Pressed RIGHT " + r);
|
||||||
|
lastPress = System.nanoTime();
|
||||||
|
if (lastStart == 0) {
|
||||||
|
lastStart = lastPress;
|
||||||
|
} else {
|
||||||
|
if (move < 20) {
|
||||||
|
move = move + 4;
|
||||||
|
}
|
||||||
|
if ((lastPress - lastStart) > 5000000000l) {
|
||||||
|
// move = 5;
|
||||||
|
lastStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onKey(KeyCode.LEFT, () -> {
|
||||||
|
checkXAndMovePlayerIfNeeded();
|
||||||
|
player.translateX(-move); // move left 5 pixels
|
||||||
|
inc("pixelsMoved", -move);
|
||||||
|
inc("x", -move);
|
||||||
|
lastPress = System.nanoTime();
|
||||||
|
if (lastStart == 0) {
|
||||||
|
lastStart = lastPress;
|
||||||
|
} else {
|
||||||
|
if (move < 20) {
|
||||||
|
move++;
|
||||||
|
}
|
||||||
|
if ((lastPress - lastStart) > 5000000000l) {
|
||||||
|
// move = 5;
|
||||||
|
lastStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onKey(KeyCode.UP, () -> {
|
||||||
|
checkYAndMovePlayerIfNeeded();
|
||||||
|
player.translateY(-move); // move up 5 pixels
|
||||||
|
inc("pixelsMoved", +move);
|
||||||
|
inc("y", -move);
|
||||||
|
lastPress = System.nanoTime();
|
||||||
|
if (lastStart == 0) {
|
||||||
|
lastStart = lastPress;
|
||||||
|
} else {
|
||||||
|
if (move < 20) {
|
||||||
|
move++;
|
||||||
|
}
|
||||||
|
if ((lastPress - lastStart) > 5000000000l) {
|
||||||
|
// move = 5;
|
||||||
|
lastStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onKey(KeyCode.DOWN, () -> {
|
||||||
|
checkYAndMovePlayerIfNeeded();
|
||||||
|
player.translateY(move); // move down 5 pixels
|
||||||
|
inc("pixelsMoved", -move);
|
||||||
|
inc("y", +move);
|
||||||
|
lastPress = System.nanoTime();
|
||||||
|
if (lastStart == 0) {
|
||||||
|
lastStart = lastPress;
|
||||||
|
} else {
|
||||||
|
if (move < 20) {
|
||||||
|
move++;
|
||||||
|
}
|
||||||
|
if ((lastPress - lastStart) > 5000000000l) {
|
||||||
|
// move = 5;
|
||||||
|
lastStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private static int move = 5;
|
||||||
|
private static long lastPress = 0l;
|
||||||
|
private static long lastStart = 0l;
|
||||||
|
|
||||||
|
private void checkXAndMovePlayerIfNeeded() {
|
||||||
|
double diff = player.getX() - coinX;
|
||||||
|
if (diff < 300 && diff > 0) {
|
||||||
|
move = 10;
|
||||||
|
|
||||||
|
coin.translateX((diff < 0 ? 1 : (-1)) * randomNumberSource.apply(2, 8));
|
||||||
|
coinX = coin.getX();
|
||||||
|
if (coinX < 20) {
|
||||||
|
coin.setX(620);
|
||||||
|
}
|
||||||
|
if (coinX > 620) {
|
||||||
|
coin.setX(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != null && player.getX() < 0) {
|
||||||
|
player.setX(620);
|
||||||
|
inc("x", (int) (620 + (-player.getX())));
|
||||||
|
}
|
||||||
|
if (player != null && player.getX() > 640) {
|
||||||
|
player.setX(20);
|
||||||
|
inc("x", (int) (20 - player.getX()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkYAndMovePlayerIfNeeded() {
|
||||||
|
double diff = player.getY() - coinY;
|
||||||
|
|
||||||
|
if (diff < 300 && diff > 0) {
|
||||||
|
move = 10;
|
||||||
|
coin.translateY((diff < 0 ? 1 : (-1)) * randomNumberSource.apply(2, 8));
|
||||||
|
coinY = coin.getY();
|
||||||
|
|
||||||
|
if (coinY < 20) {
|
||||||
|
coin.setY(460);
|
||||||
|
}
|
||||||
|
if (coinY > 460) {
|
||||||
|
coin.setY(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != null && player.getY() < 0) {
|
||||||
|
player.setY(460);
|
||||||
|
inc("y", (int) (460 + (-player.getY())));
|
||||||
|
}
|
||||||
|
if (player != null && player.getY() > 480) {
|
||||||
|
player.setY(20);
|
||||||
|
inc("y", (int) (20 - player.getY()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initGameVars(Map<String, Object> vars) {
|
||||||
|
vars.put("pixelsMoved", 0);
|
||||||
|
vars.put("x", 0);
|
||||||
|
vars.put("y", 0);
|
||||||
|
vars.put("coins", 0);
|
||||||
|
vars.put("seconds", 0);
|
||||||
|
getGameTimer().runAtInterval(() -> {
|
||||||
|
inc("seconds", +1);
|
||||||
|
}, Duration.seconds(1));
|
||||||
|
|
||||||
|
getGameTimer().runAtInterval(() -> {
|
||||||
|
if (coin != null && coin.isActive()) {
|
||||||
|
|
||||||
|
double translateX = (Math.random() > 0.5 ? 1 : (-1)) * randomNumberSource.apply(2, 10);
|
||||||
|
double newX = coinX + translateX;
|
||||||
|
if (newX < 10) {
|
||||||
|
translateX = 20;newX = coinX + translateX;
|
||||||
|
}
|
||||||
|
if (newX > 460) {
|
||||||
|
translateX = -20;newX = coinX + translateX;
|
||||||
|
}
|
||||||
|
coinX = newX;
|
||||||
|
coin.translateX(translateX);
|
||||||
|
|
||||||
|
|
||||||
|
double translateY = (Math.random() > 0.5 ? 1 : (-1)) * randomNumberSource.apply(2, 10);
|
||||||
|
double newY = coinY + translateY;
|
||||||
|
if (newY < 10) {
|
||||||
|
translateY = 20;newY = coinY + translateY;
|
||||||
|
}
|
||||||
|
if (newY > 630) {
|
||||||
|
translateX = -20;newY = coinY + translateY;
|
||||||
|
}
|
||||||
|
coinY = newY;
|
||||||
|
coin.translateY((Math.random() > 0.5 ? 1 : (-1)) + randomNumberSource.apply(2, 10));
|
||||||
|
}
|
||||||
|
}, Duration.millis(20));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiFunction<Integer, Integer, Integer> randomNumberSource = (min, max) -> (min + ((int) (Math.random() * (max < min ? min : (max - min)))));
|
||||||
|
|
||||||
|
private static double currentX, currentY, coinX, coinY;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initGame() {
|
||||||
|
int rectancleSide = 10 + ((int) (Math.random() * 40d));
|
||||||
|
Supplier<Integer> randomByteSupplier = () -> (randomNumberSource.apply(0, 255));
|
||||||
|
|
||||||
|
PropertyMap state = FXGL.getWorldProperties();
|
||||||
|
|
||||||
|
final double x = Math.random() * 600;
|
||||||
|
final double y = Math.random() * 400;
|
||||||
|
state.setValue("x", (int) x);
|
||||||
|
state.setValue("y", ((int) y));
|
||||||
|
|
||||||
|
ImageView blupiView = createBlupiView();
|
||||||
|
|
||||||
|
player = entityBuilder()
|
||||||
|
.type(EntityType.PLAYER)
|
||||||
|
.at(x, y)
|
||||||
|
// .viewWithBBox(new Rectangle(rectancleSide, rectancleSide, Color.rgb(
|
||||||
|
// randomByteSupplier.get(),
|
||||||
|
// randomByteSupplier.get(),
|
||||||
|
// randomByteSupplier.get()
|
||||||
|
// )))
|
||||||
|
.viewWithBBox(blupiView)
|
||||||
|
// .viewWithBBox("brick.png")
|
||||||
|
.with(new CollidableComponent(true))
|
||||||
|
.buildAndAttach();
|
||||||
|
|
||||||
|
spawnNewCoin();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Circle createCoin() {
|
||||||
|
int value = random(1, 5);
|
||||||
|
final Circle circle = new Circle(15, 15, 15 + value, Color.YELLOW);
|
||||||
|
final Text text = new Text(String.valueOf(value));
|
||||||
|
final StackPane stack = new StackPane();
|
||||||
|
stack.getProperties().put("coinValue", value);
|
||||||
|
circle.getProperties().put("coinValue", value);
|
||||||
|
stack.getChildren().addAll(circle, text);
|
||||||
|
return circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initPhysics() {
|
||||||
|
getPhysicsWorld().addCollisionHandler(new CollisionHandler(EntityType.PLAYER, EntityType.COIN) {
|
||||||
|
|
||||||
|
// order of types is the same as passed into the constructor
|
||||||
|
@Override
|
||||||
|
protected void onCollisionBegin(Entity player, Entity coin) {
|
||||||
|
coin.removeFromWorld();
|
||||||
|
inc("coins", +coin.getProperties().getInt("coinValue"));
|
||||||
|
move = 5;
|
||||||
|
spawnNewCoin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initUI() {
|
||||||
|
Text textPixels = new Text();
|
||||||
|
textPixels.setTranslateX(50);
|
||||||
|
textPixels.setTranslateY(100);
|
||||||
|
textPixels.textProperty().bind(getWorldProperties().intProperty("pixelsMoved").asString());
|
||||||
|
|
||||||
|
Text x = new Text();
|
||||||
|
x.setTranslateX(150);
|
||||||
|
x.setTranslateY(100);
|
||||||
|
x.textProperty().bind(getWorldProperties().intProperty("x").asString());
|
||||||
|
|
||||||
|
Text y = new Text();
|
||||||
|
y.setTranslateX(250);
|
||||||
|
y.setTranslateY(100);
|
||||||
|
y.textProperty().bind(getWorldProperties().intProperty("y").asString());
|
||||||
|
|
||||||
|
Text coins = new Text();
|
||||||
|
coins.setTranslateX(350);
|
||||||
|
coins.setTranslateY(100);
|
||||||
|
coins.textProperty().bind(getWorldProperties().intProperty("coins").asString());
|
||||||
|
|
||||||
|
Text seconds = new Text();
|
||||||
|
seconds.setTranslateX(450);
|
||||||
|
seconds.setTranslateY(100);
|
||||||
|
seconds.textProperty().bind(getWorldProperties().intProperty("seconds").asString());
|
||||||
|
|
||||||
|
getGameScene().addUINode(textPixels);
|
||||||
|
getGameScene().addUINode(x);
|
||||||
|
getGameScene().addUINode(y);
|
||||||
|
getGameScene().addUINode(coins);
|
||||||
|
getGameScene().addUINode(seconds);
|
||||||
|
|
||||||
|
var brickTexture = getAssetLoader().loadTexture("brick.png");
|
||||||
|
brickTexture.setTranslateX(50);
|
||||||
|
brickTexture.setTranslateY(450);
|
||||||
|
|
||||||
|
getGameScene().addUINode(brickTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
launch(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnNewCoin() {
|
||||||
|
final Circle coinCircle = createCoin();
|
||||||
|
int coinValue = (int) coinCircle.getProperties().get("coinValue");
|
||||||
|
final Integer x = randomNumberSource.apply(40, 600);
|
||||||
|
final Integer y = randomNumberSource.apply(40, 400);
|
||||||
|
coinX = x;
|
||||||
|
coinY = y;
|
||||||
|
Entity newCoin = entityBuilder()
|
||||||
|
.type(EntityType.COIN)
|
||||||
|
.at(x, y)
|
||||||
|
.viewWithBBox(coinCircle)
|
||||||
|
// .viewWithBBox(createBlupiView())
|
||||||
|
.with("coinValue", coinValue)
|
||||||
|
.with(new CollidableComponent(true))
|
||||||
|
.buildAndAttach();
|
||||||
|
coin = newCoin;
|
||||||
|
PropertyMap state = FXGL.getWorldProperties();
|
||||||
|
|
||||||
|
getGameTimer().runOnceAfter(() -> {
|
||||||
|
if (newCoin.isActive()) {
|
||||||
|
newCoin.removeFromWorld();
|
||||||
|
spawnNewCoin();
|
||||||
|
inc("coins", -coinValue);
|
||||||
|
}
|
||||||
|
}, Duration.seconds(randomNumberSource.apply(5, 15)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageView createBlupiView() {
|
||||||
|
final String im = new File("/home/robertvokac/Desktop/speedy_eggbert/speedy_eggbert_I/IMAGE08/blupi000.blp").toURI().toString();
|
||||||
|
Image image = new Image(im, false);
|
||||||
|
ImageView result = new ImageView(image);
|
||||||
|
result.setViewport(new Rectangle2D(165, 118, 30, 47));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user