mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Snake game that combines DMD and IRreceiver
This commit is contained in:
parent
178d8a0e4b
commit
311f8bbc1a
31
doc/ir-snake.dox
Normal file
31
doc/ir-snake.dox
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\file ir-snake.dox
|
||||
\page ir_snake Snake Video Game Using an Infrared Remote Control
|
||||
|
||||
This example demonstrates the use of the DMD and IRreceiver classes.
|
||||
The full source code follows:
|
||||
|
||||
\include IR/examples/Snake/Snake.pde
|
||||
*/
|
@ -49,6 +49,8 @@ LCD shield.
|
||||
\li \ref dmd_demo "Demo" that shows off various bitmap drawing features.
|
||||
\li \ref dmd_running_figure "RunningFigure" example that demonstrates how
|
||||
to draw and animate bitmaps.
|
||||
\li \ref ir_snake "Snake" game that combines the dot matrix display with
|
||||
IRreceiver to make a simple video game.
|
||||
|
||||
\section main_BlinkLED BlinkLED Utility Library
|
||||
|
||||
@ -90,6 +92,8 @@ realtime clock and the LCD library to implement an alarm clock.
|
||||
\li IRreceiver class that receives incoming RC-5 commands from an
|
||||
infrared remote control.
|
||||
\li \ref ir_dumpir "DumpIR" example that dumps all incoming RC-5 commands.
|
||||
\li \ref ir_snake "Snake" game that combines DMD with an infrared remote
|
||||
control to make a simple video game.
|
||||
|
||||
\section main_other Other
|
||||
|
||||
|
190
libraries/IR/examples/Snake/Snake.pde
Normal file
190
libraries/IR/examples/Snake/Snake.pde
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <IRreceiver.h>
|
||||
#include <DMD.h>
|
||||
#include <Mono5x7.h>
|
||||
|
||||
#define SNAKE_ADVANCE_TIME 150
|
||||
#define SNAKE_BLINK_TIME 500
|
||||
#define SNAKE_INC_STEPS 5
|
||||
#define SNAKE_MAX_LENGTH 50
|
||||
#define SNAKE_START_LENGTH 10
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
DMD display;
|
||||
IRreceiver ir;
|
||||
bool paused;
|
||||
bool gameOver;
|
||||
bool waitForStart;
|
||||
bool snakeDrawn;
|
||||
unsigned long lastChange;
|
||||
Point direction;
|
||||
Point snakeParts[SNAKE_MAX_LENGTH];
|
||||
int snakeLength;
|
||||
int incStep;
|
||||
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
display.refresh();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
display.enableTimer1();
|
||||
display.setFont(Mono5x7);
|
||||
startGame();
|
||||
}
|
||||
|
||||
void drawSnake(Bitmap::Color color) {
|
||||
for (int index = 0; index < snakeLength; ++index)
|
||||
display.setPixel(snakeParts[index].x, snakeParts[index].y, color);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Handle the "Game Over" state. Any key press starts a new game.
|
||||
int cmd = ir.command();
|
||||
if (gameOver) {
|
||||
if (cmd != -1 && (cmd & IRreceiver::AUTO_REPEAT) == 0)
|
||||
startGame();
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause the game if waiting for the first start. While waiting,
|
||||
// blink the location of the snake to help the player get their bearings.
|
||||
if (waitForStart) {
|
||||
if (cmd == -1) {
|
||||
if ((millis() - lastChange) >= SNAKE_BLINK_TIME) {
|
||||
snakeDrawn = !snakeDrawn;
|
||||
drawSnake(snakeDrawn ? Bitmap::White : Bitmap::Black);
|
||||
lastChange += SNAKE_BLINK_TIME;
|
||||
}
|
||||
return;
|
||||
}
|
||||
drawSnake(Bitmap::White);
|
||||
waitForStart = false;
|
||||
snakeDrawn = true;
|
||||
lastChange = millis();
|
||||
}
|
||||
|
||||
// Process commands from the player.
|
||||
switch (cmd) {
|
||||
|
||||
// Both arrow keys and numbers can be used to control the direction,
|
||||
// in case the remote control does not have arrow keys.
|
||||
case RC5_LEFT: case RC5_4:
|
||||
changeDirection(-1, 0);
|
||||
break;
|
||||
case RC5_RIGHT: case RC5_6:
|
||||
changeDirection(1, 0);
|
||||
break;
|
||||
case RC5_UP: case RC5_2:
|
||||
changeDirection(0, -1);
|
||||
break;
|
||||
case RC5_DOWN: case RC5_8:
|
||||
changeDirection(0, 1);
|
||||
break;
|
||||
|
||||
case RC5_PAUSE: case RC5_PLAY: case RC5_0:
|
||||
// Pause or resume the game.
|
||||
paused = !paused;
|
||||
lastChange = millis();
|
||||
break;
|
||||
|
||||
case RC5_STOP: case RC5_STANDBY:
|
||||
// Stop the game and start a new one.
|
||||
startGame();
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance the snake position if not paused and the timeout has expired.
|
||||
if (!paused && (millis() - lastChange) >= SNAKE_ADVANCE_TIME) {
|
||||
++incStep;
|
||||
advanceSnake(incStep >= SNAKE_INC_STEPS);
|
||||
lastChange += SNAKE_ADVANCE_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
void startGame() {
|
||||
randomSeed(micros() + analogRead(A0)); // Analog read adds some noise.
|
||||
display.clear();
|
||||
display.drawRect(0, 0, display.width() - 1, display.height() - 1);
|
||||
for (int count = 0; count < 10; ++count) {
|
||||
int x, y;
|
||||
if (random(0, 2) == 0) {
|
||||
x = random(1, display.width() - 5);
|
||||
y = random(1, display.height() - 1);
|
||||
display.drawLine(x, y, x + 4, y);
|
||||
} else {
|
||||
x = random(1, display.width() - 1);
|
||||
y = random(1, display.height() - 3);
|
||||
display.drawLine(x, y, x, y + 2);
|
||||
}
|
||||
}
|
||||
paused = false;
|
||||
gameOver = false;
|
||||
waitForStart = true;
|
||||
snakeDrawn = true;
|
||||
lastChange = millis();
|
||||
direction.x = 1;
|
||||
direction.y = 0;
|
||||
incStep = 0;
|
||||
snakeLength = SNAKE_START_LENGTH;
|
||||
for (int index = 0; index < snakeLength; ++index) {
|
||||
snakeParts[index].x = 3 + index;
|
||||
snakeParts[index].y = 4;
|
||||
display.setPixel
|
||||
(snakeParts[index].x, snakeParts[index].y, Bitmap::White);
|
||||
}
|
||||
}
|
||||
|
||||
void changeDirection(int x, int y) {
|
||||
direction.x = x;
|
||||
direction.y = y;
|
||||
}
|
||||
|
||||
void advanceSnake(bool increase) {
|
||||
int x = snakeParts[snakeLength - 1].x + direction.x;
|
||||
int y = snakeParts[snakeLength - 1].y + direction.y;
|
||||
if (display.pixel(x, y) == Bitmap::White) {
|
||||
gameOver = true;
|
||||
display.clear();
|
||||
display.drawText(5, 0, "Game");
|
||||
display.drawText(3, 8, "Over!");
|
||||
return;
|
||||
}
|
||||
if (!increase || snakeLength >= SNAKE_MAX_LENGTH) {
|
||||
display.setPixel(snakeParts[0].x, snakeParts[0].y, Bitmap::Black);
|
||||
for (int index = 0; index < snakeLength - 1; ++index)
|
||||
snakeParts[index] = snakeParts[index + 1];
|
||||
} else {
|
||||
++snakeLength;
|
||||
}
|
||||
snakeParts[snakeLength - 1].x = x;
|
||||
snakeParts[snakeLength - 1].y = y;
|
||||
display.setPixel(x, y, Bitmap::White);
|
||||
if (increase)
|
||||
incStep = 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user