Red light green light radio game (#1438)

* added new game

* added suggestion

* updated summary

* added tips

* RSSI info
This commit is contained in:
Peli de Halleux 2018-10-16 10:27:42 -07:00 committed by GitHub
parent 920b30a304
commit 55f36d2f5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 223 additions and 5 deletions

View File

@ -47,6 +47,7 @@
* [Light Level Meter](/projects/light-level-meter)
* [Radio bridge](/projects/radio-bridge)
* [Snap the dot](/projects/snap-the-dot)
* [Red light green light](/projects/red-light-green-light)
## #examples

View File

@ -28,16 +28,16 @@ Here are some cool projects that you can build with your @boardname@!
"url": "/projects/fireflies",
"description": "Simulate fireflies with micro:bits, try it in the dark!",
"imageUrl": "/static/mb/projects/fireflies.png"
}, {
"name": "Infection",
"url": "/projects/infection",
"description": "An epidemic has broken out, see who will survive.",
"imageUrl": "/static/mb/projects/infection.png"
}, {
"name": "Hot or Cold",
"url": "/projects/hot-or-cold",
"description": "Find the hidden player by seeing if your close or not.",
"imageUrl": "/static/mb/projects/hot-or-cold.jpg"
}, {
"name": "Red Light Green Light",
"url": "/projects/red-light-green-light",
"description": "Play the classic game with your @boardname@.",
"imageUrl": "/static/mb/projects/red-light-green-light.png",
}, {
"name": "Voting Machine",
"url": "/projects/voting-machine",
@ -48,5 +48,10 @@ Here are some cool projects that you can build with your @boardname@!
"url": "/projects/rps-teams",
"description": "The Rock-Paper-Scissors game with lots and lots of players.",
"imageUrl": "/static/mb/projects/rpsteams.png"
}, {
"name": "Infection",
"url": "/projects/infection",
"description": "An epidemic has broken out, see who will survive.",
"imageUrl": "/static/mb/projects/infection.png"
}]
```

View File

@ -0,0 +1,212 @@
# Red Light Green Light
This is a classic game where the game master is looking the opposite direction and saying commands to player.
When the game master says "red light" and turns around, all players should stop. If the game master stops a moving player, he has to go back to the start.
When the game master turns around and says "green light", all players move and try to touch the game master.
In this remake, we will use @boardname@, the radio and the accelerometer to enforce those rules!
## The game master
Let's start with the code running on the game master @boardname@. Don't use this code for players!
### States
We define two states, ``GREENLIGHT`` and ``REDLIGHT`` and a ``state`` variable to store the current game state.
When the game master presses ``A``, the game goes into "green light" mode. When he presses ``B``,
the state goes in "red light" mode.
```blocks
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
GREENLIGHT = 1
REDLIGHT = 2
```
### Communication
The radio group is set to ``1``. We will set the same group in the player code. The game state is streamed in a forever loop so that players receive constantly.
```blocks
let state = 0;
radio.setGroup(1)
basic.forever(function () {
radio.sendNumber(state)
})
```
### Red light, green light
Use the ``||radio:on button pressed`` block to run code when button ``A`` and ``B`` are pressed.
When ``A`` is pressed, the game goes into ``GREENLIGHT`` mode. When ``B`` is pressed, the game
goes into ``B`` mode. We also use ``||basic:show icon||`` to display the current state.
```blocks
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
input.onButtonPressed(Button.A, function () {
state = GREENLIGHT
basic.showIcon(IconNames.Yes)
})
input.onButtonPressed(Button.B, function () {
state = REDLIGHT
basic.showIcon(IconNames.No)
})
GREENLIGHT = 1
REDLIGHT = 2
```
### Game master code
All together the game master code looks like this:
```blocks
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
input.onButtonPressed(Button.A, function () {
state = GREENLIGHT
basic.showIcon(IconNames.Yes)
})
input.onButtonPressed(Button.B, function () {
state = REDLIGHT
basic.showIcon(IconNames.No)
})
GREENLIGHT = 1
REDLIGHT = 2
radio.setGroup(1)
basic.forever(function () {
radio.sendNumber(state)
})
```
### ~ hint
Make sure to rename this program to ``game master`` or something so that you don't confuse it with the player program!
### ~
### Improve the game
* Use ``||music:ring tone||`` to play a sound while the game is in ``GREENLIGHT`` mode.
* Attach a servo and move the arm based on the game state
## The players
The code for players needs to listen for the game master state.
### States
First, we redefine the state constant, ``GREENLIGHT``, ``REDLIGHT`` and set the radio to ``1``.
We also add a ``state`` variable that will store the state of the game.
```blocks
let RED = 0
let state = 0
let GREEN = 0
GREEN = 1
RED = 2
radio.setGroup(1)
```
### Communication
We use the ``radio:on received number`` block to store the game master state into the ``state`` variable.
```blocks
let state = 0
radio.onReceivedNumber(function (receivedNumber) {
state = receivedNumber
})
```
### Display
In a forever loop, we display different icons based on the game state. Use a ``||logic:if||`` and
``||basic:show icon||`` blocks to display the game state.
```blocks
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
basic.forever(function () {
if (state == GREENLIGHT) {
basic.showIcon(IconNames.Yes)
} else if (state == REDLIGHT) {
basic.showIcon(IconNames.No)
}
})
```
### Movement check
If the ``state`` is equal to ``REDLIGHT``, we need to check that the player is not moving.
This is where the accelerometer comes into play. The accelerometer measures forces applied to the @boardname@.
If the player moves, it is likely that some small forces will be applied and the accelerometer will detect it.
At all times, gravity is applied to the @boardname@, so the acceleration strength at rest always near ``1000``mg.
If the acceleration strength is far from that value, say ``1100`` or ``900``, we can assume that the player is moving. To compute this we use this formula:
moving = | acc strength - 1000 | > 1000
Now that we know the math, we can turn this into code.
```block
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
let moving = false
if (state == REDLIGHT) {
moving = Math.abs(input.acceleration(Dimension.Strength) - 1000) > 100
if (moving) {
game.gameOver()
}
}
```
### Player code
All together:
```blocks
let moving = false
let REDLIGHT = 0
let state = 0
let GREENLIGHT = 0
radio.onReceivedNumber(function (receivedNumber) {
state = receivedNumber
})
GREENLIGHT = 1
REDLIGHT = 2
radio.setGroup(1)
basic.forever(function () {
if (state == GREENLIGHT) {
basic.showIcon(IconNames.Yes)
} else if (state == REDLIGHT) {
basic.showIcon(IconNames.No)
}
if (state == REDLIGHT) {
moving = Math.abs(input.acceleration(Dimension.Strength) - 1000) > 100
if (state == REDLIGHT && moving) {
game.gameOver()
}
}
})
```
### ~ hint
Make sure to rename this program to ``player`` or something so that you don't confuse it with the game master program!
### ~
### Tuning
Does the movement check work? Try changing the ``100`` value to tune the detection sensivity. Try ``64``.
### Improve the game
* Use ``||music:ring tone||`` to play a tone while in green mode.
* Use the packet signal strength to detect that you've reached the game master.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB