Translation notice
This page was translated with machine translation and may contain inaccuracies. If you can help improve it, please open an issue or submit a pull request.
Better right-click detection: Halving method
Let’s look at a performance improvement solution for right-click detection:
Right-click detection (halving method)
Before we start, let’s do an experiment: If a scoreboard value initially is, add it first every time, then divided by, and see what happens:
- initial:
- ,
- ,
- ,
- ,
- ...
You'll notice that the last value always seems to be。
If we don't continue to add, what will happen?
- initial:
- ,
- ,
- ,
- ,
- ...
If we don't continue to add, this value will change frombecome, and then return to the initial Did you notice anything strange?
Let’s look directly at the resulting numbers:
You will find that when the value is addedDuring this period of time, the value will look like, that is, starting with, the middle is, ending with。 In other words, we only need to add, and then continue to divide by, you can get the right-click status. This is where the name "halving method" comes from.
However, players who are familiar with command will say that right-click advancement detection is very unstable and often disconnects. In this way, during a long press, the detection will start immediately after the end due to disconnection. So this method cannot be used? No, we can add it to the processChange to plus:
If the value is, it means starting to press and hold the right button If the value is, it means release the right button Otherwise as long as it is not, indicating that you are pressing and holding the right button But some people will say, what will happen if I press and release it immediately?
🕹️
What if you press it longer?
🕹️
🕹️
What if contact is discontinued?
🕹️
🕹️
🕹️
🕹️
You will find that as long asorback, no matter how you do it, this value is based onorStart withended. This property can only be satisfied by dividing by 2, which is why it is called the "halving method".
Why is this? In this process, onlyandDivide bywill get, other numbers will not. And other numbers are divided multiple times byAfter that, you will eventually come back to。
Due to space limitations, this video does not carry out strict mathematical proofs. If you are interested you can prove it yourself.
Next, I will post the complete code without further explanation.
# example:rmb/using_item
# ...右键运行example:rmb/run的进度
# example:load
scoreboard objectives add rmb_flag dummy
scoreboard objectives add example dummy
scoreboard players set 2 example 2
# example:rmb/run
scoreboard players add @s rmb_flag 4
advancement revoke @s only example:rmb/using_item
# example:tick
execute as @a at @s run function example:rmb/player_tick
# example:rmb/player_tick
scoreboard players operation @s rmb_flag /= 2 example
execute if score @s rmb_flag matches 2 run say 开始长按右键
execute if score @s rmb_flag matches 3 run say 正在长按右键
execute if score @s rmb_flag matches 1 run say 松开右键summary
In this tutorial, we learned a high-performance right-click detection scheme-the halving method. The knowledge points involved are:
Halving method:
- Taking advantage of the properties of integer division, byThe formula of , completes the state flow within a variable
- If you need touch-off protection, you only need to modify the numbers and do not need to add new logic.
State mapping table
| Scheme | Value | Meaning | |----------|----|----------------| | Halving ||Start by right-clicking | | | | Long pressing the right button | | | | Release the right button | | | | No operation | | Halving ||Start by right-clicking | | | | Release the right button | | | | No operation | | |Other values| Long pressing the right button |
- scoreboard operations
- Constant setting: The scoreboard operation does not support direct division by numbers. A "constant score" must be set first (such as setting
exampleThe score is2) as the divisor. - Operation instructions:
- Input signal:
scoreboard players add @s rmb_flag 4(Executed in the function triggered by advancement) - Status decay:
scoreboard players operation @s rmb_flag /= 2 example(Executed in Tickfunction)
- Input signal:
- Constant setting: The scoreboard operation does not support direct division by numbers. A "constant score" must be set first (such as setting