Falling Blocks
Otherwise known as Tetris (TM). I wanted to create a Tetris-like game for the fun of it, so I started looking around to see what others have done. Soon I found a nice implementation of Tetris using JavaFX by Christian Schudt. Here is a link to his blogspot: http://myjavafx.blogspot.com/2013/12/tetris-with-javafx.html. His version of Tetris is more complicated than some other implementations I could have used, but he used several JavaFX coding techniques that I wanted to learn such as property bindings, so I dove right in.
The game play code is mostly Christian's, but I did fix a few things, moved some things around, and added high scores and options for changing the block colors, the language, and the size of the playing board. Just to do those things I had to really dive into his code and see how he did things in JavaFX. I learned a lot and will definitely be using the techniques in future projects!
The game play code is mostly Christian's, but I did fix a few things, moved some things around, and added high scores and options for changing the block colors, the language, and the size of the playing board. Just to do those things I had to really dive into his code and see how he did things in JavaFX. I learned a lot and will definitely be using the techniques in future projects!
Here is the jar file with the game. Just copy it to your computer and run it.
Note: You will need Java on your PC to run this. |
|
OptionsPlayers have several options they can adjust on this screen.
1. They can choose to play one of three widths: 10, 15, or 20 blocks. 2. They can change the colors of the blocks. I used a JavaFX color picker for this. Players can reset the colors if they want to also. 3. They can choose to see English or Spanish text. Options are saved from session to session in a simple .txt file. If the text file does not exist, it creates a new one - so just download the .jar file and the program will create a new fallingblocks.txt file. |
High Scores
High scores are kept for all three board widths.
Implementation Details
Here are some code snippets of how I did some things....
State Pattern:
I used the State Pattern for each screen in the game. When the player moves from screen to screen, the game changes state.
Constants:
I created a constants.java file to contain any constants used by the program. It is much easier to have one place to update constant values. For example:
final static int HEIGHT = 890;
final static int WIDTH_FOR_10 = 790;
final static int WIDTH_FOR_15 = 970;
final static int WIDTH_FOR_20 = 1140;
Colors:
The player can customize the game colors in the Options screen. The colors are saved in the fallingblocks.txt file.
Here is some code:
final static Color ORIGINAL_I_COLOR = Color.CYAN;
public static Color getORIGINAL_I_COLOR() {return ORIGINAL_I_COLOR;}
. . .
private static Color colorI = Constants.getORIGINAL_I_COLOR();
. . .
This line prints the color in the fallingblocks.txt file:
pw.println(colorI);
The colors in the file look like this:
0x990000ff
The colors are read from the file:
colorI = Color.web(br.readLine());
Languages:
The player can use the Options screen to choose English or Spanish for the text in the game. Their choice is stored in the fallingblocks.txt file.
I created a L.java file that contained variables that are used in all the other classes, and the English and Spanish translations. Here is some sample code:
public static String playText = "xx";
final public static String E_PLAY_TEXT = "Play";
final public static String S_PLAY_TEXT = "Jugar";
public static void useEnglish () {
playText = E_PLAY_TEXT;
public static void useSpanish () {
playText = S_PLAY_TEXT;
css Stylesheets:
I created application.css to hold the game's css. Here is how I connected the stylesheet to the program:
aroot.setId("blocks-background"); //This an identifier in the css file
. . .
scene.getStylesheets().add(AppTitleScreenState.class.getResource("application.css").toExternalForm());
Property Binding:
I haven't used property binding before so I was really interested in seeing it in action. Here is a code snippet showing the Score on the screen being updated as the player's score changes:
private final IntegerProperty score = new SimpleIntegerProperty();
Label lblPoints = new Label();
lblPoints.getStyleClass().add("score");
lblPoints.textProperty().bind(Bindings.createStringBinding(new Callable<String>() {
@Override
public String call() throws Exception {
return String.valueOf(gameController.getScoreManager().scoreProperty().get());
}
}, gameController.getScoreManager().scoreProperty()));
NetBeans:
I tried using NetBeans instead of Eclipse this project just to try it out. I like it. NetBeans seems to be more integrated than Ecli[pse and it is easier to create the .jar file. I like Eclipse's workspaces better than how NetBeans handles projects, but it's not a deal breaker.
Here's a gotcha: NetBeans would read and use image.JPG successfully, ignoring the capitalized JPG, but the jar file could not find the image because it was looking for the file name in lowercase.
State Pattern:
I used the State Pattern for each screen in the game. When the player moves from screen to screen, the game changes state.
Constants:
I created a constants.java file to contain any constants used by the program. It is much easier to have one place to update constant values. For example:
final static int HEIGHT = 890;
final static int WIDTH_FOR_10 = 790;
final static int WIDTH_FOR_15 = 970;
final static int WIDTH_FOR_20 = 1140;
Colors:
The player can customize the game colors in the Options screen. The colors are saved in the fallingblocks.txt file.
Here is some code:
final static Color ORIGINAL_I_COLOR = Color.CYAN;
public static Color getORIGINAL_I_COLOR() {return ORIGINAL_I_COLOR;}
. . .
private static Color colorI = Constants.getORIGINAL_I_COLOR();
. . .
This line prints the color in the fallingblocks.txt file:
pw.println(colorI);
The colors in the file look like this:
0x990000ff
The colors are read from the file:
colorI = Color.web(br.readLine());
Languages:
The player can use the Options screen to choose English or Spanish for the text in the game. Their choice is stored in the fallingblocks.txt file.
I created a L.java file that contained variables that are used in all the other classes, and the English and Spanish translations. Here is some sample code:
public static String playText = "xx";
final public static String E_PLAY_TEXT = "Play";
final public static String S_PLAY_TEXT = "Jugar";
public static void useEnglish () {
playText = E_PLAY_TEXT;
public static void useSpanish () {
playText = S_PLAY_TEXT;
css Stylesheets:
I created application.css to hold the game's css. Here is how I connected the stylesheet to the program:
aroot.setId("blocks-background"); //This an identifier in the css file
. . .
scene.getStylesheets().add(AppTitleScreenState.class.getResource("application.css").toExternalForm());
Property Binding:
I haven't used property binding before so I was really interested in seeing it in action. Here is a code snippet showing the Score on the screen being updated as the player's score changes:
private final IntegerProperty score = new SimpleIntegerProperty();
Label lblPoints = new Label();
lblPoints.getStyleClass().add("score");
lblPoints.textProperty().bind(Bindings.createStringBinding(new Callable<String>() {
@Override
public String call() throws Exception {
return String.valueOf(gameController.getScoreManager().scoreProperty().get());
}
}, gameController.getScoreManager().scoreProperty()));
NetBeans:
I tried using NetBeans instead of Eclipse this project just to try it out. I like it. NetBeans seems to be more integrated than Ecli[pse and it is easier to create the .jar file. I like Eclipse's workspaces better than how NetBeans handles projects, but it's not a deal breaker.
Here's a gotcha: NetBeans would read and use image.JPG successfully, ignoring the capitalized JPG, but the jar file could not find the image because it was looking for the file name in lowercase.