Die Idee zu diesem Geschicklichkeits- und Reaktionsspiel hatte ich spontan und wollte sie sogleich umsetzen.
Ziel des Spiels ist zu verhindern, dass fremde Raumschiffe die Erde erobern.
Die Raumschiffe sind 5 rote LEDs, die in zufälligen Abständen aufleuchten. Direkt vor jeder LED ist ein
Fotowiderstand (LDR), der mit einem Lichtstrahl von einem Laserpointer o.ä. beschossen werden kann. Sobald
man diesen LDR trifft, erlischt die entsprechende LED (d.h. das Raumschiff ist zerstört). Man bekommt pro
zerstörtes Raumschiff einen Punkt und einen weiteren Schuss (zu Beginn des Spiels hat man 5 Stück).
Das Spiel ist verloren, wenn man es nicht schafft, ein Raumschiff abzuschießen (zu langsam) oder die
Munition alle ist.
Details zum Aufbau und Programmierung des OLED-Moduls siehe auch "Game Of Life" mit einem OLED-Display
/**
* How to play:
* Goal of the game is to shoot as many alien spaceships as possible.
* At game start you have 5 shots. One of 5 red LEDs ("spaceship") lit randomly for a short
* time and you have to shoot this spaceship as fast as possible. If you do not hit the
* spaceship fast enough you loose and the game is over. After you hit the spaceship the
* LED will go off. If you run out of shots the game is over, but for every successfully
* hit spaceship you gain one more shot.
*/
#define PIN_PIEZO 6
#define AMOUNT_SPACESHIPS 5
#define AMOUNT_SHOTS_INIT 5
#define MAX_SPACESHIP_DELAY 2000 // in ms
#define MIN_SPACESHIP_DELAY 250 // in ms
#define SPACESHIP_DELAY_STEP 100 // in ms
#define TONE_SHOT 1
#define TONE_END_1 2
#define TONE_END_2 3
bool gameRunning;
byte pinLEDs[AMOUNT_SPACESHIPS] = {9, 10, 11, 12, 13};
byte pinLDRs[AMOUNT_SPACESHIPS] = {7, 2, 3, 4, 5};
int activeSpaceship;
byte shots;
unsigned int spaceshipDelay;
unsigned int score;
unsigned long shipAppearance;
void setup()
{
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(PIN_PIEZO, OUTPUT);
for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
pinMode(pinLEDs[i], OUTPUT);
pinMode(pinLDRs[i], INPUT);
digitalWrite(pinLEDs[i], LOW);
}
spaceshipDelay = MAX_SPACESHIP_DELAY;
gameRunning = true;
activeSpaceship = -1;
score = 0;
shots = AMOUNT_SHOTS_INIT;
initAnimation();
}
void loop()
{
if (gameRunning) {
updateSpaceships();
checkShoot();
}
}
void updateSpaceships()
{
if (activeSpaceship > -1) {
if ((millis() - shipAppearance) > spaceshipDelay) {
endGame();
}
return;
}
// delay between two spaceships
delay(random(500, 3000));
activeSpaceship = random(0, AMOUNT_SPACESHIPS);
digitalWrite(pinLEDs[activeSpaceship], HIGH);
shipAppearance = millis();
if (spaceshipDelay > (MIN_SPACESHIP_DELAY + SPACESHIP_DELAY_STEP)) {
spaceshipDelay -= SPACESHIP_DELAY_STEP;
}
}
void checkShoot()
{
if (activeSpaceship == -1) {
return;
}
for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
if (digitalRead(pinLDRs[i]) == HIGH) {
continue;
}
shots--;
if (activeSpaceship == i) {
// player hit spaceship
digitalWrite(pinLEDs[activeSpaceship], LOW);
activeSpaceship = -1;
score++;
shots++;
tone(PIN_PIEZO, 400, 50);
return;
}
if (shots <= 0) {
endGame();
return;
}
}
}
void initAnimation()
{
Serial.println("Incoming alien ships...");
for (byte i = 0; i < 9; i++) {
for (byte j = 0; j < AMOUNT_SPACESHIPS; j++) {
digitalWrite(pinLEDs[j], i%2);
}
delay(250);
}
}
void endGame()
{
gameRunning = false;
Serial.println("GAME OVER");
Serial.println("Final score: " + String(score));
for (byte i = 0; i < 6; i++) {
for (byte j = 0; j < AMOUNT_SPACESHIPS; j++) {
digitalWrite(pinLEDs[j], i%2);
}
tone(PIN_PIEZO, 660 - (i%2 * 50));
delay(300);
noTone(PIN_PIEZO);
}
for (byte i = 0; i < AMOUNT_SPACESHIPS; i++) {
digitalWrite(pinLEDs[i], LOW);
}
}
zurück