Closed armin-reichert closed 7 months ago
Sorry to bother you again. Things don't work as expected :-(
I have all webfx tools available on my machine. Creating a "hello world" sample, building/runnning it with webfx build -fr
, webfx build -gr
and webfx build -dr
all work as expected and the hello world app opens, either in a window or in the browser.
But for the webfx-demos/webfx-demo-pacman
, the app only opens in the browser! For the other variants, no window opens.
Could you please verify that this is the same in your local version? It cannot be caused by my 3 changes so far because I only changed the window background to black, added gitignore files and removed the 3D subproject.
Here are the results on my iMac:
webfx build -gr
π webfx build -fr
π webfx build -dr
π (compiles but crashes - it's actually normal because Gluon doesn't support JavaFX media yet on Windows and MacOS as stated in their doc)BTW if you want a mobile version of your game, it's possible but I will need to modify the code a little bit so playing sound can be processed by Gluon Attach on Android & iOS (the desktop & web version will still work after that modification). Let me know if you're interested.
I'm surprised that webfx build -fr
doesn't work for you. Do you have any error message in the console?
Have you tried to run the Windows fat jar and installer exe generated by the GitHub workflow (available here)?
hi Armin,
How is it going?
I just noticed that the latest online version is not working, but this is probably due to the following WebFX bug that I would like to make you aware of: when changing a node using parent.getChildren().set(x, newNode), the WebFX mapper may get it wrong and put the node at the end instead of position x.
I will try to fix that bug later, but for the time being, is it possible for you to reset the whole list instead? Ex: parent.getChildren().setAll(node1 ,node2, etc...)?
Hello Bruno,
thanks for the hint. I am aware that there is something fishy in this area. My latest commit should clarify the main scene layering a little bit.
Looks better now. Flash messages are working, the context-sensitive help is toggled by pressing 'H', the cheats like "Immunity" (Alt+Shift I) or the autopilot mode (Alt+Shift A) are displayed correctly in the context help.
Glad that it's working again, you found the workaround!
Don't hesitate to tell me when you are facing a WebFX bug, I will try to fix it, and this helps to make WebFX better π
Of course I will tell you about any strange effects I find.
Example: I have the impression that mouse clicks on a Text widget do not work properly. I had a Text instance only for the greeting message ("Click to start") but that did not work in the browser, so I had to put the text inside a panel.
I lost some time because I had to install IntelliJ to work with the webfx branch (I had absolutely no idea how to realize the "application configuration" involving ApplicationBooter inside Eclipse). But working with IntelliJ is really fun, Git integration is top.
Yes, IntelliJ is amazing, I π it too
The text only (without pane) should work... I just pull the latest source, and noticed a call to greetingText.setMouseTransparent(true);
which prevents any interaction with the user. Maybe that's the problem?
I'm glad that you have the OpenJFX configuration running in IntelliJ, so you can now see if your issues come from WebFX or the application code. For example, if the text issue is because of setMouseTransparent(), you should see that the issue is also happening with OpenJFX, and therefore it's not a WebFX bug. This OpenJFX configuration should really accelerate your development cycle! π
Well, I added the setMouseTransparent(true)
call after putting the text inside a StackPane. First I had the text only, but the mouse click on the text was only handled in the desktop version, but not in the browser version. Then I added the surrounding StackPane and wanted the mouse click over the text also being handled on the stack pane.
I tried this locally, and it works in the browser:
private Node createGreetingPane() {
DropShadow ds = new DropShadow();
ds.setOffsetY(3.0f);
ds.setColor(Color.color(0.2f, 0.2f, 0.2f));
var greetingText = new Text(">Click to start<");
//greetingText.setMouseTransparent(true);
greetingText.setEffect(ds);
greetingText.setCache(true);
greetingText.setFill(Color.YELLOW);
greetingText.setFont(AppRes.Fonts.font(AppRes.Fonts.arcade, 24));
//var pane = new StackPane(greetingText);
greetingText.setOnMouseClicked(e -> {
layers.remove(LAYER_GREETING);
rebuildMainSceneLayers();
simulation.start();
Actions.playHelpVoiceMessageAfterSeconds(4);
});
//return pane;
return greetingText;
}
Definitely didn't work here (Windows10, Google Chrome). I could try it again with the exact code above.
Maybe it's a Windows thing (as I don't test on Windows...) If you can test for me, that would be helpful.
PS: Good idea the initial click, as it makes a user interaction, and then the sound works in the browser π
π‘ Tips: if you don't want that greeting text to show in the other platforms (because they can play sound straightaway), you can use the condition dev.webfx.platform.useragent.UserAgent.isBrowser()
(just run webfx update
after inserting this in your code and the WebFX CLI should automatically insert the required WebFX module - and after that IntelliJ should propose you to replace the fully qualified name with a simple UserAgent.isBrowser()
+ import dev.webfx.platform.useragent.UserAgent;
).
Yes, that "no sound without initial gesture" feature was the reason I added this "Click Me" thing. Thanks for the tip, but the webfx branch should just be used inside the browser. You mentioned that webfx can also be used to build executables for different platforms. That's exactly what I am looking for. But will this also only be possible after downporting to Java 11 and all these changes you had made?
BTW: no single error occurs anymore in the Chrome developer console.
WebFX can compile apps to many platforms (not only the web) all from a single source code (your code in the webfx branch). The current GitHub workflow already generates different installers of your game as you can see in the generated assets here (just expand the Assets).
If you have an Android device, you can try to download and install the .apk file, but it's probably crashing because of JavaFX media not supported by Gluon. However, I can easily solve this problem using the WebFX API (let me know if you're interested).
Once everything works with WebFX, we can try to back port that into your original game.
Issue: TextFlow does not work inside browser. I used a TextFlow node to put two Text nodes with different fonts together (see GameScene2D.addSignature()
). In a window this looks find but in the browser, the text is not rendered correctly (stacked vertically).
Right, WebFX has a very limited support of TextFlow
, because it's a complex component, and the main reason for the existence of the TextFlow API in JavaFX is to provide a (poor) equivalent of HTML - but even that is already complex, and it doesn't really make sense to implement that complexity back for the browser while you can do HTML natively straightaway.
For this reason, WebFX provides alternative classes HtmlText
, HtmlTextEditor
and SvgText
in the package dev.webfx.extras.webtext
. HtmlText
for example will accept any html content that will be rendered as is in the browser, and will try to render that html content using TextFlow in the OpenJFX version (limited but should works for basic html).
Are you happy to try HtmlText
instead of TextFlow
?
Or if you prefer, I can have a look at it later today after work.
Hi Bruno,
that was not a call for action, I just collect what I find on my way and let you know.
Another question: Would it be possible to change the GitHub workflow to only build the GWT version and deploy it to the website as long as I am still adding features in the webfx branch? 10 minutes for a build is a little long.
Text positioning is different in browser than in desktop window! In the browser the signature appears lower than in the desktop version. Why?
Why are you not testing the web version on your local machine before pushing? This should be must faster.
I will have a look at the text positioning this evening.
Sorry I got a little bit confused (happens at age 56). When I installed IntelliJ some days ago I quickly clicked through the installation and overlooked that IntelliJ uses its own local Git root. My console window still referred to the Git root I use with Eclipse so the webfx build -gr
obvioulsy had no effect ony the changes I made with IntelliJ. Stupid me.
But now, when I refer to the IntelliJ Git root and call webfx build -gr
and the browser opens (via a file: URL) I observe that some things like tihe boot "animation" do not work properly. Maybe I must let the page being served by a local webserver or use the one inside IntelliJ as you proposed.
webfx build -gr
doesn't use git
, just mvn
. The important thing is to run the command under your project folder (so webfx-demo-pacman
here).
I just pulled your changes and the boot animation works fine on my local machine either with webfx build -gr
or IntelliJ webserver.
π‘ Tips: if you right-click on webfx-demo-pacman
in IntelliJ project window and select "Open in" > "Terminal", it will open a terminal tab (inside IntelliJ) already set under that folder (and it will remember that tab on next launches). This is usuallly where I type my webfx commands.
I know that the build uses Maven and not git. The problem was that IntelliJ uses a different local folder for the git repository than Eclipse and when I switched to IntelliJ I didn't change the folder in my terminal window.
When I run with webfx -gr
the boot screen shows the random hex symbols but not the random spritesheet tiles.
I hadn't spotted the spritesheet issue, I see now what you mean, but it happens only when opening from file://
, so not an issue for the final web version. Have you found how to open the html file with the IntelliJ built-in webserver?
Another π‘: You can bookmark the generated index.html in IntelliJ so you can access it quicker next times.
In the IntelliJ internal web browser, it looks ok. Of course, the text positioning issue is also there. Thanks for all the tips! I am using IntelliJ only 3 days, but Eclipse 20 years :-)
Ok, the positioning issue is with the JavaFX textOrigin
property. For now WebFX supports VPos.TOP, VPos.CENTER and VPos.BOTTOM, but not VPos.BASELINE, which is unfortunately the default value. I will investigate again if there is a way to support VPos.BASELINE in HTML, but in the meantime, you can just set a different value to textOrigin and adjust your y value accordingly. Let me know if that solves the issue.
Actually I think I found a solution and fixed the VPos.BASELINE html mapping in WebFX!
So no need to change your code finally, just get the latest webfx version (your Maven will automatically load it tomorrow, but if you don't want to wait, just clean this folder in your Maven local repository (located here from your user home: .m2/repository/dev/webfx/webfx-kit-javafxgraphics-peers-gwt
)
Works!
Great, and I triggered the GitHub workflow manually again (as no change is needed in your source code), so now the online version works as well
Hi Bruno,
I have an issue with a GridPane. For the context-sensitive help/menus (press 'H' to open/close) I use a GridPane together with a surrounding HBox to give a transparent background and some padding. In the desktop version that looks perfect, but in the browser, the vertical aligment is broken. Any idea?
Looks like a similar issue as yesterday, probably my fix for VPos.BASELINE doesn't work in all scenarios... I will have a look this evening, but for the time being, just try another value for the textOrigin. For example try text.setTextOrigin(VPos.TOP);
and you should have a better result.
hi Armin, how is it going?
FYI I just pushed some fixes in WebFX, this includes the text positioning (so you might need to remove the translation correction now).
Also as you probably noticed, I fixed the background positioning issue. But on my big 27" screen, the picture is so stretched in width that I see only the top of the image (and the yellow "Click to start !" is on top of the yellow image). I think it would be better to put that image in 'contain' mode (instead of 'cover'), and put the wallpaper behind, so something like:
var bgImage = new BackgroundImage(
AppRes.Graphics.msPacManCabinet,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,
new BackgroundSize(AUTO, AUTO, false, false, true, false));
root.setBackground(new Background(
new BackgroundImage(AppRes.Graphics.wallpaper, null, null, null, null),
bgImage));
What do you think?
Hi Bruno,
I am making progress. Working mode with IntelliJ and βwebfx cliβ is fluent, building the GWT version locally takes around 20 seconds, thatβs ok for me.
The greeting page is still provisionary, I probably will select another wallpaper, something like https://wallpapercave.com/w/wp4163225
But I am not sure about copyright etc. The assets in my games are also βstolenβ from other projects. But how should one clone a classic Arcade game without using the original assets?
Yes, I noticed that you already fixed some of the alignment issues. Thatβs great!
What I want to add in any case is some black area around the game scene, something like here: https://www.pacman1.net/
But I am open to your ideas of course too. There is not much missing until we can publish it.
Best regards Armin
For your black area, you can embed the canvas in a black StackPane container and give it a size slightly superior (ex: +10%), so something like this:
protected GameScene2D(GameController gameController) {
checkNotNull(gameController);
context = new GameSceneContext(gameController);
StackPane canvasPane = new StackPane(canvas);
canvasPane.setBackground(new Background(new BackgroundFill(Color.BLACK, new CornerRadii(10), null)));
double marginFactor = 1.1;
canvasPane.setMaxWidth(WIDTH * marginFactor);
canvasPane.setMaxHeight(HEIGHT * marginFactor);
root = new BorderPane();
root.heightProperty().addListener((py, ov, nv) -> {
double scaling = nv.doubleValue() / (HEIGHT * marginFactor);
canvasPane.setScaleX(scaling);
canvasPane.setScaleY(scaling);
// don't ask me why this works but setScaleX/Y doesn't
overlay.getTransforms().setAll(new Scale(scaling,scaling));
});
canvas.setWidth(WIDTH);
canvas.setHeight(HEIGHT);
// help appears in overlay layer at left scene border, 10% from top
helpRoot.setTranslateX(8);
helpRoot.setTranslateY(HEIGHT * 0.1);
friendlyGhostImage = new ImageView(AppRes.Graphics.friendlyGhostIcon);
friendlyGhostImage.setPreserveRatio(true);
friendlyGhostImage.setFitHeight(20);
friendlyGhostImage.setTranslateX(-20);
friendlyGhostImage.setTranslateY(helpRoot.getTranslateY());
friendlyGhostImage.setOnMousePressed (e -> Actions.showHelp());
overlay.getChildren().addAll(helpRoot, friendlyGhostImage);
layers.getChildren().addAll(canvasPane, overlay);
root.setCenter(layers);
infoVisiblePy.bind(Env.showDebugInfoPy);
}
You will need to remove the round corners from the canvas as they will be now in that container.
hi Armin, just to let you know, I created a new webfx-bundle
branch that you can merge into the webfx branch if you want (and delete webfx-bundle
once done). It does load the bundles from messages.properties
(sorry for the dirty hardcoding in the initial version). FYI it's necessary to list messages.properties as an embed resource in webfx.xml to make this work (otherwise loading the resource would be asynchronous) and run webfx update
(already done in webfx-bundle
).
Just a suggestion for the font used in the help: wouldn't it be better to use a monospace font (ex: Courier) to get the shortcuts aligned in the right part?
Hi Bruno,
thanks for the effort. Message bundles are not so important for this demo but I will do what you suggested.
What about the persistent high scores? Would it be much work to make these work too?
I changed the font in the help menus. When changing the font size I observed that in GWT, GridPane.setHgap()
and GridPane.setVgap()
seem to have no effect. Is this a known issue?
GridPane.setHgap()
and GridPane.setVgap()
do have effect (try with a big value like 100 and you will see). Maybe it's more a difference between the font metrics between JavaFX & HTML? I will have a deeper look later...
For the high scores persistence, yes it's possible. I will create a new branch for this that you will merge to webfx. Will let you know once done.
I just pushed some changes (monospace font, workaround for grid gap issue).
BTW: Yesterday, I observed differences between my local GWT version and the version created by the build on the website. Do I have to update something locally to get them in sync again?
That's probably because I pushed my fixes on WebFX yesterday (that's why I sent you a message). This is immediately considered on the GitHub workflow because the workflow rebuilds a new VM from scratch and therefore always download the latest Maven snapshots. But on your local machine, Maven does a snapshot refresh only once a day (on first invocation). So your local WebFX snapshots were not the same in the meantime.
π‘ Tip: you can use webfx update -c
to force the snapshot cleaning (as mentioned in webfx update -H
)
I just merged webfx-bundle into my local webfx branch. Now I get errors:
Package 'dev.webfx.platform.useragent' is declared in module 'webfx.platform.useragent', but module 'pacman.ui.fx' does not read it
What to do?
webfx update
is always a good try
At least it transforms compile errors into runtime errors :-)
Exception in thread "Thread-1" java.lang.RuntimeException: Exception in Application init method at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:896) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.nio.file.InvalidPathException: Illegal char <:> at index 4: file:\C:\Users\Armin\IdeaProjects\webfx-demo-pacman\pacman-ui-fx\target\classes\de\amr\games\pacman\ui\fx\assets\texts\messages.properties at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153) at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77) at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92) at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232) at java.base/jdk.internal.module.Resources.toSafeFilePath(Resources.java:143) at java.base/jdk.internal.module.Resources.toFilePath(Resources.java:97) at java.base/jdk.internal.module.ModuleReferences$ExplodedModuleReader.find(ModuleReferences.java:382) at java.base/jdk.internal.loader.BuiltinClassLoader$2.run(BuiltinClassLoader.java:464) at java.base/jdk.internal.loader.BuiltinClassLoader$2.run(BuiltinClassLoader.java:459) at java.base/java.security.AccessController.doPrivileged(AccessController.java:569) at java.base/jdk.internal.loader.BuiltinClassLoader.findMiscResource(BuiltinClassLoader.java:458) at java.base/jdk.internal.loader.BuiltinClassLoader.findResource(BuiltinClassLoader.java:341) at java.base/java.lang.ClassLoader.getResource(ClassLoader.java:1404) at java.base/java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1738) at webfx.platform.resource.java@0.1.0-SNAPSHOT/dev.webfx.platform.resource.spi.impl.java.JavaResourceProvider.getResourceInputStream(JavaResourceProvider.java:44) at webfx.platform.resource.java@0.1.0-SNAPSHOT/dev.webfx.platform.resource.spi.impl.java.JavaResourceProvider.getText(JavaResourceProvider.java:38) at webfx.platform.resource@0.1.0-SNAPSHOT/dev.webfx.platform.resource.Resource.getText(Resource.java:31) at pacman.ui.fx/de.amr.games.pacman.ui.fx.util.ResourceManager.loadBundle(ResourceManager.java:135) at pacman.ui.fx/de.amr.games.pacman.ui.fx.app.AppRes$Texts.load(AppRes.java:91) at pacman.ui.fx/de.amr.games.pacman.ui.fx.app.AppRes.lambda$load$3(AppRes.java:56) at pacman.ui.fx/de.amr.games.pacman.ui.fx.app.AppRes.load(AppRes.java:62) at pacman.ui.fx/de.amr.games.pacman.ui.fx.app.AppRes.load(AppRes.java:56) at pacman.ui.fx/de.amr.games.pacman.ui.fx.app.PacManGameAppFX.init(PacManGameAppFX.java:73) at webfx.kit.openjfx@0.1.0-SNAPSHOT/dev.webfx.kit.launcher.spi.impl.openjfx.JavaFxWebFxKitLauncherProvider$FxKitWrapperApplication.init(JavaFxWebFxKitLauncherProvider.java:102) at javafx.graphics@19/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:825) ... 2 more
webfx update
fixed the previous issue. What's happening now is a Windows error when trying to read the file (but your GWT should work). It looks like Windows doesn't like the 'file:' prefix in the path. I will see what I can do...
As mentioned, this has no priority at all. Maybe we should just create a list of all the issues found and give them priorities. I really do not want to steal your time with such things.
It's actually good that you report these problems, as I don't have a Windows computer (I have an iMac & a Linux laptop).
I think I fixed the problem (it was in the WebFX Platform layer). Now pushed. Can you run webfx update -c
and let me know if this solves the issue?
You are my Windows tester π
Strange. After webfx update -c
I cannot use the run configuration in IntelliJ anymore. I get java.lang.ClassNotFoundException: dev.webfx.platform.boot.ApplicationBooter
.
Sometimes IntelliJ gets confused with all these modules. Try "Reload all Maven projects" (the recycling icon in the Maven tool windows on the right). Let me know if it helps.
Yes, that helped! Now I can run the (merged) webfx-bundle branch locally without errors, in the VM and in the GWT version. Changes in the messages.properties
file also appear in the help menu.
However, what do I have to do to get the German bundle messages_de.properties
at runtime? In Eclipse, I add the VM parameters -Duser.language -Duser.country=de
to get that but I didn't success to do that with the WebFX PacMan run configuration in IntelliJ. Or is the locale-dependent loading not yet implemented?
Great, this means that the Windows bug is fixed! Thank you! π
You can't pass VM parameters to the browser, but maybe you can use dev.webfx.platform.windowlocation.WindowLocation.getQueryString()
. Then if you add ?lang=de
to the browser url, that method will return lang=de
and then you can read messages_de.properties
instead in ResourceManager.loadBundle()
. To make this work, you will need to list messages_de.properties
in the embed resources in webfx.xml
. Let me know if you need more help with this.
I wanted to add the VM parameters to the IntelliJ run config to test it with the VM. How can I do that? The browser is another question. But as I said the resource bundle support has prio lower than low.
Right now the WindowLocation
methods (such as getQueryString()
) returns null in the JVM, but maybe I could add a possibility to initialise the window location from VM parameters, and then you could pass ?lang=de
when running in the JVM? In this way the same java code would work for both the browser and the JVM (which is the goal of WebFX). What do you think?
Alternatively, you can add a language menu (EN & DE) in your game, and we persist that setting. But it's more work for you...
Regarding the score persistence, I think I have something ready. Are you ok if I push that in the webfx branch of webfx-demo-pacman-core
?
Hi Bruno,
feel free to make any changes without asking me.
I will continue tomorrow, old men must rest and also have a wine cellar to work on. Malescasse 2009 or Capbern-Gasqueton 2012, that's the question for today :-)
What do you mean old? You said you were 56! I'm not far behind... π€£
Ok I pushed the changes, which updated the webfx-demo-pacman-core
snapshots. You can get them with webfx update -c
in webfx-demo-pacman
(this will also update your build chain with a new WebFX module added for the persistence -> you will need to include these changes in your next commit & push to GitHub).
A difficult question for the day! But whatever your choice, enjoy! π· And then rest! π π
Say I want to use webfx to build a GWT executable (and maybe others too) for an existing JavaFX application (in my case: https://github.com/armin-reichert/pacman-javafx)
Do I have to bring my Maven artifacts to some central Maven repository first to get this working, or can webfx also resolve dependencies against my local Maven repository?