#include <U8glib.h>
#define SW 3
#define DT 4
#define CLK 2
#define DCLK 6
#define DIO 5
#define buzzer 10
TM1637Display OurDisplay = TM1637Display(DCLK, DIO);
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00};
U8GLIB_128X64 My_u8g_Pannel(U8G_I2C_OPT_NONE);
#define jumpSound 700
#define blaSound 125
#define speedSound 1000
#define DBOUNCE 180
#define gameStart 0
#define gameEnd 1
#define gamePlaying 2
volatile int gameStatus = gameStart;
static unsigned char dinoJump [] U8G_PROGMEM = {
0x00, 0xFC, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xEE, 0x0F, 0x00, 0xFE, 0x0F,
0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x07, 0X06, 0xFF, 0x03,
0xC3, 0xFF, 0x00, 0xE7, 0XFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0xFC, 0x1F, 0x00, 0xF8, 0x1F, 0x00,
0xF0, 0x1F, 0x00, 0xF0, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0xE0, 0x0E, 0x00,
0xE0, 0x1E, 0x00,
};
static unsigned char dinoLeft [] U8G_PROGMEM = {
0x00, 0xFC, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xEE, 0x0F, 0x00, 0xFE, 0x0F,
0x00, 0xFE, 0x0F, 0x00, 0x7E, 0x08, 0x00, 0x7E, 0x00, 0x06, 0xFF, 0x03,
0x87, 0x3F, 0x00, 0xE7, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0xFC, 0x1F, 0x00, 0xF8, 0x1F, 0x00,
0xF0, 0x1F, 0x00, 0xE0, 0x1E, 0x00, 0x60, 0x00, 0x00, 0xE0, 0x00, 0x00,
0xE0, 0x00, 0x00,
};
static unsigned char dinoRight [] U8G_PROGMEM = {
0x00, 0xFC, 0x07, 0x00, 0xEE, 0x07, 0x00, 0xE6, 0x0F, 0x00, 0xFE, 0x0F,
0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x7C, 0x00, 0x06, 0xFF, 0x03,
0xC3, 0xFF, 0x00, 0xE7, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0xFC, 0x1F, 0x00, 0xF8, 0x1F, 0x00,
0xF0, 0x1F, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x0E, 0x00,
0x00, 0x1E, 0x00,
};
static unsigned char cloud [] U8G_PROGMEM = {
0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x03, 0x00, 0x00, 0x00,
0x03, 0x06, 0x00, 0x00, 0x80, 0x01, 0x04, 0x00, 0x00, 0x40, 0x00, 0x1C,
0x00, 0x00, 0x40, 0x00, 0xE4, 0x03, 0x00, 0x18, 0x00, 0x00, 0x02, 0xE0,
0x0F, 0x00, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,
0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x40, 0x03, 0xFF, 0xFF, 0xFF, 0x7F,
};
static unsigned char oneCactus [] U8G_PROGMEM = {
0x30, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x01, 0xFB, 0x03,
0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0XFF, 0x01,
0xFE, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00,
0x78, 0x00, 0x00, 0x00,
};
static unsigned char twoCactus [] U8G_PROGMEM = {
0x30, 0xC0, 0x00, 0x38, 0xE0, 0x00, 0x38, 0xE8, 0x00, 0x38, 0xEC, 0x00,
0x38, 0xED, 0x04, 0xBB, 0xED, 0x0E, 0xBB, 0xED, 0x0E, 0xBB, 0xFD, 0x0E,
0xBB, 0xFD, 0x0E, 0xBB, 0xF9, 0x0E, 0xFF, 0xF1, 0x0F, 0xFF, 0xE0, 0x07,
0x7E, 0xE0, 0x01, 0x38, 0xE0, 0x00, 0x38, 0xE0, 0x00, 0x38, 0xE0, 0x00,
0x38, 0xE0, 0x00, 0x38, 0xE0, 0x00, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char threeCactus [] U8G_PROGRMEM = {
0x00, 0xC0, 0x00, 0x18, 0xC0, 0x01, 0X18, 0xC0, 0x01, 0x58, 0xD8, 0X01,
0x58, 0xFC, 0x01, 0x58, 0xFC, 0x0F, 0x78, 0xDC, 0x0F, 0x7F, 0xFC, 0x0F,
0x3B, 0xFD, 0x0D, 0x1B, 0xF9, 0x0C, 0x5B, 0xF5, 0x0F, 0x5B, 0xC5, 0x07,
0x5F, 0xE7, 0x03, 0xDE, 0xE7, 0x01, 0xD8, 0xC3, 0x01, 0x98, 0xC1, 0x01,
0x18, 0xC1, 0x01, 0x18, 0xC1, 0x01, 0x18, 0xE1, 0x01, 0x00, 0x00, 0x00,
};
static unsigned char oneCatusSmall [] U8G_PROGMEM = {
0x0C, 0x0C, 0x3C, 0x3D, 0x2D, 0x3D, 0x1D, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C,
};
static unsigned char twoCactusSmall [] U8G_PROGMEM = {
0x0C, 0x03, 0x0F, 0x03, 0x6C, 0x0B, 0x6D, 0x0B, 0x6D, 0x0B, 0x0B, 0x0B,
0xF1, 0x0F, 0x0E, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03,
};
static unsigned char threeCactusSmall [] U8G_PROGMEM = {
0x04, 0x41, 0x00, 0x0C, 0x61, 0x00, 0xFC, 0x79, 0x01, 0xFD, 0x7D, 0x01,
0x7D, 0x6D, 0x01, 0x7D, 0x7D, 0x01, 0xCF, 0xE5, 0x01, 0xCE, 0x67, 0x00,
0x8C, 0x67, 0x00, 0x0C, 0x63, 0x00, 0x0C, 0x61, 0x00, 0x0C, 0x61, 0x00,
};
static unsigned char dinoBlah [] U8G_PROGMEM = {
0x00, 0xFC, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xC6, 0x0F, 0x00, 0xC6, 0x0F,
0x00, 0xCE, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x06, 0xFF, 0x03,
0x87, 0x7F, 0x00, 0xE7, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00,
0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0xFC, 0x1F, 0x00, 0xF8, 0x1F, 0x00,
0xF0, 0x1F, 0x00, 0xF0, 0x0E, 0x00, 0x60, 0x0E, 0x00, 0x60, 0x0E, 0x00,
0xE0, 0x1E, 0x00,
};
static unsigned char gameOver [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0x01, 0x02, 0x0C, 0x0C, 0x3E, 0x00, 0x78, 0x60,
0x30, 0x7C, 0xF0, 0x01, 0x0C, 0x01, 0x07, 0x14, 0x0A, 0x02, 0x00, 0x84,
0x40, 0x10, 0x04, 0x10, 0x02, 0x04, 0x00, 0x05, 0x14, 0x0A, 0x02, 0x00,
0x02, 0x41, 0xC1, 0x18, 0x10, 0x02, 0x04, 0x00, 0x05, 0x14, 0x0A, 0x02,
0x00, 0x02, 0xC1, 0x18, 0x04, 0x10, 0x02, 0xC4, 0x81, 0x0D, 0x34, 0x0B,
0x3E, 0x00, 0x02, 0x81, 0x08, 0x7C, 0x0F, 0x01, 0x04, 0x81, 0x08, 0x24,
0x09, 0x02, 0x00, 0x02, 0x81, 0x0D, 0x04, 0x10, 0x01, 0x04, 0x81, 0x0F,
0x64, 0x09, 0x02, 0x00, 0x02, 0x01, 0x05, 0x04, 0x10, 0x02, 0x0C, 0xC1,
0x18, 0xC4, 0x08, 0x02, 0x00, 0x84, 0x00, 0x05, 0x40, 0x10, 0x02, 0xF8,
0x41, 0x10, 0xC4, 0x08, 0x3E, 0x00, 0x78, 0x00, 0x07, 0x7C, 0x10, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
};
int currentStateCLK;
int lastStateCLK;
int MyScore = 0;
int dinoMove = 0;
volatile int jumping = 0;
int cloudx = 128;
int obstacles [2] = {1, 4};
int obstaclex [2] = {128, 200};
int speed = 8;
unsigned long startTime = millis(), curTime;
int lastBeep = 0;
void ShowScore () {
if (gameStatus == gamePlaying) {
curTime = millis();
MyScore = (curTime - startTime) * speed / 1000;
OurDisplay.showNumberDecEx(MyScore);
if (MyScore / 100 > lastBeep) {
tone (buzzer, 1000, 100);
delay(150);
tone(buzzer, 1250, 100);
lastBeep = MyScore / 100;
}
}
}
void StartStopGame () {
static unsigned long last_interrupt = 0;
if (millis() - last_interrupt > DBOUNCE) {
if (gameStatus == gamePlaying) {
if (jumping ==0) {
jumping = 1;
tone (buzzer, jumpSound, 100);
}
}
else if (gameStatus == gameStart) gameStatus = gamePlaying;
else gameStatus = gameStart;
}
last_interrupt = millis();
}
void resetGame () {
MyScore = 0;
startTime = millis();
odstaclex[0] = 128;
obstaclex [1] = 200;
dinoMove = 0;
}
void setup() {
OurDisplay.setBrightness(7);
OurDisplay.clear();
resetGame();
ShowScore ();
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
pinMode(SW, INPUT_PULLUP);
pinMode(buzzer, OUTPUT);
attachInterrupt(digitalPinToInterrupt(SW), StartStopGame, FALLING);
}
void loop(void) {
ShowScore();
My_u8g_Panel.firstPage();
do {
draw();
} while ( My_u8g_Panel.nextPage() );
if (gameStatus == gamePlaying) {
moveDino();
moveCloud();
moveObstacles();
}
}
void moveDino () {
if (jumping == 0) dinoMove = (dinoMove + 1) % 3;
else {
if (jumping == 1) {
dinoMove = dinoMove + 8;
if (dinoMove > 32) jumping = 2;
} else {
dinoMove = dinoMove - 8;
if (dinoMove < 8) {
jumping = 0;
dinoMove = 0;
}
}
}
checkCollision ();
}
void moveCloud () {
cloudx --;
if (cloudx < -38) cloudx= 128;
}
void moveObstacles() {
int obx = obstaclex [0];
obx = obx - speed;
if (obx < -20) {
obstaclex[0] = obstaclex[1];
obstaclex[1] = obstaclex[0] +random(80, 125);
obstaclex[0] = obstaclex[1];
obstaclex[1] = random(1, 6);
}
else {
obstaclex[0] = obx;
obstaclex[1] -= speed;
}
}
void draw(void) {
u8g_prepare();
if (gameStatus == gamePlaying) {
drawDino ();
drawShape (0, clodx);
drawObsticles ();
}
else if (gameStatus == gameStart) {
My_u8g_Panel.drawStr( 0, 10, "Welcome to");
My_u8g_Panel.drawStr( 10, 30, "Dino!!");
My_u8g_Panel.drawStr( 0, 50, "Push to begin");
resetGame();
ShowScore();
}
else {
My_u8g_Panel.drawXBMP( 14, 12, 100, 15, gameOver);
drawDino ();
drawShape (0, cloudx);
drawObsticles ();
}
}
void drawDino (void) {
if (gameStaus == gameEnd) {
My_u8g_Panel.drawXBMP( 0, 43 - dinoMove, 20, 21, dinoBlah);
return;
}
switch (dinoMove) {
case -1: My_u8g_Panel.drawXBMP( 0, 43, 20, 21, dinoBlah); break;
case 0: My_u8g_Panel.drawXBMP( 0, 43, 20, 21, dinoJump); break;
case 1: My_ug8_Panel.drawXBMP( 0, 43, 20, 21, dinoLeft); break;
case 2: My_u8g_Panel.deawXBMP( 0, 43 - dinoMove, 20, 21, dinoJump); break;
}
}
void drawShape (int shape, int x) {
switch (shape) {
case 0: My_u8g_Panel.drawXBMP( x, 5, 39, 12, cloud); break;
case 1: My_u8g_Panel.drawXBMP( x, 44, 10, 20, oneCactus); break;
case 2: My_u8g_Panel.drawXBMP( x, 44, 20, 20, twoCactus); break;
case 3: My_u8g_panel.drawXBMP( x, 44, 20, 20, threeCactus); break;
case 4: My_u8g_Panel.drawXBMP( x, 52, 6, 12, oneCactusSmall); break;
case 5: My_u8g_Panel.drawXBMP( x, 52, 12, 12, twoCactusSmall); break;
case 6: My_u8g_Panel.drawXBMP( x, 52, 17, 12, threeCactusSmall); break;
}
}
void checkCollission () {
int obx = obstaclex [0];
int obw, obh;
switch (obstacles[0]) {
case 0: obw = 39; obh = 10; break;
case 1: obw = 10; obh = 20; break;
case 2: obw = 17; obh = 20; break;
case 3: obw = 17; obh = 20; break;
case 4: obw = 6; obh = 12; break;
case 5: obw = 12; obh = 12; break;
case 6: obw = 17; obh = 12; break;
}
if (obx > 15 || obx + obw < 5 || dinoMove > obh -3) {}
else {
gameStatus = gameEnd;
tone(buzzer, 125, 100);
delay(150);
tone (buzzer, 125, 100);
}
}
void drawObsticles () {
drawShape (obstacles[0], obstaclex[0]);
drawShape (obstacles[1], obstaclex[1]);
}
void u8g_prepare(void) {
My_u8g_Panel.setFont(u8g_font_6x10);
My_u8g_Panel.setFontRefHeightExtentedText();
My_u8g_Panel.setDefaultForegroundColor();
My_u8g_Panel.setFontPosTop();
}
#include <inttypes.h>
#define SEG_A 0b00000001
#define SEG_B 0b00000010
#define SEG_C 0b00000100
#define SEG_D 0b00001000
#define SEG_E 0b00010000
#define SEG_F 0b00100000
#define SEG_G 0b01000000
#define SEG_DP 0b10000000
#define DEFAULT_BIT_DELAY 100
class TM1637Display {
public:
TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay = DEFAULT_BIT_DELAY);
void setBrigntness(uint8_t brightness, bool on = true);
void setSegments(const uint8_t segment[], uint8_t length = 4, uint8_t pos = 0);
void clear();
void showNumberDec(int num, bool leading_zero = false, uint8_t lenght = 4, uint8_t pos = 0);
void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
uint8_t encodeDigit(uint8_t digit);
protected:
void bitDelay();
void start();
void stop();
bool writeByte(uint8_t b);
void showDots(uint8_t dots, uint8_t*digits);
void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
private:
uint8_t m_pinClk;
uint8_t m_pinDIO;
uint8_t m_brightness;
unsigned int m_bitDelay;
};
#endif
extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
}
#include <Arduino.h>
#define TM1673_I2C_COMM1 0x40
#define TM1637_I2C_COMM2 0xC0
#define TM1637_I2C_COMM3 0x80
const uint8_t digitToSegment[] = {
0b00111111,
0b00000110,
0b01011011,
0b01001111,
0b01100110,
0b01101101,
0b01111101,
0b00000111,
0b01111111,
0b01101111,
0b01110111,
0b01111100,
0b00111001,
0b01011110,
0b01111001,
0b01110001,
};
static const uint8_t minuSegments = 0b01000000;
TM1637Display::TM1637Display(uint8_t pinClk, uint8_t pinDIO, unsigned int bitDelay)
{
m_pinClk = pinClk;
m_pinDIO = pinDIO;
m_bitDelay = bitDelay;
pinMode(m_pinClk, INPUT);
pinMode(m_pinDIO, INPUT);
digitalWrite(m_pinClk, LOW);
digitalWrite(m_pinDIO, LOW);
}
void TM1637Display::setBrightness(uint8_t brighness, bool on)
{
m_brightness = (brightness & 0x7) | (on? 0x08 : 0x00);
}
void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos)
{
start();
writeByte(TM1637_I2C_COMM1);
stop();
start();
writeByte(TM1637_I2C_COMM2 + (pos & 0x03));
for (uint8_t k=0; k < lenght; k++)
writeByte(segment[k]);
stop();
start();
writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f));
stop();
}
void TMI637Display::clear()
{
uint8_t data[] = { 0, 0, 0, 0 };
setSegments(data);
}
void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, uint8_t pos)
{
showNumberDecEx(num, 0, leading_zero, length, pos);
}
void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos)
{
showNumberBaseEx(num < 0? -10, num < 0? -num : num, dots, leading_zero, length, pos);
}
void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos)
{
showNumberBaseEx(16, num, dots, leading_zero, length, pos);
}
void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero, uint8_t length, uint8_t pos)
{
bool negative = false;
if (base < 0) {
base = -base;
negative = true;
}
uint8_t digits[4];
if (num == 0 && !leading_zero) {
for(uint8_t i = 0; i < (leading-1); i++)
digits[i] = 0;
digits[lenght-1] = encodeDigit(0);
}
else {
for(int i = length-1; i >= 0; --i)
{
uint8_t digit = num % base;
if (digit == 0 && num == 0 && leading_zero == false)
digits[i] = 0;
else
digits[i] = encodeDigit(digit);
if (digit == 0 && num == 0 && negative) {
digits[i] = minusSegments;
negative = false;
}
num /= base;
}
if(dots != 0)
{
showDots(dots, digits);
}
}
setSegments(digits, length, pos);
}
void TM1637Display::bitDelay()
{
delayMicroseconds(m_bitDelay);
}
void TM1637Display::start()
{
pinMode(m_pinDIO, OUTPUT);
bitDelay();
}
void TM1637Display::stop()
{
pinMode(m_pinDIO, OUTPUT);
bitDelay();
pinMode(m_pinClk, INPUT);
bitDelay();
pinMode(m_pinDIO, INPUT);
bitDelay();
}
bool TM1637Display::writeByte(uint8_t b)
{
uint8_t data = b;
for(uint8_t i = 0; i < 8; i++) {
pinMode(m_pinClk, OUTPUT);
bitDelay();
if (data & 0x01)
pinMode(m_pinDIO, INPUT);
else
pinMode(m_pinDIO, OUTPUT);
bitDelay();
pinMode(m_pinClk, INPUT);
bitDelay();
data = data >> 1;
}
pinMode(m_pinClk, OUTPUT);
pinMode(m_pinDIO, INPUT);
bitDelay();
pinMode(m_pinClk, INPUT);
bitDelay();
uint8_t ack = digitalRead(m_pinDIO);
if (ack == 0)
pinMode(m_pinDIO, OUTPUT);
bitDelay();
pinMode(m_pinClk, OUTPUT);
bitDelay();
return ack;
}
void TM1637Display::showDots(uint8_t dots, uint8_t* digits)
{
for(int i = 0; i < 4; ++i)
{
digits[i] |= (dots & 0x80);
dots <<=1;
}
}
uint8_t TM1637Display::encodeDigit(uint8_t digit)
{
return digitToSegment[digit & 0x0f];
}