* added new game * added suggestion * updated summary * added tips * RSSI info
5.5 KiB
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.
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.
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.
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:
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 inGREENLIGHT
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.
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.
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.
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.
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:
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.