Skip to content

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

Esan Sang Sang Sang

Esan Sang Sang Sang

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 is0, add it first every time4, then divided by2, and see what happens:

  • initial:0
  • 0+4=44÷2=2
  • 2+4=66÷2=3
  • 3+4=77÷2=3
  • 3+4=77÷2=3
  • ...

You'll notice that the last value always seems to be3
If we don't continue to add4, what will happen?

  • initial:0
  • 0+4=44÷2=2
  • 2+4=66÷2=3
  • 3+4=77÷2=3
  • 3+4=77÷2=3
  • 3÷2=1
  • 1÷2=0
  • 0÷2=0
  • ...

If we don't continue to add4, this value will change from3become1, and then return to the initial0 Did you notice anything strange?
Let’s look directly at the resulting numbers:

0
2
3
3
3
1
0
0

You will find that when the value is added4During this period of time, the value will look like23331, that is, starting with2, the middle is3, ending with1。 In other words, we only need to add4, and then continue to divide by2, 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 process4Change to plus6

0
3
4
5
5
2
1
0

If the value is3, it means starting to press and hold the right button If the value is1, it means release the right button Otherwise as long as it is not0, 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?

0
0
3 🕹️
1
0
0

What if you press it longer?

0
0
3 🕹️
4 🕹️
2
1
0
0

What if contact is discontinued?

0
0
3 🕹️
4 🕹️
5 🕹️
2
5 🕹️
2
1
0

You will find that as long as+4or+6back÷2, no matter how you do it, this value is based on2or3Start with1ended. 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, only3and2Divide by2will get1, other numbers will not. And other numbers are divided multiple times by2After that, you will eventually come back to2
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.

bash
# 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, by(currentvalue+inputvalue)÷2The 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 | |----------|----|----------------| | +4Halving |2|Start by right-clicking | | | 3| Long pressing the right button | | | 1| Release the right button | | | 0| No operation | | +6Halving |3|Start by right-clicking | | | 1| Release the right button | | | 0| 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 settingexampleThe 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)

Powered by VitePress and GitHub Pages