2 Player Competitive VS Timing Game
343 Views, 3 Favorites, 0 Comments
2 Player Competitive VS Timing Game
You will need:
1.Digilent Basys 3, FPGA Board (or any other FPGA, )
2. A relatively up to date version of Vivado, or some other VHDL environment
3. A computer that can run the mentioned program.
The Game Itself
How the FSM interacts with the modules.
How to play
To start, you press the middle button. This will cause “99”, representing the health of player two, to display on the seven segment display. Then, the LEDs will light up sequentially from right to left. This forms a power bar. Once the power bar is full, it resets. The object of player one is to flip their switch when the bar is as high as possible. The more LEDs lit up, the more damage player one does to player two. After player one flips their switch, the damage dealt is deducted from player two’s health. Then, it switches to player two’s turn. Now, the number displayed represents player one’s health, and the power bar fills up from left to right. Once player two makes their move, the damage is deducted, and it is back to player one’s turn again. This repeats until one player reaches 0 health. Video of this functioning is attached.
FSM
This game is essentially one big finite state machine, which some complex logic happening based on the state that the FSM is in.
State 1: Menu
The first state is the menu screen, which is one of the simpler states. It includes the seven segment display displaying the word “PLAY”, and the button that causes the game to start. The button, BTN, leads us to the next state, which is player one’s turn.
State 2: Player One’s turn
Player one’s turn activates a signal that causes the seven segment display to display Player two’s health. Another signal turns on to activate a shift register imported from another module that we created (Pone.vhd). This shift register makes the LED’s light up like an increasing power gauge would in other games, and it would then reset to 0 when it reaches the max amount of LED’s that could be lit. It updates on the rising edge of the clock obtained from barclock.vhd, which is modified from a borrowed lab file. We had player one’s bar start from the right, and fill up to the left, because player one’s switch is also on the left (for intuitive user experience). Once the switch is flipped, the state moves on to player one deduct, and the amount of LED’s active is saved in a signal.
State 3: Player One deduct The signal with the amount of LED’s active determines the amount of health that gets deduct. This is done by having another shift register (deductor1.vhd) that rather than increments the LEDs, decrements them. This decrements on the rising edge of one of the clock div modules that we borrowed and modified (downcounterclock.vhd). Right as one LED is turned off, one point of health is deducted from player two’s total health. If during this process player two reaches 0 health, we stop and immediately move on to the “Game over” state. Otherwise, once the LED vector reaches “0000000000000000”, we move on to player two’s turn.
State 4: Player Two’s turn Player two’s turn is exactly like player one’s turn, except the shift register for it (Ptwo.bhd) goes from left to right, and the switch is on the right side of the board. A signal activates to have Player 1’s health display. Once switch 2 is active, this moves on to Player Two’s deduct turn.
Stage 5: Player Two Deduct Just like player two’s turn, player two deduct acts a lot like player one deduct. The main difference is that the shift register which controls the LED’s turning off goes in the opposite direction, which is an easy modification to make once you have player one’s deduct working properly.
Stage 6: Game Over If at any point either player reaches zero health, the game switches to this state. Nothing fancy displays. If BTN one is pressed, then the health is reset to 99, and the state goes back to menu, effectively starting the game over.
Modules
Black Box Diagram for Game
Downcounterclock (based on clk_div.vhd module by Bryan Mealy):
This is the clock that handles the timing of the deductors. The constant named max_count is 3x more than barclock’s max_count constant. This will make the deductors 3x slower than the speed of the bar.
Barclock - (based on clk_div.vhd module by Bryan Mealy):
This clock handles the timing of the power gauges, which we made increment quickly to add difficulty to the game. This timing can be adjusted to your liking, increasing the speed by making the constant max_count a larger number, or decreasing it by making max_count a smaller number. Sseg_dec - (Written by Bryan Mealy): This module takes an 8 bit number as input, which it decodes, converting the number to its decimal equivalent, and then outputs to the seven segment display. For this file to work, you need to make sure your constraints match ours.
Pone:
This is a shift register that shifts bits to the left, adding one hot bit to make it look like the power gauge is increasing. When all of the bits are hot, all bits reset to ‘0’, and the cycle starts over.
Ptwo:
This is a flipped version of the P1 module.
Deductor1:
This is a combination of a shift register and a subtractor. The shift register goes in the opposite direction of P1’s shift register, indicating a deduction. This also subtracts 1 from Player 2’s health for every clock cycle, so with the combination of these two functions, it will look like the health of the opponent is decreasing by 1 for every led of the health bar that goes down.
Deductor2: This is a flipped version of the Deductor1 module.
PlayDecoder (borrowed and slgihtly modified from ekchen35649 his 133 instructable): This is used in the menu state to display the word “PLAY” on the seven segment decoder.
Test
This game was originally inspired by one of the minigames from Kirby. It is a simple two-player game that can be played on an Basys 3 Board, or any FPGA.
Step 1: Required Materials
You will need: Digilent Basys 3, FPGA Board (or any other) A relatively up to date version of Vivado, or some other vhdl environment A computer that can run the mentioned program A brain
Step 2: The Game Itself
How to play
To start, you press the middle button. This will cause “99”, representing the health of player two, to display on the seven segment display. Then, the LEDs will light up sequentially from right to left. This forms a power bar. Once the power bar is full, it resets. The object of player one is to flip their switch when the bar is as high as possible. The more LEDs lit up, the more damage player one does to player two. After player one flips their switch, the damage dealt is deducted from player two’s health. Then, it switches to player two’s turn. Now, the number displayed represents player one’s health, and the power bar fills up from left to right. Once player two makes their move, the damage is deducted, and it is back to player one’s turn again. This repeats until one player reaches 0 health. Video of this functioning is attached.
To play the game, load it on a basys board, and press the middle button. Try to flip the switch with as many LED’s active as possible, and then wait and watch as the board deducts those points from your opponent’s health. Then, pass it over to your friend, and
Step 3: FSM
This game is essentially one big finite state machine, which some complex logic happening based on the state that the FSM is in.
(State Diagram)
State 1: Menu
The first state is the menu screen, which is one of the simpler states. It includes the seven segment display displaying the word “PLAY”, and the button that causes the game to start. The button, BTN, leads us to the next state, which is player one’s turn.
State 2: Player One’s turn
Player one’s turn activates a signal that causes the seven segment display to display Player two’s health. Another signal turns on to activate a shift register imported from another module that we created (Pone.vhd). This shift register makes the LED’s light up like an increasing power gauge would in other games, and it would then reset to 0 when it reaches the max amount of LED’s that could be lit. It updates on the rising edge of the clock obtained from barclock.vhd, which is modified from a borrowed lab file. We had player one’s bar start from the right, and fill up to the left, because player one’s switch is also on the left (for intuitive user experience). Once the switch is flipped, the state moves on to player one deduct, and the amount of LED’s active is saved in a signal.
State 3: Player One deduct
The signal with the amount of LED’s active determines the amount of health that gets deduct. This is done by having another shift register (deductor1.vhd) that rather than increments the LEDs, decrements them. This decrements on the rising edge of one of the clock div modules that we borrowed and modified (downcounterclock.vhd). Right as one LED is turned off, one point of health is deducted from player two’s total health. If during this process player two reaches 0 health, we stop and immediately move on to the “Game over” state. Otherwise, once the LED vector reaches “0000000000000000”, we move on to player two’s turn.
State 4: Player Two’s turn
Player two’s turn is exactly like player one’s turn, except the shift register for it (Ptwo.bhd) goes from left to right, and the switch is on the right side of the board. A signal activates to have Player 1’s health display. Once switch 2 is active, this moves on to Player Two’s deduct turn.
Stage 5: Player Two Deduct
Just like player two’s turn, player two deduct acts a lot like player one deduct. The main difference is that the shift register which controls the LED’s turning off goes in the opposite direction, which is an easy modification to make once you have player one’s deduct working properly.
Stage 6: Game Over If at any point either player reaches zero health, the game switches to this state. Nothing fancy displays. If BTN one is pressed, then the health is reset to 99, and the state goes back to menu, effectively starting the game over.
Black Box
Step 4: Modules
Downcounterclock (based on clk_div.vhd module by Bryan Mealy):
This is the clock that handles the timing of the deductors. The constant named max_count is 3x more than barclock’s max_count constant. This will make the deductors 3x slower than the speed of the bar.
Barclock - (based on clk_div.vhd module by Bryan Mealy): This clock handles the timing of the power gauges, which we made increment quickly to add difficulty to the game. This timing can be adjusted to your liking, increasing the speed by making the constant max_count a larger number, or decreasing it by making max_count a smaller number. Sseg_dec - (Written by Bryan Mealy): This module takes an 8 bit number as input, which it decodes, converting the number to its decimal equivalent, and then outputs to the seven segment display. For this file to work, you need to make sure your constraints match ours.
Pone: This is a shift register that shifts bits to the left, adding one hot bit to make it look like the power gauge is increasing. When all of the bits are hot, all bits reset to ‘0’, and the cycle starts over.
Ptwo: This is a flipped version of the P1 module.
Deductor1: This is a combination of a shift register and a subtractor. The shift register goes in the opposite direction of P1’s shift register, indicating a deduction. This also subtracts 1 from Player 2’s health for every clock cycle, so with the combination of these two functions, it will look like the health of the opponent is decreasing by 1 for every led of the health bar that goes down.
Deductor2: This is a flipped version of the Deductor1 module.
PlayDecoder (borrowed and slightly modified from ekchen35649 his 133 instructable):
This is used in the menu state to display the word “PLAY” on the seven segment decoder.
To Do: pictures, video