In the previous post, I have explains some auxiliary sprites and some code segments of Pen sprite. In this post, I will explain all the other main code segments of Pen sprite and finalize the analysis of this project.
So let’s begin now.
“when Start clicked” main segment
This is the main code segment of Pen sprite. When the player presses the green Flag, this code segment will enter into a forever loop. Within the loop, it first erases all the previous pen traces, and then renders the tiles by calling “render” block.
Please note the use of variable “start?”. No matter its value is True or False, “erase all” and “render” blocks will always execute because at the initiation stage, when the mouse hovers over different Choose Number sprite clones, the tiles should be erased and then rendered again.
When “start?” variable is 1, besides rendering the tiles, the program will check which tile id the mouse is hovering over by calling “get hover id at” block. The next step, it will record those tiles which could move to the empty position by calling “find swap options” block (which I introduced in Post 1).
The program will then make a judgement. When the mouse is pressed down, the current hovering id is within the “swap options” list and “won?” variable is 0 (means that the puzzle is not solved), it will call “move hover id to open spot” (which I explained in Post 1) to move the current chosen tile to the empty position, and then check if the player wins the puzzle game.
We could see that the main code segment “when Start clicked” encapsulates many different blocks. Many blocks need to conduct some logic judgement or mathematical calculation within them. However, don’t forget that computer is running very fast, so all the above operations within one iteration could be finished within just a fraction of a second and the player will feel that the game responds very fast to user action.
Block definitions such as “find swap options” and “move hover id at” have been explained in the Post 1 because those two blocks need to be used when shuffling the tiles. Therefore, in this post, I will mainly focus on explaining two function blocks – “render” and “get hover id at”.
Rendering function blocks
“Render” Block Definition
This block is simple. It iterates the whole “tile order” list to render each tile by calling “render tile” block, whose definition is shown below.
“render tile” block definition
In this block definition, it receives two input parameters. One is “val” which represents the tile’s value. The other is “loc” which represents the tile’s sequence in the “tile order” list.
The first step the program does is to generate “xloc” and “yloc” based on the value of “loc”. “xloc” represents which column the tile is located at. “yloc” represents which row the tile is.
When “val” is equal to “loc”, the tile is just put at the proper location when the puzzle is solved. The program will draw a white backdrop surrounding that tile, as shown in the below diagram. It does not mean that the tile could not move to other position later, but just reminds the player or gives a tip that the final position for this tile is just at that place.
However, since the game board is in light purple, the white color is not easy to be recognized. It would have better effect if the color changes to some high contrast color such as blue or orange.
After that, the program sets pen brightness and saturation based on “val” – the tile’s value. Till now, the “render file” block has not actually rendered the tile, yet. It will pass the real rendering work to another block “render rounded rectangle at” block. When the tile is hovered over by mouse, render its size a bit bigger (TILE SIZE * 0.75), otherwise, render its size as (TILE SIZE * 0.7).
I will introduce “render rounded rectangle at” block in the below section. Before that, I would like to explain how “render file” block passes the input parameters to “render rounded rectangle at” block.
Calculate a tile’s rendering coordinate
In the above “render tile” block, you might notice that the input parameters of “render rounded rectangle at” looks very complicated.
For input “x”, it represents the x value of the tile’s center point. It uses the formula: x = (xloc – 0.5) * (TILE SIZE) – (BOARD SIZE) /2.
For input “y”, it represents the y value of the tile’s center point. It uses the formula: y = (BOARD SIZE) / 2 – (yloc – 0.5) * (TILE SIZE)
The purpose of the above two formula is to convert the column position (“xloc” variable) and row position (“yloc” variable) into the real coordinate values on the stage. Take an example of the tile located at column 2, row 1, the calculation of X and Y is shown in the below diagram.
“render rounded rectangle at” block definition
Once getting the center point coordinate (x, y) of a tile, tile size and roundness, the block “render rounded rectangle at” could begin to work. It finds out the top-left corner’s coordinate of the tile, and then drives the pen stroke from left to right. The pen naturally has a round shape at the both ends. The 20 pen strokes overlap each other to finally form the round corner tile.
Detect if won
The win condition is that each item value in “tile order” is equal to its sequence. If any tile’s value is not equal to its sequence in “tile order” list, the puzzle is not solved, yet. The program will set “won?” to 0 and exit this code segment.
Retrieve Mouse Position
“get hover id at” block definition
This block will “translate” the current mouse position into the tile’s index in the “tile order” list. It is kind of like a reversed process of “render file”.
It first excludes the condition that the mouse hovers outside of the board area, where the hover id will be set to “none”. If the mouse hovers within the area of game board, it calculates the “hover id” based on the mouse’s x and y value, BOARD SIZE and TILE SIZE. “hover id” corresponds to the item’s index in the “tile order” list. I will not explain those formulas further in this post, leaving it to readers to understand them.
Till now, all the major blocks of Pen sprites have been covered. After combining all the above function blocks together, the game now could run properly.
At the end of the post, I would like to give my personal opinion.
I am really impressed by the rendering functionality. Since this project uses purple color tones, it chooses to draw the tiles using pen functionality of Scratch. The challenging point is how to find out the coordinate and render rounded tiles accurately. Such a round corner square actually is drawn by overlapping the pen strokes together.
Another challenge is how to know which tile the mouse is hovering over. Again, since the tiles are not sprite clones, but images, the program needs to convert the mouse position into hovering id by using some mathematical formulas. The conversion is interesting and involves lots of brain twisting.
The same game could be implemented by other methods, such as using the sprite clones to show the tiles. The implementation will be different, but an interesting topic. We might analyze another sliding puzzle project using sprite clones in near future, so stay tuned!
Note: All the analysis articles are copyright products of http://www.thecodingfun.com. Anyone re-posting them should credit author and original source. Anyone using them for commercial purposes or translating them into other languages should notify TheCodingFun and get confirmation first. All Rights Reserved.