FollowMe uses the outputs of the Lego RCX computer to drive a spinning wheel and a light - and also uses the various sounds that the RCX can make. These are the things that the player has to imitate - using (appropriately) a second wheel attached to a rotation sensor, a light sensor and a touch sensor.
![]() | The whole machine. (Notice the cabling) |
![]() | The light sensor. |
![]() | The motion sensor & motor |
![]() | The light and The touch sensor |
When FollowMe spins the wheel, you have to spin the other wheel in the same direction. When FollowMe flashes the light, you have to block the light sensor with your hand. When FollowMe makes a sound, you have to press the touch sensor (which makes a similar sound). You must only do the thing it tells you to do - and you must do it quickly!
Every time you get it right, FollowMe picks another thing for you to do. If you get it wrong, the game is over and the score is displayed on the RCX's LCD panel. Each time you get it right, you have less time to get the next thing right - so the game goes faster and faster until you can no longer keep up.
When you eventually lose, you'll hear a low beeping sound with your final score shown on the LCD. You have to stop the RCX and press RUN to play another game.
Precise details of what each command is and how you have to respond is easy to change - if for example you don't have a rotation sensor or you'd like some more complicated mechanics.
Here is a listing of the NQC program that plays the game. You need at least revision 2.0 of the Lego RCX firmware (although you can have an older RCX) and a reasonably recent version of NQC that knows how to drive the rev 2 firmware:
/* Attach a motor to OUT_A and a Lego lamp to each of OUT_B and OUT_C. Attach a rotation sensor with a 40t gear wheel and an axle to SENSOR 1, a light sensor to SENSOR 2 and a bump sensor to SENSOR 3. The light from OUT_C should shine directly into the light sensor with just enough room between for you to put your finger. Place a black 1x2 one-hole beam in front of the light sensor to block it's own light from interfering. The OUT_B light must not be close to the light sensor. You may find that you have to flip the motor polarity in order for it to rotate in the same direction that the rotation sensor is measuring. The RCX then tells you what to do - and you have to follow it's commands: When the OUT_B lamp lights, you have to block the light sensor sufficiently to reduce the light coming from the OUT_C lamp by 20%. When the motor turns, you have to spin the rotation sensor by at least a quarter turn in the same direction. When the musical tone sounds, you have to press the touch sensor to make it play the opposite tone. The game gets gradually faster and faster and you have less and less time to respond. When you finally mess up, the RCX will display your score and you'll have to press RUN to play again. */ int score ; /* Has to be global to be displayed on LCD */ task main () { int pick ; int action ; int speed ; int rot ; int lig ; int snd ; int i ; int light_on ; /* Zero the score and set the initial speed to something easy to beat */ score = 0 ; speed = 300 ; /* Set up the sensors and outputs appropriately */ SetSensorType(SENSOR_1, SENSOR_TYPE_ROTATION ) ; SetSensorMode(SENSOR_1, SENSOR_MODE_ROTATION ) ; SetSensorType(SENSOR_2, SENSOR_TYPE_LIGHT ) ; SetSensorMode(SENSOR_2, SENSOR_MODE_PERCENT ) ; SetSensorType(SENSOR_3, SENSOR_TYPE_TOUCH ) ; SetSensorMode(SENSOR_3, SENSOR_MODE_BOOL ) ; SetPower ( OUT_A, 7 ) ; Off ( OUT_A ) ; /* Motor to tell you what to do */ SetPower ( OUT_B, 7 ) ; Off ( OUT_B ) ; /* Lamp to tell you what to do */ SetPower ( OUT_C, 7 ) ; On ( OUT_C ) ; /* Lamp to light the light sensor */ /* Tell the LCD to display the score */ SelectDisplay ( DISPLAY_USER ) ; SetUserDisplay ( score, 0 ) ; /* Calibrate the light sensor so we can tell when it's blocked */ Wait ( 20 ) ; light_on = (SENSOR_2 * 8) / 10 ; /* Trigger on 80% as much light */ /* Initialise the random seed so we don't get the same game every time */ SetRandomSeed ( light_on ) ; /* There must be a better way! */ while ( true ) { action = Random ( 3 ) + 1 ; pick = 0 ; ClearSensor ( SENSOR_1 ) ; /* Zero the rotation sensor */ /* Pick an action for the RCX to perform... */ switch ( action ) { case 1 : /* Motor clockwise */ OnFwd ( OUT_A ) ; break ; case 2 : /* Motor anticlockwise */ OnRev ( OUT_A ) ; break ; case 3 : /* Light */ OnFwd ( OUT_B ) ; break ; case 4 : /* Sound */ PlaySound ( SOUND_UP ) ; break ; } /* Wait for the user to either perform an action - or run out of time */ for ( i = 0 ; i < speed ; i++ ) { rot = SENSOR_1 ; lig = SENSOR_2 ; snd = SENSOR_3 ; if ( rot > 4 ) { pick = 1 ; break ; } if ( rot < -4 ) { pick = 2 ; break ; } if ( lig < light_on ) { pick = 3 ; break ; } if ( snd == 1 ) { pick = 4 ; Off ( OUT_A ) ; Off ( OUT_B ) ; PlaySound ( SOUND_DOWN ) ; Wait ( 100 ) ; break ; } Wait ( 1 ) ; } Off ( OUT_A ) ; Off ( OUT_B ) ; /* So, did he do it right? */ if ( pick == action ) { /* Well Done! Play happy sound! */ score++ ; PlaySound ( SOUND_DOUBLE_BEEP ) ; if ( speed > 30 ) Wait ( speed ) ; else Wait ( 30 ) ; } else { /* You lose! Play sad sound and wait to be stopped manually */ while ( true ) { Wait ( 100 ) ; PlaySound ( SOUND_LOW_BEEP ) ; } } /* Make the speed increase quite fast to start with - then slow down a bit to make the game last longer - eventually, it's impossible to go any faster and still have the motor react fast enough - so stop speeding up and just hope he makes a mistake *eventually* */ if ( speed > 50 ) speed -= 10 ; else if ( speed > 10 ) speed-- ; } }