Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve scene ratio #634

Closed
iAmGio opened this issue Jun 9, 2019 · 26 comments

Comments

Projects
None yet
2 participants
@iAmGio
Copy link

commented Jun 9, 2019

Hi Almas,
basically, I want to make my game resizable, so I set manualResizeEnabled to true. The built-in scale mechanism works well, except for the fact that I want to preserve the original ratio. I opted to create rectangles on both left and right of the scene so that the window could be resized as much as wanted, so that the actual game resolution would be the same. Honestly, I don't know how to do this in FXGL since width/scale properties aren't modified in contentRoot and I don't know where to set listeners.

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

Hi, could this be related to #624 ? Could you clarify what properties you need access to?

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

I've just re-read this and I think I got the idea. During resize if the ratio is different, append black bars (similar to video playing software) either top/bot or left/right, so that the ratio remains the same. Is that right?

If so, this should probably be implemented as a setting: settings.setPreserveResizeRatio(true) or smth along these lines

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 9, 2019

Yes, that's exactly what I meant (I'm not native English, sorry). That implementation would be great.

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

I am unsure about black bars. The original background color is transparent, so I think it would be sensible to leave the bars as transparent (effectively white). Would that work for you?

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 9, 2019

Would that work for you?

That's not a problem. However, couldn't the color be set by changing -fx-background-color of the content root?

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

I think so, which means even if I don't set the color, you will be able to update it as necessary.

AlmasB added a commit that referenced this issue Jun 9, 2019

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

To get the latest build (once it completes), you can use this:

<dependencies>
    <dependency>
        <groupId>com.github.almasb</groupId>
        <artifactId>fxgl</artifactId>
        <version>dev-SNAPSHOT</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>oss.sonatype.org-snapshot</id>
        <url>http://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
</repositories>
@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

Need to enable both

settings.setManualResizeEnabled(true);
settings.setPreserveResizeRatio(true);
@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 9, 2019

Is this build compatible with Java < 11?

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 9, 2019

No, I'm afraid. Only 11+ is being developed. As FXGL 11 has a completely new architecture, it is not sensible to develop both, especially considering it is superior to FXGL 8 arch. Eventually, there might be a backport of the 11 codebase to 8 but no plans at the moment.

@iAmGio iAmGio closed this Jun 9, 2019

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 10, 2019

Is it possible to align the game scene to center?

Image

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 10, 2019

You can play around with root or contentRoot of the game scene. Maybe layoutX/Y or translateX/Y can offset the scene as required.

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 10, 2019

I think it's not working as expected.
Set initial size to 1280x720, I manually resized the window to a similar size but quite smaller than the original one.
gameScene.root (orange) should cover the whole window because w1/h1 == w2/h2. Also, gameScene.contentRoot (gray) is able to go out of the root.

Image

I've made this image that shows how the scene (initial size 1280x720, w/h = 1.77) could be resized every time the window size is modified:

Image2

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 11, 2019

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 11, 2019

The formula would be:
scene = window * w2/h2 / w1/h1
where:
scene = width (if w1/h1 < w2/h2) or height of the game scene.
window = width or height (as above) of the window
w1/h1 = ratio of width to height of the original window
w2/h2 = ratio of width to height of the resized window

@AlmasB AlmasB reopened this Jun 12, 2019

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 16, 2019

So effectively, 2 fixes are required for this:

  • Center game scene?
  • Resize root to match content root?
@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 16, 2019

Yes.

AlmasB added a commit that referenced this issue Jun 16, 2019

apply scale transform on content root, not root, center content root.…
… Centering root has no effect if scale ratio is not preserved as translate values remain 0, closes #634
@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 16, 2019

Done. Give CI a few minutes to build and upload, then just refresh your dev-SNAPSHOT dependency.

You can set color to background either way:

getGameScene().getRoot().setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
getGameScene().getRoot().setStyle("-fx-background-color: black");
@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 17, 2019

The fixes look great. However, the content root can still expand out of the game scene:
Image

Orange = gameScene.root;
Blue = UI node that should match the correct content root size;
How you can see, my character is able to go out of it.

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 17, 2019

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

Player component: https://hastebin.com/itudoxadod.m
For visibility (in initGame()):

getGameScene().root.style = "-fx-background-color: orange"
getGameScene().addUINode(Rectangle(getAppWidth().toDouble(), getAppHeight().toDouble(), Color(.0, .0, 1.0, .5)))
@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 18, 2019

Sorry, I meant a minimal example that I can run, so App : GameApplication(), etc. that demonstrates the issue

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameScene;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.*;
import com.almasb.fxgl.input.Input;
import com.almasb.fxgl.input.UserAction;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;

public class Demo extends GameApplication {

    private Entity player;

    @Override
    protected void initSettings(GameSettings settings) {
        settings.setManualResizeEnabled(true);
        settings.setPreserveResizeRatio(true);
        settings.setWidth(1280);
        settings.setHeight(720);
        settings.setTitle("Demo");
    }

    @Override
    protected void initInput() {
        Input input = FXGL.getInput();
        input.addAction(new UserAction("Up") {
            @Override
            protected void onAction() {
                player.translateY(-5.0);
            }
        }, KeyCode.W);
        input.addAction(new UserAction("Right") {
            @Override
            protected void onAction() {
                player.translateX(5.0);
            }
        }, KeyCode.D);
        input.addAction(new UserAction("Down") {
            @Override
            protected void onAction() {
                player.translateY(5.0);
            }
        }, KeyCode.S);
        input.addAction(new UserAction("Left") {
            @Override
            protected void onAction() {
                player.translateX(-5.0);
            }
        }, KeyCode.A);
    }

    @Override
    protected void initGame() {
        GameWorld gameWorld = FXGL.getGameWorld();
        gameWorld.addEntityFactory(new DemoEntityFactory());
        player = gameWorld.spawn("player", new SpawnData(200, 200));
    }

    @Override
    protected void initUI() {
        GameScene gameScene = FXGL.getGameScene();
        gameScene.addUINode(new Rectangle(FXGL.getAppWidth(), FXGL.getAppHeight(), new Color(.0, .0, 1.0, .5)));
    }

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

    public class DemoEntityFactory implements EntityFactory {

        @Spawns("player")
        public Entity newPlayer(SpawnData data) {
            return FXGL.entityBuilder()
                    .at(data.getX(), data.getY())
                    .view(new Rectangle(100.0, 100.0, Color.BLACK))
                    .build();
        }
    }
}
@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 18, 2019

I think I've finally understood the issue :) I adapted your initial approach with Rectangles.

You should be able to do this:

getGameScene().getPaddingTop().setFill(Color.YELLOW);
getGameScene().getPaddingBot().setFill(Color.RED);
getGameScene().getPaddingRight().setFill(Color.GREEN);
getGameScene().getPaddingLeft().setFill(Color.BLUE);

which actually gives you more control over each padding

@AlmasB

This comment has been minimized.

Copy link
Owner

commented Jun 18, 2019

build on its way

@iAmGio

This comment has been minimized.

Copy link
Author

commented Jun 21, 2019

It seems to work well, thank you!

@iAmGio iAmGio closed this Jun 21, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.