In our last project, we created a basic Minecraft game controller and wrote the code to allow us to map the buttons and accelerometer to specific functionality related to Steve, our Minecraft character.
In this project, we will implement the same functionality as we did previously, but we will revise the code to use a Dictionary to map the button inputs to functionality, making the program much more simple and straightforward. This will be the foundation of our future Minecraft programs.
Our goal with this project is to greatly simplify the button controls we implemented in our Minecraft Controller 1 project. This will make future controller projects easier to write and will also make the code easier to read and debug.
As a reminder, here is the code from the previous project that we're going to focus on changing:
Specifically, in this project, we're going to make two major changes to the code above:
We will use a Dictionary to define the button controls and use a
for
loop to reduce the large number of if/else
loops
We will greatly simplify the remaining if/else
statement in
our code
for
loopThe first thing we're going to do to simplify our code is to use a Python Dictionary to enumerate (create a list of) our button controls.
If you recall, a Dictionary maps a set of keys to their values. In this
case, the set of keys will be the buttons and their respective GPIOs, and the
values will be the specific control
commands for each:
Now that we have our button control definitions in a Dictionary, we can
replace the large number of if/else
statements (one set for each
button) with a for
loop and single set of if/else
statements:
if/else
statementIn our code above, we use a four-line if-else statement to check each controller button (to see if it was being pressed) each time through the game loop:
While this works just fine, using four lines of code to complete this task is more cumbersome than necessary.
NOTE:You may notice that in the Minecraft Controller 1 project and in the
above step, we did not include release=False
in the first
action
statement. That's because this is the default assumption
of the function, and therefore it's not needed. We include it above, as it
will make the next part of this discussion more understandable.
As you can see, the first line of the code above tests whether the button is being pressed. If so, the second line of code takes specific action; if not, the third and fourth lines of code stop the specific action.
Those four lines of code can actually be condensed into the following single line of code, which does the exact same thing:
If it's not clear why the single line of code above is equivalent to the original four lines of code, let's break it down in a little more detail.
You'll notice that the original four lines of code essentially accomplish the following two things:
If button.is_pressed()=True
, then
action(release=False)
If button.is_pressed()=False
, then
action(release=True)
In other words, the result of button.is_pressed()
is changed
to the opposite and inserted into the action(release=...)
statement.
The not
keyword is referred to as a "boolean operator," and
it is used to flip False to True (0 to 1) and True to False (1 to 0). The
statement:
action(release=(not button.is_pressed()))
simply takes the result of button.is_pressed()
, flips it and
inserts the result into the release=...
statement.
We can now replace the if/else
statement in our
for
with the single statement:
Here is what the full code for this project should look like. The functionality is equivalent to the functionality in the Minecraft Controller 1 project, but the code is much more compact and readable: