Is it the 10th Advent Calendar?
This time I would like to make a simple rock-paper-scissors game with the title. I hope you read it with the recognition of the continuation of the JavaFX introduction article I posted earlier. -First JavaFX ~ Easy introduction Hello world GUI creation ~
-macOS Sierra 10.12.6 -Eclipse Oxygen 4.7.3a (e (fx) clipse installed by plug-in) -Scene Builder2.0
This time, the difference from the previous article is the element that uses images to create packages other than application.
The flow in the game created this time is assumed to be as follows.
This time I borrowed it from a free material site.
-Illustration of rock-paper-scissors-goo -Illustration of rock-paper-scissors, choki, piece -Illustration of rock-paper-scissors / par
--application: FX GUI related sources are here --game: This rock-paper-scissors process goes here --pic: Put an image of rock-paper-scissors hand. Goo: Rock.png, Choki: Scissors.png, Par: Papaer.png
Operate within SceneBuilder.
As a preparation, create a JavaFX project with eclipse in the same procedure as last time.
The project name should be "JankenFX". (It can be anything)
After the project is generated, partially rewrite Main.java of the application package.
Scene scene = new Scene(root,400,400);
The line that is
Scene scene = new Scene(root, 500 ,400);
Rewrite to. That's all for preparation.
After completing the preparation, open Form.fxml with SceneBuilder.
At first, there is nothing in the center, so click Border Pane at the bottom left of the screen and set the Pref width to 500 and Pref Height to 400 in the Layout on the right side of the screen. At this point, you should see a white panel in the center of the screen.
I will paste the image of the state when the work with Scene Builder this time is finished first.
The operations performed for each location of BorderPane are as follows.
Top --Label: Write a sentence according to the title and progress. "Label_text" is written in fxid.
Center -HBox: The parts inside the HBox are evenly arranged horizontally. Alignment in propaties is set to CENTER. In HBox --ImageView (left): Draws your own rock-paper-scissors hand. I am writing "image_player" in fxid. --ImageView (right): Draws the opponent's rock-paper-scissors hand. I am writing "image_enemy" in fxid.
Left --Label: I wrote "you" in the propaties text so that I could identify it as my own.
Right --Label: "Ai" is written in the propaties text so that you can tell that it is the other party's hand.
Bottom --HBox: Explanation omitted In HBox --Button (OK): A button for advancing the game screen. fxid is "button_OK" and On Action is "onOKClicked". --Button (Goo): It is a button to put out your hand with rock-paper-scissors. fxid is "button_Rock" and On Action is "onRockClicked". --Button (choki): It is a button to put out your hand with rock-paper-scissors. fxid is "button_Scissors" and On Action is "onScissorsClicked". --Button (par): It is a button to put out your hand with rock-paper-scissors. fxid is "button_Paper" and On Action is "onPaperClicked".
The Form.fxml that has been operated and filled out so far is as follows.
Form.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="500.0"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="application.FormController">
<bottom>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="button_OK" mnemonicParsing="false" onAction="#onOKClicked" text="OK" />
<Button fx:id="button_Rock" mnemonicParsing="false" onAction="#onRockClicked" text="Goo" />
<Button fx:id="button_Scissors" mnemonicParsing="false" onAction="#onScissorsClicked" text="Choki" />
<Button fx:id="button_Paper" mnemonicParsing="false" onAction="#onPaperClicked" text="Par" />
</children>
</HBox>
</bottom>
<top>
<Label fx:id="label_text" alignment="CENTER" prefHeight="80.0" prefWidth="400.0" text="Rock-paper-scissors game" BorderPane.alignment="CENTER">
<font>
<Font size="20.0" />
</font>
</Label>
</top>
<center>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<ImageView fx:id="image_player" fitHeight="188.0" fitWidth="200.0">
<image>
<Image url="@../pic/Rock.png " />
</image>
</ImageView>
<ImageView fx:id="image_enemy" fitHeight="188.0" fitWidth="200.0">
<image>
<Image url="@../pic/Rock.png " />
</image>
</ImageView>
</children>
</HBox>
</center>
<right>
<Label text="Open" BorderPane.alignment="CENTER">
<font>
<Font size="15.0" />
</font>
</Label>
</right>
<left>
<Label text="you" BorderPane.alignment="CENTER">
<font>
<Font size="15.0" />
</font>
</Label>
</left>
</BorderPane>
There are two programs to create, one is to add FormController.java and the other is to create Battle.java in the game package. I think that the source created this time is ** a wasteful source ** due to the lack of experience of the author. Please note.
FormController.java The rewritten version is as follows.
FormController.java
package application;
import java.util.Random;
import game.Battle;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class FormController {
@FXML private Button button_OK;
@FXML private Button button_Rock;
@FXML private Button button_Scissors;
@FXML private Button button_Paper;
@FXML private Label label_text;
@FXML private ImageView image_player;
@FXML private ImageView image_enemy;
private Battle battle= new Battle();
private final Image ROCK= new Image("pic/Rock.png ");
private final Image SCISSORS= new Image("pic/Scissors.png ");
private final Image PAPER= new Image("pic/Paper.png ");
private int hand_player;
private int hand_enemy;
private int result; //Hold the result of rock-paper-scissors as an int
private Random rand= new Random(); //Randomly generate the opponent's hand
//Progress 1(Waiting for rock-paper-scissors input)Advance progress at times other than
@FXML
public void onOKClicked() {
if(battle.getPhase() != 1){
battle.nextPhase();
draw();
}
}
@FXML
public void onRockClicked() {
if(battle.getPhase() == 1) {
hand_player= 1;
hand_enemy= rand.nextInt(3)+ 1;
result= battle.battle(hand_player, hand_enemy, battle.getPhase());
battle.nextPhase();
draw();
}
}
@FXML
public void onScissorsClicked() {
if(battle.getPhase() == 1) {
hand_player= 2;
hand_enemy= rand.nextInt(3)+ 1;
result= battle.battle(hand_player, hand_enemy, battle.getPhase());
battle.nextPhase();
draw();
}
}
@FXML
public void onPaperClicked() {
if(battle.getPhase() == 1) {
hand_player= 3;
hand_enemy= rand.nextInt(3)+ 1;
result= battle.battle(hand_player, hand_enemy, battle.getPhase());
battle.nextPhase();
draw();
}
}
//Update the drawing according to the progress
public void draw() {
switch (battle.getPhase()) {
case 0:
label_text.setText("Jaken game");
image_player.setImage(ROCK);
image_enemy.setImage(ROCK);
break;
case 1:
label_text.setText("Rock-paper-scissors, rock-paper-scissors...");
break;
case 2:
image_player.setImage(changeImage(hand_player));
image_enemy.setImage(changeImage(hand_enemy));
switch (result) {
case 1:
label_text.setText("You win! !!");
break;
case 2:
label_text.setText("You lose...");
break;
case 3:
label_text.setText("This is Aiko!");
default:
break;
}
break;
default:
break;
}
}
//Update the image of rock-paper-scissors hand
private Image changeImage(int hand) {
switch (hand) {
case 1:
return ROCK;
case 2:
return SCISSORS;
case 3:
return PAPER;
default:
return ROCK; //exception
}
}
}
Battle.java
package game;
//Class that processes rock-paper-scissors
public class Battle {
private int phase; //Hold the progress of the game
//Progress 0 on object creation:Initialize on the first standby screen
public Battle() {
this.phase= 0;
}
//Process rock-paper-scissors. 1 if you win,2 if you lose,Returns 3 for Aiko
public int battle(int p, int e, int phase) { //p:My hands, e,Opponent's hand
if(phase==1) { //Progress 1:Operates only when waiting for input
//Rock-paper-scissors hand is goo:1,Choki:2,Par:3
if(p==1) {
if(e==1) return 3;
else if(e==2) return 1;
else if(e==3) return 2;
}
else if(p==2) {
if(e==1) return 2;
else if(e==2) return 3;
else if(e==3) return 1;
}
else if(p==3) {
if(e==1) return 1;
else if(e==2) return 2;
else if(e==3) return 3;
}
}
return -1; //exception
}
//Take progress to the next stage. Update to 0 when phase reaches 3
public void nextPhase() {
phase++;
if(phase>2)phase= 0;
}
//Progress getter
public int getPhase() {
return phase;
}
}
Once you have created the above two classes and copied and pasted the rock-paper-scissors hand image into the pic package, you are done. thank you for your hard work.
Initial screen![Screenshot 2018-08-22 21.26.09.png](https://qiita-image-store.s3.amazonaws.com/0/281151/426cae40-d493-3de0-328e-80fccf3eed35. png)
Input waiting screen
Result: Press the OK button to return to 1.
This time, in a position that is an extension of the previous Hello World, I created a rock-paper-scissors game by using a class in another package and reading images. We would appreciate it if you could use it as a practice material by changing the image to be used or changing the layout with SceneBuilder.
Thank you for reading this far.
Recommended Posts