Part 4 – Player Tank and movement

In this episode we will add in the players tank and give them the ability to control it in the left or right direction. This will require some buttons putting onto our board. First the full source code (expand and copy as required). Once compiled and uploaded to your Arduino the display should look like this:

So the first addition you should notice are these three lines

We are setting these “constants” to the digital pins 4 ,5 and 6 of the Arduino. These will be the pins that our buttons are connected to. The next lines are related to the player:

Mostly self explanatory. The PLAYER_X_MOVE_AMOUNT is the number of pixels the players tank moves at a time. The X and Y for the player is the players start position. Lines 106 to 115 (of the main code) define the players “Tank” graphics. If you are not sure about this then please refer to episode 2 where we discuss the graphics in more detail.

Next we have added a structure for the player:

Just like the Invader (AlienStruct) in the previous episode this at present just holds the position of the players tank.

Line 156 initialises the player variable as a global variable (accessible to all parts of the code)

The setup routine has been expanded quite a lot:

The InitPlayer initialise the player (more on that shortly) and then we set some pin modes for the Arduino pins that we will connect our buttons to. We are using the Arduino built in constant INPUT_PULLUP. This means these pins will be used for inputs and that we will used the Arduinos internal 10K (10,000) Ohm resistors to connect them (pull them up) to +5V.  Why do we do this?…

Floating Inputs
On most electronics inputs, whether they are microprocessors (like the Arduino) or other types of chips, they should always be connected to something if you intend to use them in some way. If they are left “floating” i.e. with no connection to anything then they can give false values. That is to say they could report a 1 (+v) or 0 (gnd)  input when actually the pin has not been set to any value by the user. Now traditionally in these situations you simply add a 10K resistor (although any high value resistor will usually be OK) to the input pin and connect it to either the positive or negative voltage. If connected to the positive then the pin will always report a “1” unless you deliberately connect it to the negative supply rail (gnd for our purposes). If connected to the 0V then it will always report a “0” unless we deliberately connect it to the +v rail. In either case the input value is most definitely a 1 or a 0. If you do not do this then you could get spurious 1‘s or 0‘s on the input pin when it is not deliberately connected to a voltage rail. The designers of the Atmel processor used by the Arduino spoilt us by putting some 10K resistors inside the chip, nice 🙂 So we don’t need to add them ourselves, to use them we just need to use INPUT_PULLUP setting to enable this and the pin will automatically be connected to the +ve rail via a 10K resistor.

So this pin will always report a “1” when we read it unless we connect it to the 0V rail. This is important to note when we come to wire up our pins to the push switches and when we come to read the values from the pins and make sense of them.

Wiring the buttons
We have three buttons to wire up, Left,Right and Fire to Arduino pins 4,5,6 respectively. Diagram and real life wiring below (Click for large view):

Actual real world wiring

So as can be seen when a button is pressed it connects that pin to ground (0V). When we look at that pins value it will read a 0 of pressed and a 1 if not pressed.

Player Control
So where do we scan for these button presses, within the Physics routines mentioned in the last episode, here is the function again with an important addition:

Let’s look in more detail at the PlayerControl function:

We scan for two button presses at present (as fire is not yet implemented). If the RIGHT_BUT pin is 0 then we’ve pressed the right move button, BUT we only update the players X position if the end of the tank is still on screen – (Player.Ord.X+TANKGFX_WIDTH<SCREEN_WIDTH),  If it is we simply increase the players X position by the amount of pixels the player moves per move (PLAYER_X_MOVE_AMOUNT).

Similarly, the LEFT_BUT is scanned and if the pressed and the players X position is still on screen then the X position will be decremented by the player movement amount. This all ensures that the tank cannot go off the ends of the screen.

Displaying the player
Added to the UpdateDisplay function is just one line that plots the players tank

Initialising the player
Back at the start we saw that we called a player initialise routine, here it is:

At present it doesn’t do much apart from set the players initial start position. That’s it for this episode, you should now have some marching Invaders and a move-able Tank, it really should be starting to look like a playable game now 🙂 Next time we’ll look at firing a missile and implementing the destruction of those pesky Invaders!

Enjoy and Learn 🙂