Update 1. Added ChessMen move logic 2. Adjust ChessMen pieces flashing and stopping flashing logic 2. Add custom font display instructions (font-spider and skills) 3. Added compatibility section: Canvas Background Color Compatibility 2020.03.10 Update: 1. 2. Adjust the webpack.config.js file to the outer chain 3. Add a description of how to build a parcel 4. Adjust the componentized text 5. Add ChessMen chess drawing, erasing method introduction 6. Add ChessMen chess flashing, stop flashing, move logic introductionCopy the code
Cause 1.
I have been in touch with programming for nearly 10 years. It is a pity that I have been lost in business from my initial feeling of liking coding. This article will discuss with you how to realize a Chinese chess game from the perspective of interest.
Why do you choose the topic of Chinese chess? Firstly, it is the first chess game that the blogger learned, and the general with two guns taught by his father when he was a child still remembers it. Secondly, relative to pure business, this topic is also more interesting, not only can exercise programming skills, but also can entertain yourself, kill two birds with one stone. Without further ado, let’s begin!
2. The initialization
As the blogger is in the React stack, the following technologies are related to React, but mainly canvas.
A mature create-React-app was not selected for project initialization.
First build tool: Webpack
To add webpack.config.js, click to view the configuration
Don’t be afraid if you are not familiar with Webpack, these configuration bloggers are not written at a time, according to the needs to find the Webpack document, and hand knock configuration, do not copy and paste, after writing will have a new experience.
Version 2 build tool: Parcel
Thanks for the suggestion of @circle circle circle. After trying it out, Parcel does a great job with zero configuration.
Add.babelrc file
{
"plugins": ["@babel/plugin-proposal-class-properties"],
"presets": ["@babel/preset-react"]
}
Copy the code
Modify the start and build commands
"scripts": {
"start": "parcel ./index.html -p 6888",
"build": "rm -rf dist && parcel build --public-url . ./index.html"
},
Copy the code
3. The modular
React componentized approach.
Create components in the Component directory
ChessBoard
The boardChessMen
pieces
3.1. ChessBoard
thinking
Observe the checkerboard picture. There are 9 horizontal cells and 10 vertical cells.
After analyzing the necessary theme parameters of a checkerboard (grid line width, grid line color, background color, border line width, border color, border spacing, text color), we decided to use canvas to realize checkerboard drawing.
There are two reasons for not using images:
-
- Easy to customize the checkerboard style, you can easily change the checkerboard style by modifying the theme parameters
-
- Helps to think about grids and positioning
3.2. ChessMen
thinking
First, whether to reuse the same canvas with ChessBoard, or to overlay another canvas on the canvas of ChessBoard?
In order to avoid redrawing the ChessBoard when flashing and moving pieces, we decided to adopt the overlay scheme ~
Second, how to manage the position, text, red and black of the chess pieces
As shown below:
- 1. Use a two-dimensional array to manage the position of the pieces, according to the pieces
${colorType + colorName + colorIndex}
Joining together, such as24
On behalf ofA black car
No chess pieces are used0
- Definition 2.
COLOR_TYPE
Manage the pieces red and black - 3. Define
RED
,BLACK
Object management text in red and black
4. Draw
One thing to think about before drawing, because the screen of the device is different, the checkerboard can be large or small, if we draw the width of 50, not all devices.
So we need to calculate the width and height of the grid first, because the grid is square, so it is called width in the code.
1. The screen width is subtracted a fixed value as the maximum width. A bit of padding is better after all. 2. Compare the horizontal and vertical values divided by the number of cells and use the smaller value as the cell width.
With cellWidth in place, let’s start the actual Canvas operation!
4.1. The grid
You can imagine how to draw grids in junior high school. In fact, it is the same in canvas. It is not necessary to think that computers are mechanical, but they are drawn one by one.
Draw 10 lines across and 9 lines across, and you get a grid structure like this
This is to use some knowledge of the for loop, and then keep moveTo, lineTo in the loop.
Careful friends may have observed that there should not be vertical lines in the Chu River and Han Dynasty. Here we are not according to the vertical line is the first, nor the last, so we can simply deal with it.
And when we do that, we get a checkerboard that looks like this
We just need to draw the handsome and will be in the throne of xx.
There is a wrapper around the moveTo, lineTo methods in the component code, and the return this, chained call with comments to make the code move more clearly. Those of you who know jquery will smile because it’s so familiar.
4.2. The border
There is also a border around the checkerboard grid. There is nothing to say about drawing four lines, but for those of you who want to draw lines continuously, we can simply add CTX lineTo and moveTo to our component methods. This allows you to move moveTo again without having to lineTo a certain point.
4.3. The text
Use fillText API to increase the chu river han boundary. To make the font look nice, STKaiti was used.
Since not all devices have this font, we need to download the stkati. TTF source file first and use a font-spider with an HTML file to reduce stkati. TTF from 12.1MB to 20KB.
There is a problem to be noted here. If you want to use custom font in canvas, you must first load this text with HTML tag, otherwise it will be invalid when you draw the font for the first time.
The blogger also made a mistake by placing HTML loaded text in div #app, so it is possible to render the text before parsing the DOM, causing the font not to parse first.
4.4 pieces
The main need to draw chess pieces through the following methods:
Ctx. arc: Draw circles
Ctx. lineWidth: sets the lineWidth so that the pieces appear to have an inner circle and an outer center circle
Ctx. fillText: fills the text
CTX. ShadowOffsetX&Y shadowBlur shadowColor set shadows to make the pieces more three-dimensional
4.5. Erase the pieces
Searched the ready-made scheme on the Internet, but did not analyze the code principle.
5. Logic
5.1. Point position judgment
To get the click position of the mouse in canvas, we can use event.layerX, event.layerY.
After the location is obtained, it needs to be associated with the coordinates using the following logic:
Click with canvas position layerX | Y cellWidth width divided by the number of grid, subtracting the chessboard.
5.2. Blink and stop blinking
Based on the position coordinates of the click, make the following judgment:
Flash:
- Timing 1 second, wipe out the chess pieces, delay 500ms to draw chess pieces
- And record the coordinate position and color of the last click
- It must be a round to trigger the flicker
Stop flashing:
- If this time click the chess piece is the same as last time, clear the 1s erasing and drawing timer.
- If the chess piece clicked this time is different from the last time and is of the same side, clear the 1s erasing and drawing timer first, and then execute the blinking logic.
5.3 Rules of The game –isShouldMove
First, based on the following two points
- The same color should not be moved, such as moving a red car to a red car
- The same position should not move, because moving will trigger a round change
Let’s look at the movement rules for different types of pieces
I is the target ordinate, j is the target ordinate, this.lasti is the pre-move ordinate, this.lastj is the pre-move ordinate
5.3.0. | jailer
Cross the river or not: just walk one space up and down
Has crossed the river: as long as it is horizontal regardless of the direction, as long as a grid can be
5.3.1. Handsome | will be
Fix 9 points and move only one space at a time vertically or horizontally.
5.3.2. | gentleman
Fixed 5 points and moved one space both vertically and horizontally at the same time.
5.3.3. | like
At the same time in the vertical and horizontal move two squares, and the direction of the movement of the middle point without chess pieces. At the same time, don’t cross the river.
5.3.4. Car
Take only the longitudinal example to judge that there is only one piece (the car itself) or two pieces (the car itself and another piece, and the piece is at the end of this displacement) on the moving path.
5.3.5. Ma
Move two squares vertically and one square horizontally at the same time.
| | at the same time on the lateral movement and two longitudinal mobile one)
And move two squares on the direction of the middle point without chess pieces
5.3.6. Gun
Take only the longitudinal example to judge that there is only one piece (the gun itself) or three pieces (the gun itself, the middle piece and the target piece, and the target piece is at the end of this displacement) on the moving path.
6. The adaptive
Based on the following two points, adaptive is supplemented.
1. Grid width is first calculated, which is naturally adaptive. 2. Font position and size are multiplied by 'cellWidth', so it should not be a problem.Copy the code
Use Window to listen for resize events + stabilization + redraw.
2010.03.08 Because the elements on the board are still relatively simple, if the pieces are added later, there may be performance problems, and the pieces need to be drawn after resize, so the state management of the pieces is needed.
There will be no performance problems in the initial test of chess piece redrawing, but I do not know the power consumption related problems, so it is suspended ~.
7. Compatibility
When setting fillStyle for canvas CTX, if you want to use transparent background, you should use RGBA mode. Using # XXXXXXX 8-bit color code will cause the background to be black on many devices.
8. Write at the end
The original is not easy, I hope you can dig friends sprout a little thumb, encourage!
Github address: Github for Chinese Chess (React version)
Preview: Chinese Chess (React Version)
Thanks for reading!