Source of article: Computer Enthusiast Author: Zhang Jian
Do you still remember the Minicooper who shuttled through Hollywood traffic like an elf in "The Last Day"? Mark Wahlberg and Sally Theron drove it to transport gold worth tens of millions under the noses of their enemies. However, if a Minicooper body that cannot run quickly is placed in front of you now, how would you think of it? Is it still the wandering elf? Today, let us assemble the parts for this Minicooper piece by piece and let it run.
Preface
Starting from this issue, we provide you with the complete game source code (click to download). Java Cafe advocates that everyone pays equal attention to theory and practice. We will introduce key technologies and implementation ideas to you in the series. Friends can read the source code in conjunction with the article, just like reading a newspaper and drinking coffee at the same time. This is where the fragrance of Didi is not exhausted.
game layout
"Lianliankan" is a two-dimensional chess game. If you want to design a chess game, GridLayout should be the best choice. Now let's take a look at the constructor of GridLayout:
・GridLayout(): By default, the layout area is divided into 1*1 size
・GridLayout(int rows, int cols): Specifies the number of horizontal and vertical grids in the layout area
・GridLayout(int rows, int cols, int hgap, int vgap): Same as above, and also specifies the horizontal spacing hgap and vertical spacing vgap between each grid
Don't let these three constructors scare you. In fact, as long as you like it, you can use any of them with confidence. Even if you accidentally use the "wrong" one, there are ways to adjust it in the future. The only thing to note is that when adding controls to GridLayout, the default order is from the upper left to the lower right.
Now let's determine the number of grids for the game. How many grids are appropriate? Too little will make the game less difficult, too much will cause visual impact. Therefore, we should express it through a pair of constants. Even if we want to modify it in the future, it will be a breeze.
In Java, the definition of constants needs to be written in the form of public final static. If we stipulate that the game board has 8 grids horizontally and 8 grids vertically, then we should define it like this:
public final static int ROW = 8;
public final static int COLUMN = 8;
Then, we use the second constructor of GridLayout to create the layout:
GridLayout gridLayout = new GridLayout(ROW, COLUMN);
Finally, we also need to change the layout of the game area (contentPanel) to the above layout:
contentPanel.setLayout(gridLayout);
If you compile and run the program at this time, you may be wondering: Why has there been no change in the interface? Is there something wrong? Although we have specified the layout, no controls have been added, so of course no changes can be seen. Now let's add buttons to the layout:
for (int i = 0; i < ROW * COLUMN; i++) {
JButton button = new JButton("Kyodai");
contentPanel.add(button);
}
Try running the program again. Is it the same as mine (see Figure 1)?
Clever use of JButton to make a fuss
JButton is a button control. It is also an extremely common control in Swing. However, we still need to spend a little effort to understand and use it, because when you are able to use JButton proficiently, you will find other Swing controls. It's also so similar.
If you run the program you just wrote, you will find that the buttons in the game area are always full, which is very inconvenient for actual game operation. Therefore, we have to find a way to free up some grids. The GridLayout layout is all good, but you can't skip a certain grid when adding controls. What should I do now?
In fact, this is not difficult. Since GridLayout does not allow skipping, if we integrate the controls added in a certain grid with the background of the GridLayout layout, we will achieve a consistent visual effect. In addition, if someone else clicks on this grid accidentally, the button will still be exposed. We have to find a way to prevent the button from being clicked, which requires the use of JButton's setEnabled() method. Finally, for clickable buttons, when they are clicked, we have to distinguish which button was clicked.
When we implemented the "About" function last time, we used the e.getSource() method to determine the source of the mouse click event. However, that was only effective for named controls. Here, using an array to represent buttons is undoubtedly the best way. First, let us modify the above code:
JButton[] dots = new JButton[ROW * COLUMN];
for (int i = 0; i < ROW * COLUMN; i++) {
dots[i] = new JButton("Kyodai");
dots[i].setActionCommand("" + i);
contentPanel.add(dots[i]);
dots[i].addActionListener(this);
}
Don't forget to write dots[i] = new JButton("Kyodai") in the loop body. Although the dots group number was defined and used earlier, this only tells the program that we need to use some JButtons, but, These JButtons are still not initialized. At the same time, we not only use setActionCommand() to specify event names for buttons, but also use the addActionListener() method to add event response processing to each button.
Regarding the event response code, we can add it after the original actionPerformed() event code:
if (e.getSource() instanceof JButton) {
JButton button = (JButton) e.getSource();
int offset = Integer.parseInt(button.getActionCommand());
int row, col;
row = Math.round(offset / COLUMN);
col = offset - row * COLUMN;
JOptionPane.showMessageDialog(this, "ROW="+row+", COL="
+ col, "Button", JOptionPane.INFORMATION_MESSAGE);
}
In the above code, e.getSource() instanceof JButton is used to determine whether the generated event is generated by a JButton type control, and then performs forced class conversion on the control that generates the event source, and then uses Integer.parseInt(button The .getActionCommand()) method converts the obtained event name into an integer, and the following code restores this integer to row and column information.
Okay, now run the program and click each button to see if a dialog box like the one on the right will appear?
Note that our subscripts start from 0. The program source code of this issue (click to download).
Using images in Swing
At present, we have solved the user operation problem. In order to make the interface beautiful, we need to use pictures instead of text. Friends who have time and patience can make personalized pictures by themselves, but be careful to keep the size of each picture consistent, otherwise it will be too ugly. If you want to save trouble, you can also directly use the images provided in the download package.
In Swing, you can use the setIcon(Image image) method to set an image for a JButton. The parameter image is the image object we want to set. There are many ways to get this object:
・Use the Toolkit class to obtain:
image = Toolkit.getDefaultToolkit().getImage(url);
・Use the getImage() method of the ImageIcon class to obtain:
image = new ImageIcon(getClass().getResource(filename)).getImage();
We choose the first method here. In order to facilitate obtaining the Image object again in the future, we can write this as a function:
Image getImage(String filename){
URLClassLoader urlLoader = (URLClassLoader) this.getClass().getClassLoader();
URL url = null;
Image image = null;
url = urlLoader.findResource(filename);
image = Toolkit.getDefaultToolkit().getImage(url);
return image;
}
With this function, it will be much more convenient to use images in the future, isn't it?
Now that the picture is available, we can express the map information in Map.Java in the source code package in the form of a picture. Since this code is about the algorithm code of the game, I won’t list the code anymore. Let’s briefly explain how it is done here! In Map.Java, we use a two-dimensional array map[][] to save image information. At the same time, we also use a one-dimensional array images[] to save each image object. Each element in the map has an value. This value not only indicates the value corresponding to the button in the game interface, but also indicates the number of the image in the images[] array used by this button. The program running interface will be much more beautiful.
summary
Today we introduced the JButton control in Swing. For most Swing controls, the usage of JButton can be copied. Don't underestimate this JButton. When you can master it well, your Swing skills will have been improved to a higher level. In addition, we also learned two methods of loading image files in Java. Finally, we combined the above two parts to create a beautiful game interface. Although I have not written the complete code here, I believe that everyone will be able to achieve the goal by referring to my source program and through your own efforts. If you encounter a problem that cannot be solved, you can contact me through [email protected].
I don’t know if you are satisfied with today’s content? The excitement is yet to come, everyone should continue to patronize our cafe!