Being new to Javafx and java, I'm having trouble picturing the design for a chess game.
So I have the start method like following in my JavaFX Application-extended class:
public void start(Stage primaryStage) throws Exception{
Scene scene = new Scene(createContent());
primaryStage.setTitle("ChessGame");
primaryStage.getIcons().add(new Image("file:images/icon.png"));
primaryStage.setScene(scene);
primaryStage.show();
}
protected Parent createContent(){
Pane root = new Pane();
root.setPrefSize(WIDTH*TILE_SIZE, HEIGHT*TILE_SIZE);
boardInitialize("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -");
root.getChildren().add(tileGroup);
root.getChildren().add(pieceGroup);
return root;
}
The problem is, I don't know where to put the game's logic inside my application. The game logic will handle player's turn, check for checks and checkmates, generate possible moves, etc (and later a very crude AI if possible). I have tried to jam it into the start method, but it doesn't work because the start method only runs once. Pygame with their gameloop makes much more sense than this and I can see how I would go with it. So my question is: where do I put the game logic in my application?
You may use the Model-View-Controller (+ Network if needed) architecture to design your system. JavaFX is really useful when working with the MVC.
Rules of Thumb:
1- Do not put your game logic inside the Model, Network and View(FXML) classes.
2- Use FXML as part of the design (it will bootstrap your work).
3- Try to achieve " Low coupling & High Coherence "
4- Some example from a fully-working MVC JavaFX project.
> /* WelcomeScreenController class (interacts with the FXML file)*/
> #FXML
> void doSignup(ActionEvent event) {
>
> user = username.getText();
> pass = password.getText();
>
> if(user != null && !user.isEmpty() && pass != null && !pass.isEmpty())
> if (checkBox.isSelected())
> GameEngine.game().getAccessManager().callSignupService(user,pass);
> else
> showNotification("You need to accept terms.");
> }
5- Try to handle button logic from the Controller class of the particular FXML file. http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm
6- Create a controller class named "GameEngine" to do all your computations about the game logic. Call GameEngine's methods from the button's handle action event method.
7- Try to use Object-Oriented Programming methodologies. (Polymorphism, Inheritance, Design Patterns, etc.)
I would stand upon the shoulders of others and use a library that already has some structure in it.
With that you can follow the model that build upon the experience of others and use their best practices and avoid the pitfalls they have experienced.
For JavaFX I am aware of the FXGL library, which comes with a nice list of examples of how to build a game in JavaFX.
On YouTube you can find several examples and tutorials for this library.
First of all, I would like to let you know that I have never written a Javafx application and I could be wrong.
The start method, as you correctly pointed out is the main entry point of a Javafx application, as you can see from the anatomy of a Javafx application described here. You can initialize your game there, but naturally, the moves will occur later than running the start. You will need to use event handling to handle the case when a move is being attempted by a player.
Once you are able to handle the move events, you will also be able to check whether a move is correct or not, or, to check the possible valid move options of a given player. I would like to suggest that you should have your own classes for the business logic and to avoid mixing business logic with event handling, even though the event handler will invoke business logic methods.
Related
I'm trying to make an augmented reality application with vuforia and unity.
whenever it recognize the image target, it must tell a story by showing text , and it should enable the user to press next and back to go on reading the different parts of this story, I'm totally new to unity and don't know how to handle with UI throughout scripting, I need some help on how to accomplish the part of "going forward and backward on showing the story by hitting Next and Back buttons", and all these parts of story should be related to the same image target in the same scene.
I appreciate it if you help me with an example code.
You should create some script that attach on trackable object, maybe something like this.
public class DataBook {
string[] dataBook;
string idText;
bool isActive;
}
Then you must create another script to set that trackable object is active or not, this link can help you to get that.
https://developer.vuforia.com/forum/faq/unity-how-do-i-get-list-active-trackables
Then after you get the active trackable object, you can set the dialog from the book by create another controller script for button, example
public void Next() {
DataBook[] books = FindObjectsOfType<DataBook>(); // if the object more than one, it will be more easy if it only the one
foreach (var book in books)
{
if (book.isActive) {
book.idText += 1;
textUI.text = book.dataBook[idText]; //textUI assign to object text on canvas
}
}
}
you can learn about unity UI Button on this :
https://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button
Good luck
Basically, what I want to do is have two objects (fpscontroller and a wall) that collide like normal. But, once a script runs, they won't collide anymore.
So, how do I make that script that makes the two objects ignore collision with each other? I've tried looking this up, and what I got was Physics.IgnoreCollision, but the documentation on that confused me. And when I tried putting it in and replacing their variables with my variables, I got a bunch of errors.
So, please help.
The way i would go about doing this is through layers.
In unity, a convenient way to ignore physics collision between objects is through setting the object to be ignored to a layer which your player object will always ignore.
So, to go about setting this up imagine the following:
fpscontroller's layer is set to "player" (a layer i have created and named such).
wall's layer is initially always set to "wall" (once again a layer i have created)
Additionally, I create a layer that i call "IgnorePlayerCollisions"
Now i go to: Edit > Project Settings > Physics
Here i can check the box which will turn off collisions between my player and IgnorePlayerCollisions layers.
Now, at runtime i run my script which says:
Change Wall Layer to "IgnorePlayerCollisions". Voila, my player now ignores all collisions with this layer.
Code Examples: (You don't need these all):
// Function to Change a GameObject Layer to the Ignore Layer
public void ChangeGameObjectLayerToIgnore(GameObject go) {
go.layer = [Index of Ignore Layer];
}
// Function to Change "This" GameObjects layer to any other layer
public void ChangeThisGameObjectLayer(int layerIndex) {
this.gameObject.layer = layerIndex;
}
// Change a GameObject layer to another layer
public void ChangeGameObjectLayer(GameObject go, int layerIndex) {
go.layer = layerIndex;
}
How?
Place a C# function into a script and attach it to either your desired gameobject. In your case, i may attach it my Player GameObject since it seems like you may want to disable object throughout the game based on specific trigger or something. It really depends on how you plan to trigger the function.
Let me know if this makes sense or not. If not, i can attempt to make it more legible.
Good luck and have fun!
Most Unity tutorials suggest using Mouse events within the Update function, like this:
function Update () {
if (UnityEngine.Input.GetMouseButton(1)) {
}
}
This strikes me as really inefficient though, similar to using onEnterFrame in AS or setInterval in JS to power the whole application - I'd really prefer to use an events based system.
the OnMouseDown() method is useful, but is only fired when the MouseDown is on the object, not anywhere in the scene.
So here's the question: Is there a MouseEvent in Unity for detecting if the mouse button is down globally, or is the Update solution the recommended option?
This strikes me as really inefficient though, similar to using
onEnterFrame in AS or setInterval in JS to power the whole application
- I'd really prefer to use an events based system.
As already pointed out in comments, this isn't necessary less efficient. Every event based system is probably using a polling routine like that behind the scenes, updated at a given frequency.
In many game engines/frameworks you are going to find a polling based approach for input handling. I think this is related to the fact that input update frequency is directly correlated to the frame rate/update loop frequency. In fact it doesn't make much sense to listen for input at higher or lower frequency than your game loop.
So here's the question: Is there a MouseEvent in Unity for detecting
if the mouse button is down globally, or is the Update solution the
recommended option?
No there isn't. Btw if you want you can wrap mouse input detection inside a single class, and expose events from there where other classes can register to.
Something like:
public class MouseInputHandler : MonoBehavior
{
public event Action<Vector2> MousePressed;
public event Action<Vector2> MouseMoved;
...
void Update()
{
if (Input.GetMouseButton(0))
{
MousePressed(Input.mousePosition);
...
}
}
}
Like stated, you can use it without major concerns, Unity will 'make its magic' internally as to set processing power sensitive code execution for you in terms of polling events. That's the beauty of a modern game engine after all. You normally shouldn't have to be hacking your way around a common feature such a mouse click detection.
However if you don't want to go using the main Update() you can make a CoRoutine if you feel more comfortable with that, just bear in mind that Unity coroutines are not multi-threaded neither, so at the end everything needs to wait anyway.
Seems like I'm confused with the next stuff:
Screen
ApplicationListener
Game
I was trying hard but still can't undestand the difference of these terms.
What I'm trying to do:
Create a Class which will be extended from Game (implements ApplicationListener or Screen), it will be the area, where all actions happen (player movement, spawning enemies, etc). Then create a class that will be probably implemented the Screen. Score, multipliers and some usefull text will be there.
Then I want to create a stage in another class that includes my classes (thin line with score on high of the screen and the area with the game below. In other words I want to divide the game and text).
Hope you get the idea, so how should I realize the classes with the game, score and a main class which includes them? (Screen, ApplicationListener, Game)
Or there is a way how to do it easier?
The ApplicationListener is the entry point of your LibGDX application. LibGDX has several backends to support multiple platforms. All those backends get an ApplicationListener which will be one of your self-made classes.
Game actually implements ApplicationListener which means that you could also supply a Game instead of an ApplicationListener. But a Game has more functionality, since it is a class and not only an interface. It provides you with a basic approach to split your game in several logical parts, which will keep your code more clean. Those parts are called Screens. A Game will always have one Screen which will count as the active one and all the methods from Game are actually just being forwarded to the currently active Screen.
A Screen is one more of your own classes which you implement. It could be a SplashScreen, a LoadingScreen or a GameplayScreen... maybe a MainMenuScreen and an OptionsScreen. What about a HighscoresScreen? You get the idea here. Whenever you want to switch the Screen you will use Game.setScreen() to do so. This in turn will call Screen.hide() on the current Screen and Screen.show() on the next Screen.
The ApplicationListener Interface gives you all the Methods, which are called by the main game loop:
create() is called when your App is started for the first time.
dispose() is called when your App is getting closed.
pause() is called when a call is incoming or you press the homebutton.
resume() is called, when you come back to the App, after pause() has been called.
resize() is called on desktop when you resize the window.
render() is called once every Gameloop (max 60 times per ).
Extending Game does more or less the same, but it allready has some deffault implementations. Those deffault implementations call this functions on the current screen. So if you start your App create() is called on your Game class and this calls create() for your current screen.
A Screen reppresents the things which have to be rendered on Screen. Most times there are different Screens for different logics. So for example a MainMenuScreen a GameScreen and a OptionsScreen. Those Screens can be set by calling setScreen() in your Game class. This automatically calls hide() for the current Screen and show() for the new Screen.
I hope this helps you by understanding Libgdx.
New to GWT here...
I'm using the UIBinder approach to layout an app, somewhat in the style of the GWT Mail sample. The app starts with a DockLayoutPanel added to RootLayoutPanel within the onModuleLoad() method. The DockLayoutPanel has a static North and a static South, using a custom center widget defined like:
public class BigLayoutWidget extends ResizeComposite {
...
}
This custom widget is laid out using BigLayoutWidget.ui.xml, which in turn consists of a TabLayoutPanel (3 tabs), the first of which contains a SplitLayoutPanel divided into WEST (Shortcuts.ui.xml) and CENTER (Workpanel.ui.xml). Shortcuts, in turn, consists of a StackLayoutPanel with 3 stacks, each defined in its own ui.xml file.
I want click events within one of Shortcuts' individual stacks to change the contents of Workpanel, but so far I've only been able to manipulate widgets within the same class. Using the simplest case, I can't get a button click w/in Shortcuts to clear the contents of Workpanel or make WorkPanel non-visible.
A few questions...
Is ResizeComposite the right type of class to extend for this? I'm following the approach from the Mail example for TopPanel, MailList, etc, so maybe not?
How can I make these clicks manipulate the contents of panels in which they do NOT reside?
Are listeners no longer recommended for handling events? I thought I saw somewhere during compilation that ClickHandlers are used these days, and the click listener "subscription" approach is being deprecated (I'm mostly using #UiHandler annotations)
Is there an easy way to get a handle to specific elements in my app/page? (Applying the "ID" field in the UI.XML file generates a deprecation warning). I'm looking for something like a document.getElementById() that get me a handle to specific elements. If that exists, how do I set the handle/ID on the element, and how can I then call that element by name/id?
Note that I have the layout itself pretty well nailed; it's the interaction from one ui.xml modularized panel to the next that I can't quite get.
Thanks in advance.
If you don't have a use for resizing events than just use Composite
What you want is what the GWT devs called message bus (implemented as HandlerManager). You can get a nice explanation in the widely discussed (for example, on the GWT Google Group, just search for 'mvp') presentation by Ray Ryan from Google I/O 2009 which can be found here. Basically, you "broadcast" an event on that message bus and then a Widget listening for that event gets the message and does its stuff.
Yep, *Handlers are the current way of handling events - the usage is basically the same so migration shouldn't be a problem (docs). They changed it so that they could introduce custom fields in the future, without breaking existing code.
If you've set an id for any DOM element (for Widgets I use someWidget.getElement().setId(id), usually in combination with DOM.createUniqueId()) you can get it via GWT.get(String id). You'll get then a RootPanel which you'll have to cast to the right Widget class - as you can see it can get a little 'hackish' (what if you change the type of the Widget by that id? Exceptions, or worse), so I'd recommend sticking with MVP (see the first point) and communicating via the message bus. Remember however, that sometimes it's also good to aggregate - not everything has to be handled via the message bus :)
Bottom line is I'd recommend embracing MVP (and History) as soon as possible - it makes GWT development much easier and less messy :) (I know from experience, that with time the code starts to look like a nightmare, if you don't divide it into presentation, view, etc.)