diff --git a/DinoGame/DinoGame.xml b/DinoGame/DinoGame.xml
new file mode 100644
index 0000000..4829f5d
--- /dev/null
+++ b/DinoGame/DinoGame.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DinoGame/README.md b/DinoGame/README.md
new file mode 100644
index 0000000..624c200
--- /dev/null
+++ b/DinoGame/README.md
@@ -0,0 +1,3 @@
+# Mixly_DinoGame
+
+
diff --git a/DinoGame/block/dino_game.js b/DinoGame/block/dino_game.js
new file mode 100644
index 0000000..0f100cf
--- /dev/null
+++ b/DinoGame/block/dino_game.js
@@ -0,0 +1,79 @@
+;(() => {
+ //
+ Blockly.Blocks.dino_game_setup = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField('DinoGame初始化, 选择u8g2实例:')
+ .appendField(new Blockly.FieldTextInput('u8g2'), 'oled')
+
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+
+ Blockly.Blocks.dino_game_loop = {
+ init: function () {
+ this.appendDummyInput().appendField('DinoGame循环执行命令')
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+
+ Blockly.Blocks.dino_game_start_game = {
+ init: function () {
+ this.appendDummyInput().appendField('DinoGame开始游戏')
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+
+ Blockly.Blocks.dino_game_dino_jump = {
+ init: function () {
+ this.appendDummyInput().appendField('DinoGame恐龙跳跃')
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+
+ Blockly.Blocks.dino_game_set_cheat = {
+ init: function () {
+ this.appendDummyInput()
+ .appendField('是否开启作弊')
+ .appendField(
+ new Blockly.FieldDropdown([
+ ['开启', 'CHEAT_MODE_CHEAT'],
+ ['关闭', 'CHEAT_MODE_NORMAL'],
+ ]),
+ 'isCheat'
+ )
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+
+ Blockly.Blocks.dino_game_show_ultraman = {
+ init: function () {
+ this.appendDummyInput().appendField('DinoGame显示奥特曼')
+ this.setPreviousStatement(true, null)
+ this.setNextStatement(true, null)
+ this.setColour(345)
+ this.setTooltip('Dino')
+ this.setHelpUrl('Dino')
+ },
+ }
+})()
diff --git a/DinoGame/config.json b/DinoGame/config.json
new file mode 100644
index 0000000..dfba51c
--- /dev/null
+++ b/DinoGame/config.json
@@ -0,0 +1,3 @@
+{
+ "version": "0.1.0"
+}
\ No newline at end of file
diff --git a/DinoGame/generator/dino_game.js b/DinoGame/generator/dino_game.js
new file mode 100644
index 0000000..2e47e6f
--- /dev/null
+++ b/DinoGame/generator/dino_game.js
@@ -0,0 +1,37 @@
+;(() => {
+ //
+ Blockly.Arduino.forBlock.dino_game_setup = function () {
+ var oled = this.getFieldValue('oled')
+ Blockly.Arduino.definitions_[
+ 'header'
+ ] = `#include "dino_game_arduino.h"\nDinoGameArduino dinoGameArduino(&${oled});`
+ Blockly.Arduino.setups_['setup'] = 'dinoGameArduino.setup();'
+ var code = ''
+ return code
+ }
+
+ Blockly.Arduino.forBlock.dino_game_loop = function () {
+ var code = 'dinoGameArduino.loop();'
+ return code
+ }
+
+ Blockly.Arduino.forBlock.dino_game_start_game = function () {
+ var code = 'dinoGameArduino.startGame();'
+ return code
+ }
+
+ Blockly.Arduino.forBlock.dino_game_dino_jump = function () {
+ var code = 'dinoGameArduino.dinoJump();'
+ return code
+ }
+ Blockly.Arduino.forBlock.dino_game_set_cheat = function () {
+ var dropdown_isCheat = this.getFieldValue('isCheat')
+ var code = `dinoGameArduino.setCheatMode(${dropdown_isCheat});`
+ return code
+ }
+
+ Blockly.Arduino.forBlock.dino_game_show_ultraman = function () {
+ var code = 'dinoGameArduino.showUltraman();'
+ return code
+ }
+})()
diff --git a/DinoGame/libraries/dino_game/dino_game.cpp b/DinoGame/libraries/dino_game/dino_game.cpp
new file mode 100644
index 0000000..0245788
--- /dev/null
+++ b/DinoGame/libraries/dino_game/dino_game.cpp
@@ -0,0 +1,272 @@
+#include
+#include "dino_game.h"
+
+#define dino_min(a, b) ((a) < (b) ? (a) : (b))
+
+// public
+DinoGame::DinoGame(
+ int stageWidth,
+ int stageHeight, unsigned long (*systemCurrentTimeFunc)(),
+ long (*randomFunc)(long, long))
+{
+ _stageWidth = stageWidth;
+ _stageHeight = stageHeight;
+
+ _cheatMode = CHEAT_MODE_NORMAL;
+
+ if (systemCurrentTimeFunc == nullptr)
+ {
+ printf("error: systemCurrentTimeFunc is null \n");
+ }
+ if (randomFunc == nullptr)
+ {
+ printf("error: randomFunc is null \n");
+ }
+
+ _systemCurrentTimeFunc = systemCurrentTimeFunc;
+ _randomFunc = randomFunc;
+}
+
+DinoGame::~DinoGame()
+{
+}
+
+void DinoGame::setup()
+{
+ resetGame();
+ splashStage();
+}
+
+void DinoGame::loop()
+{
+ if (_gameStatus == GAME_PLAYING_STATUS)
+ {
+ moveObstacles();
+ moveDino();
+ checkCollision();
+ calLevel();
+ }
+}
+
+void DinoGame::startGame()
+{
+ if (_gameStatus != GAME_PLAYING_STATUS)
+ {
+ _gameStatus = GAME_PLAYING_STATUS;
+ resetGame();
+ }
+}
+
+void DinoGame::setCheatMode(CheatMode mode)
+{
+ _cheatMode = mode;
+}
+
+Dino *DinoGame::getDino()
+{
+ return &_dino;
+}
+
+Obstacle *DinoGame::getObstacleReal()
+{
+ return &_obstacleReal;
+}
+
+Obstacle *DinoGame::getObstacleBackup()
+{
+ return &_obstacleBackup;
+}
+
+DinoGameStatus DinoGame::getGameStatus()
+{
+ return _gameStatus;
+}
+
+unsigned int DinoGame::getScore()
+{
+ return _score;
+}
+
+unsigned int DinoGame::getLevel()
+{
+ return _level;
+}
+
+void DinoGame::dinoJump()
+{
+ if (_dino.action == DINO_WALKING || _cheatMode == CHEAT_MODE_CHEAT)
+ {
+ _dino.action = DINO_JUMPING;
+ }
+}
+
+// protected
+
+void DinoGame::resetGame()
+{
+ _score = 0;
+ _speed = 2;
+ _level = 1;
+
+ _startTime = _systemCurrentTimeFunc();
+
+ _dino.action = DINO_WALKING;
+ _dino.pose = DINO_JUMP;
+ _dino.frame.size.width = 20;
+ _dino.frame.size.height = 21;
+ _dino.frame.postion.x = 0;
+ _dino.frame.postion.y = _stageHeight - _dino.frame.size.height;
+ _dino.frame.offset.x = 0;
+ _dino.frame.offset.y = 0;
+
+ _obstacleReal = getRandomObstacle();
+ _obstacleReal.frame.postion.x = _stageWidth;
+ _obstacleBackup = getRandomObstacle(8);
+ _obstacleBackup.frame.postion.x = _stageWidth * 2;
+}
+
+void DinoGame::splashStage()
+{
+ _obstacleReal = getRandomObstacle(0);
+ _obstacleReal.frame.postion.x = _stageWidth * 0.4;
+
+ _obstacleBackup = getRandomObstacle();
+ _obstacleBackup.frame.postion.x = _stageWidth * 0.7;
+}
+
+void DinoGame::calLevel()
+{
+ _currentTime = _systemCurrentTimeFunc();
+
+ if (_score >= 5 * (_speed - 1))
+ {
+ _speed++;
+ _level++;
+ }
+}
+
+void DinoGame::checkCollision()
+{
+ if (((_obstacleReal.category != OBSTACLE_BIRD && _dino.frame.offset.y < _obstacleReal.hitZone.size.height - 3) ||
+ (_obstacleReal.category == OBSTACLE_BIRD && _dino.frame.offset.y > 5 && _dino.frame.offset.y < _obstacleReal.hitZone.postion.y)) &&
+ (_obstacleReal.hitZone.postion.x < 13 && _obstacleReal.hitZone.postion.x + _obstacleReal.hitZone.size.width > 5))
+ {
+ _gameStatus = GAME_OVER_STATUS;
+ }
+}
+
+void DinoGame::moveDino()
+{
+ if (_dino.action == DINO_WALKING)
+ {
+ _dino.frame.offset.y = (_dino.frame.offset.y + 1) % 3;
+ _dino.pose = (DinoPose)(_dino.frame.offset.y + 1);
+ }
+ else
+ {
+ _dino.pose = DINO_JUMP;
+ if (_dino.action == DINO_JUMPING)
+ {
+ _dino.frame.offset.y = _dino.frame.offset.y + _speed;
+ if (_dino.frame.offset.y > 32)
+ {
+ _dino.action = DINO_FALLING;
+ }
+ }
+ else
+ {
+ _dino.frame.offset.y = _dino.frame.offset.y - _speed;
+ if (_dino.frame.offset.y < 8)
+ {
+ _dino.action = DINO_WALKING;
+ _dino.frame.offset.y = 0;
+ }
+ }
+ }
+}
+
+void DinoGame::moveObstacles()
+{
+ int newX = _obstacleReal.frame.postion.x - _speed;
+
+ if (newX < -_obstacleReal.frame.size.width)
+ {
+ _score = _score + 1;
+ _obstacleReal = _obstacleBackup;
+ _obstacleBackup = getRandomObstacle(8);
+ _obstacleBackup.frame.postion.x = _obstacleReal.frame.postion.x + _randomFunc(_stageWidth * 0.8, _stageWidth);
+ }
+ else
+ {
+ _obstacleReal.frame.postion.x = newX;
+ _obstacleBackup.frame.postion.x -= _speed;
+ }
+
+ _obstacleReal.hitZone.postion = _obstacleReal.frame.postion;
+ _obstacleBackup.hitZone.postion = _obstacleBackup.frame.postion;
+}
+
+Obstacle DinoGame::getRandomObstacle(int max)
+{
+ int rand = _randomFunc(0, max);
+ Obstacle obstacle;
+ switch (rand)
+ {
+ case 1:
+ obstacle.category = OBSTACLE_ONE_CACTUS;
+ obstacle.frame.size.width = 10;
+ obstacle.frame.size.height = 20;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 2:
+ obstacle.category = OBSTACLE_TWO_CACTUS;
+ obstacle.frame.size.width = 20;
+ obstacle.frame.size.height = 20;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 3:
+ obstacle.category = OBSTACLE_THREE_CACTUS;
+ obstacle.frame.size.width = 20;
+ obstacle.frame.size.height = 20;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 4:
+ obstacle.category = OBSTACLE_ONE_SMALL_CACTUS;
+ obstacle.frame.size.width = 6;
+ obstacle.frame.size.height = 12;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 5:
+ obstacle.category = OBSTACLE_TWO_SMALL_CACTUS;
+ obstacle.frame.size.width = 12;
+ obstacle.frame.size.height = 12;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 6:
+ obstacle.category = OBSTACLE_THREE_SMALL_CACTUS;
+ obstacle.frame.size.width = 17;
+ obstacle.frame.size.height = 12;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height;
+ break;
+ case 0:
+ default:
+ obstacle.category = OBSTACLE_BIRD;
+ obstacle.frame.size.width = 21;
+ obstacle.frame.size.height = 18;
+ obstacle.frame.postion.x = 200;
+ obstacle.frame.postion.y = _stageHeight - obstacle.frame.size.height - _dino.frame.size.height - 3;
+ break;
+ }
+
+ obstacle.hitZone = obstacle.frame;
+ obstacle.hitZone.size.width = dino_min(obstacle.hitZone.size.width, 17);
+ return obstacle;
+}
+
+// private
\ No newline at end of file
diff --git a/DinoGame/libraries/dino_game/dino_game.h b/DinoGame/libraries/dino_game/dino_game.h
new file mode 100644
index 0000000..e7d1870
--- /dev/null
+++ b/DinoGame/libraries/dino_game/dino_game.h
@@ -0,0 +1,140 @@
+#ifndef __DINO_GAME_H_
+#define __DINO_GAME_H_
+
+typedef struct
+{
+ int x;
+ int y;
+} Position;
+
+typedef struct
+{
+ int x;
+ int y;
+} Offset;
+
+typedef struct
+{
+ int width;
+ int height;
+} Size;
+
+typedef struct
+{
+ Position postion;
+ Offset offset;
+ Size size;
+} Frame;
+
+typedef struct
+{
+ Frame frame;
+} Object;
+
+typedef enum
+{
+ OBSTACLE_BIRD = 0,
+ OBSTACLE_ONE_CACTUS = 1,
+ OBSTACLE_TWO_CACTUS = 2,
+ OBSTACLE_THREE_CACTUS = 3,
+ OBSTACLE_ONE_SMALL_CACTUS = 4,
+ OBSTACLE_TWO_SMALL_CACTUS = 5,
+ OBSTACLE_THREE_SMALL_CACTUS = 6,
+} ObstacleCategory;
+
+struct Obstacle : public Object
+{
+ Frame hitZone;
+ ObstacleCategory category;
+};
+
+typedef enum
+{
+ GAME_WAITING_STATUS = 0,
+ GAME_PLAYING_STATUS = 1,
+ GAME_OVER_STATUS = 2,
+} DinoGameStatus;
+
+typedef enum
+{
+ DINO_WALKING = 0,
+ DINO_JUMPING = 1,
+ DINO_FALLING = 2,
+} DinoAction;
+
+typedef enum
+{
+ DINO_BLAH = 0,
+ DINO_JUMP = 1,
+ DINO_LEFT = 2,
+ DINO_RIGHT = 3,
+} DinoPose;
+
+struct Dino : public Object
+{
+ DinoAction action;
+ DinoPose pose;
+};
+
+typedef enum
+{
+ CHEAT_MODE_NORMAL = 0,
+ CHEAT_MODE_CHEAT = 1,
+} CheatMode;
+
+class DinoGame
+{
+public:
+ DinoGame(
+ int stageWidth,
+ int stageHeight,
+ unsigned long (*systemCurrentTimeFunc)(),
+ long (*randomFunc)(long, long));
+ virtual ~DinoGame();
+
+ void setup();
+ void loop();
+
+ void setCheatMode(CheatMode mode);
+
+ DinoGameStatus getGameStatus();
+ Dino *getDino();
+ Obstacle *getObstacleReal();
+ Obstacle *getObstacleBackup();
+
+ unsigned int getScore();
+ unsigned int getLevel();
+ void startGame();
+ void dinoJump();
+
+protected:
+ int _stageWidth;
+ int _stageHeight;
+
+ DinoGameStatus _gameStatus;
+ unsigned long _startTime;
+ unsigned long _currentTime;
+
+ unsigned int _speed;
+ unsigned int _level;
+ unsigned int _score;
+
+ CheatMode _cheatMode;
+
+ Dino _dino;
+ Obstacle _obstacleReal;
+ Obstacle _obstacleBackup;
+
+ Obstacle getRandomObstacle(int max=6);
+ void calLevel();
+ void resetGame();
+ void splashStage();
+ void checkCollision();
+ void moveDino();
+ void moveObstacles();
+
+ unsigned long (*_systemCurrentTimeFunc)();
+ long (*_randomFunc)(long, long);
+};
+
+#endif // !__DINO_GAME_H_
\ No newline at end of file
diff --git a/DinoGame/libraries/dino_game/dino_game_arduino.cpp b/DinoGame/libraries/dino_game/dino_game_arduino.cpp
new file mode 100644
index 0000000..e2a7f72
--- /dev/null
+++ b/DinoGame/libraries/dino_game/dino_game_arduino.cpp
@@ -0,0 +1,293 @@
+#include "dino_game_arduino.h"
+
+unsigned int getObstacleImageAddress(Obstacle *obstacle)
+{
+ unsigned int obstacleImageAddress;
+
+ switch (obstacle->category)
+ {
+ case OBSTACLE_ONE_CACTUS:
+ obstacleImageAddress = reinterpret_cast(oneCactusImg);
+ break;
+ case OBSTACLE_TWO_CACTUS:
+ obstacleImageAddress = reinterpret_cast(twoCactusImg);
+ break;
+ case OBSTACLE_THREE_CACTUS:
+ obstacleImageAddress = reinterpret_cast(threeCactusImg);
+ break;
+ case OBSTACLE_ONE_SMALL_CACTUS:
+ obstacleImageAddress = reinterpret_cast(oneSmallCactusImg);
+ break;
+ case OBSTACLE_TWO_SMALL_CACTUS:
+ obstacleImageAddress = reinterpret_cast(twoSmallCactusImg);
+ break;
+ case OBSTACLE_THREE_SMALL_CACTUS:
+ obstacleImageAddress = reinterpret_cast(threeSmallCactusImg);
+ break;
+ case OBSTACLE_BIRD:
+ default:
+ obstacleImageAddress = reinterpret_cast(obstacle->frame.postion.x % 20 > 10 ? birdUpImg : birdDownImg);
+ break;
+ }
+
+ return obstacleImageAddress;
+}
+
+// public
+DinoGameArduino::DinoGameArduino(U8G2 *u8g2)
+ : _u8g2(u8g2),
+ _dinoGame(_u8g2->getWidth(), _u8g2->getHeight(), millis, random)
+{
+}
+
+DinoGameArduino::~DinoGameArduino()
+{
+}
+
+void DinoGameArduino::setup()
+{
+ _u8g2->begin();
+ _u8g2->setFont(u8g2_font_timR08_tf);
+ _u8g2->setFontMode(1);
+ _u8g2->setBitmapMode(1);
+ _u8g2->setFontPosTop();
+ _u8g2->enableUTF8Print();
+
+ _dinoGame.setup();
+ delay(300);
+}
+
+void DinoGameArduino::loop()
+{
+ _u8g2->firstPage();
+ do
+ {
+ drawDino();
+ drawObstacleReal();
+ drawObstacleBackup();
+ drawCloud();
+
+ if (_cheatMode == CHEAT_MODE_CHEAT)
+ {
+ _u8g2->setFont(u8g2_font_timR08_tf);
+ _u8g2->setCursor(_cloud.frame.postion.x, 12);
+ _u8g2->print("c");
+ }
+
+ if (_showUltraman == 1)
+ {
+ _u8g2->drawXBMP(
+ _dinoGame.getDino()->frame.postion.x,
+ _dinoGame.getDino()->frame.postion.y - _dinoGame.getDino()->frame.offset.y - 58 + _dinoGame.getDino()->frame.size.height,
+ 20,
+ 58,
+ ultramanImg);
+ }
+
+ if (_dinoGame.getGameStatus() == GAME_WAITING_STATUS)
+ {
+ _u8g2->setFont(u8g2_font_timR12_tf);
+ char title[] = "= Dino Game =";
+ _u8g2->setCursor((_u8g2->getWidth() - (sizeof(title) - 1) * 8) / 2, 0);
+ _u8g2->print(title);
+ }
+ else if (_dinoGame.getGameStatus() == GAME_OVER_STATUS)
+ {
+ _u8g2->drawXBMP(
+ (_u8g2->getWidth() - 100) / 2,
+ (_u8g2->getHeight() - 15) / 2,
+ 100,
+ 15,
+ gameOverImg);
+ }
+ else if (_dinoGame.getGameStatus() == GAME_PLAYING_STATUS)
+ {
+ _u8g2->setFont(u8g2_font_timR08_tf);
+
+ _u8g2->setCursor(0, 0);
+ char lvText[6];
+ unsigned int currentLevel = _dinoGame.getLevel();
+ sprintf(lvText, "LV: %d", currentLevel);
+ _u8g2->print(lvText);
+ }
+
+ if (_dinoGame.getGameStatus() == GAME_PLAYING_STATUS || _dinoGame.getGameStatus() == GAME_OVER_STATUS)
+ {
+ char scoreText[10];
+ unsigned int score = _dinoGame.getScore();
+ sprintf(scoreText, "SCORE: %d", score);
+
+ unsigned int i;
+ for (i = 0; i < sizeof(scoreText); i++)
+ {
+ if (scoreText[i] == '\0')
+ {
+ break;
+ }
+ }
+ _u8g2->setCursor((_u8g2->getWidth() - (i - 1) * 6), 0);
+ _u8g2->print(scoreText);
+ }
+
+ } while (_u8g2->nextPage());
+
+ _dinoGame.loop();
+ moveCloud();
+}
+
+void DinoGameArduino::startGame()
+{
+ if (_dinoGame.getGameStatus() != GAME_PLAYING_STATUS)
+ {
+ _dinoGame.startGame();
+ }
+}
+
+void DinoGameArduino::setCheatMode(CheatMode cheatMode)
+{
+ _cheatMode = cheatMode;
+ _dinoGame.setCheatMode(cheatMode);
+}
+
+void DinoGameArduino::dinoJump()
+{
+ _dinoGame.dinoJump();
+}
+
+void DinoGameArduino::showUltraman()
+{
+ _showUltraman = 1;
+}
+
+unsigned int DinoGameArduino::getScore()
+{
+ return _dinoGame.getScore();
+}
+
+unsigned int DinoGameArduino::getLevel()
+{
+ return _dinoGame.getLevel();
+}
+
+DinoGameStatus DinoGameArduino::getGameStatus()
+{
+ return _dinoGame.getGameStatus();
+}
+
+// protected
+
+void DinoGameArduino::drawDino()
+{
+ Dino *dino = _dinoGame.getDino();
+ resetDinoImagePtr(&_dinoImagePtr, dino);
+
+ _u8g2->drawXBMP(
+ dino->frame.postion.x,
+ dino->frame.postion.y - dino->frame.offset.y,
+ dino->frame.size.width,
+ dino->frame.size.height,
+ _dinoImagePtr);
+}
+
+void DinoGameArduino::drawObstacleReal()
+{
+ Obstacle *obstacle = _dinoGame.getObstacleReal();
+ resetObstacleImagePtr(&_obstacleRealImagePtr, obstacle);
+ _u8g2->drawXBMP(
+ obstacle->frame.postion.x,
+ obstacle->frame.postion.y,
+ obstacle->frame.size.width,
+ obstacle->frame.size.height,
+ _obstacleRealImagePtr);
+}
+
+void DinoGameArduino::drawObstacleBackup()
+{
+ Obstacle *obstacle = _dinoGame.getObstacleBackup();
+ resetObstacleImagePtr(&_obstacleBackupImagePtr, obstacle);
+
+ _u8g2->drawXBMP(
+ obstacle->frame.postion.x,
+ obstacle->frame.postion.y,
+ obstacle->frame.size.width,
+ obstacle->frame.size.height,
+ _obstacleBackupImagePtr);
+}
+
+void DinoGameArduino::moveCloud()
+{
+ _cloud.frame.postion.y = 10;
+ _cloud.frame.size.width = 39;
+ _cloud.frame.size.height = 12;
+
+ _cloud.frame.postion.x--;
+
+ if (_cloud.frame.postion.x < -_cloud.frame.size.width)
+ {
+ _cloud.frame.postion.x = _u8g2->getWidth();
+ }
+}
+
+void DinoGameArduino::drawCloud()
+{
+ _u8g2->drawXBMP(
+ _cloud.frame.postion.x,
+ _cloud.frame.postion.y,
+ _cloud.frame.size.width,
+ _cloud.frame.size.height,
+ cloudImg);
+}
+
+// private
+void DinoGameArduino::resetDinoImagePtr(
+ const unsigned char **dinoImagePtr,
+ Dino *dino)
+{
+ switch (dino->pose)
+ {
+ case DINO_JUMP:
+ *dinoImagePtr = dinoJumpImg;
+ break;
+ case DINO_LEFT:
+ *dinoImagePtr = dinoLeftImg;
+ break;
+ case DINO_RIGHT:
+ *dinoImagePtr = dinoRightImg;
+ break;
+ case DINO_BLAH:
+ default:
+ *dinoImagePtr = dinoBlahImg;
+ break;
+ }
+}
+
+void DinoGameArduino::resetObstacleImagePtr(
+ const unsigned char **obstacleImagePtr,
+ Obstacle *obstacle)
+{
+ switch (obstacle->category)
+ {
+ case OBSTACLE_ONE_CACTUS:
+ *obstacleImagePtr = oneCactusImg;
+ break;
+ case OBSTACLE_TWO_CACTUS:
+ *obstacleImagePtr = twoCactusImg;
+ break;
+ case OBSTACLE_THREE_CACTUS:
+ *obstacleImagePtr = threeCactusImg;
+ break;
+ case OBSTACLE_ONE_SMALL_CACTUS:
+ *obstacleImagePtr = oneSmallCactusImg;
+ break;
+ case OBSTACLE_TWO_SMALL_CACTUS:
+ *obstacleImagePtr = twoSmallCactusImg;
+ break;
+ case OBSTACLE_THREE_SMALL_CACTUS:
+ *obstacleImagePtr = threeSmallCactusImg;
+ break;
+ case OBSTACLE_BIRD:
+ default:
+ *obstacleImagePtr = obstacle->frame.postion.x % 20 > 10 ? birdUpImg : birdDownImg;
+ break;
+ }
+}
\ No newline at end of file
diff --git a/DinoGame/libraries/dino_game/dino_game_arduino.h b/DinoGame/libraries/dino_game/dino_game_arduino.h
new file mode 100644
index 0000000..28c0f16
--- /dev/null
+++ b/DinoGame/libraries/dino_game/dino_game_arduino.h
@@ -0,0 +1,188 @@
+#ifndef __DINO_GAME_ARDUINO_H_
+#define __DINO_GAME_ARDUINO_H_
+
+#include "dino_game.h"
+#include
+
+class DinoGameArduino;
+
+// PRE-SAVED BITMAP CONSTANTS
+
+// 20 x 21
+static const unsigned char dinoBlahImg[] U8X8_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};
+
+// 20 x 21
+static const unsigned char dinoJumpImg[] U8X8_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};
+
+// 20 x 21
+static const unsigned char dinoLeftImg[] U8X8_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};
+
+// 20 x 21
+static const unsigned char dinoRightImg[] U8X8_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};
+
+// shape 0: 39 x 12
+static const unsigned char cloudImg[] U8X8_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};
+
+// shape 1: 10 x 20
+static const unsigned char oneCactusImg[] U8X8_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};
+
+// shape 2: 20 x 20
+static const unsigned char twoCactusImg[] U8X8_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};
+
+// shape 3: 20 x 20
+static const unsigned char threeCactusImg[] U8X8_PROGMEM = {
+ 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};
+
+// shape 4: 6 x 12
+static const unsigned char oneSmallCactusImg[] U8X8_PROGMEM = {
+ 0x0C, 0x0C, 0x3C, 0x3D, 0x2D, 0x3D, 0x1D, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C};
+
+// shape 5: 12 x 12
+static const unsigned char twoSmallCactusImg[] U8X8_PROGMEM = {
+ 0x0C, 0x03, 0x0C, 0x03, 0x6C, 0x0B, 0x6D, 0x0B, 0x6D, 0x0B, 0xBD, 0x0B,
+ 0x1F, 0x0F, 0x0E, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0x03};
+
+// shape 6: 17 x 12
+static const unsigned char threeSmallCactusImg[] U8X8_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};
+
+// 'birdUp', 21x18px
+static const unsigned char birdUpImg[] PROGMEM = {
+ 0x80, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x03, 0x00, 0x30, 0x07, 0x00, 0x38, 0x0f, 0x00, 0x7c,
+ 0x1f, 0x00, 0x7e, 0x3f, 0x00, 0xff, 0x3f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff,
+ 0x03, 0x00, 0xfe, 0x0f, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char birdDownImg[] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x7c,
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0xff, 0x3f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff,
+ 0x03, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x01, 0x00};
+
+static const unsigned char gameOverImg[] U8X8_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, 0x10, 0x04, 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, 0xF0, 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, 0x04, 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};
+
+static const unsigned char ultramanImg[] U8X8_PROGMEM = {
+ 0x80, 0x1f, 0x00, 0xe0, 0x7f, 0x00, 0x78, 0xe0, 0x01, 0x1c, 0x80, 0x03, 0x0c, 0x00, 0x03, 0x06,
+ 0x40, 0x06, 0xe6, 0xe1, 0x06, 0xf3, 0xf3, 0x0f, 0x33, 0x33, 0x0c, 0x13, 0x00, 0x0c, 0x03, 0x00,
+ 0x0c, 0x03, 0x00, 0x0c, 0x03, 0x20, 0x0c, 0x06, 0x60, 0x06, 0x86, 0x37, 0x06, 0x0c, 0x1f, 0x03,
+ 0x1c, 0x88, 0x03, 0x78, 0xe0, 0x01, 0xe0, 0x7f, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x0c, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x80, 0x6d, 0x00,
+ 0x80, 0x6d, 0x00, 0xc0, 0xcc, 0x00, 0xe0, 0xcc, 0x01, 0x60, 0x8c, 0x01, 0x30, 0x0c, 0x03, 0x30,
+ 0x0c, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00,
+ 0x00, 0x1e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x33, 0x00, 0x80, 0x61, 0x00, 0x80, 0x61, 0x00, 0xc0,
+ 0xc0, 0x00, 0xe0, 0xc0, 0x01, 0x60, 0x80, 0x01, 0x30, 0x00, 0x03, 0x30, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+class DinoGameArduino
+{
+public:
+ DinoGameArduino(U8G2 *u8g2);
+ virtual ~DinoGameArduino();
+
+ void setup();
+ void loop();
+
+ unsigned int getScore();
+ unsigned int getLevel();
+ DinoGameStatus getGameStatus();
+
+ void startGame();
+ void setCheatMode(CheatMode cheatMode);
+ void dinoJump();
+ void showUltraman();
+
+protected:
+ U8G2 *_u8g2;
+ DinoGame _dinoGame;
+
+ CheatMode _cheatMode;
+
+ void drawDino();
+ void drawObstacleReal();
+ void drawObstacleBackup();
+
+ // Custom game
+ Object _cloud;
+ void moveCloud();
+ void drawCloud();
+
+private:
+ const unsigned char *_dinoImagePtr;
+ const unsigned char *_obstacleRealImagePtr;
+ const unsigned char *_obstacleBackupImagePtr;
+
+ unsigned short _showUltraman;
+
+ void resetDinoImagePtr(
+ const unsigned char **dinoImagePtr,
+ Dino *dino);
+
+ void resetObstacleImagePtr(
+ const unsigned char **obstacleImagePtr,
+ Obstacle *obstacle);
+};
+
+#endif // !__DINO_GAME_ARDUINO_H_
\ No newline at end of file
diff --git a/DinoGame/preview.png b/DinoGame/preview.png
new file mode 100644
index 0000000..dcfd76a
Binary files /dev/null and b/DinoGame/preview.png differ