/*
*
* Button Connections:
* - UP Button: connected to pin 5
* - LEFT Button: connected to pin 4
* - DOWN Button: connected to pin 3
* - RIGHT Button: connected to pin 2
* - RESET Button: connected to pin 16
*
* Note: External pull-down resistors are used with the buttons to ensure stable readings.
*
* License:
* This project is open-source hardware and software, released under the MIT License.
* See the LICENSE file for details.
*/
#include <FastLED.h>
#include "map.h"
// LED matrix settings
#define NUM_LEDS 108
#define DATA_PIN 22
#define BRIGHTNESS 255
// Setup LEDS
CRGB leds[NUM_LEDS];
// Button pins
#define UP_BUTTON 5
#define LEFT_BUTTON 4
#define DOWN_BUTTON 3
#define RIGHT_BUTTON 2
#define RESET_BUTTON 6
// LED Matrix Layout. 0-69 real pixels. 70+ Fake pixels to count as map borders.
int matrix[9][12] = {
{70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81},
{82, 0, 1, 2, 3, 4, 5, 6, 7 ,8, 9, 83},
{84, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 85},
{86, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 87},
{88, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 89},
{90, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 91},
{92, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 93},
{94, 60, 61, 62, 63, 64, 65, 66, 67 ,68, 69, 95},
{96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107}
};
int currentMap[9][12];
int currentMapX;
int currentMapY;
int mapsWorld[8][16] = {
{101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116},
{201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216},
{301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316},
{401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416},
{501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516},
{601,602,603,604,605,606,607,608,600,610,611,612,613,614,615,616},
{701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716},
{801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816}
};
unsigned long playerSpeed = 100; // Adjust this value to change speed, increase the value to make it slower
unsigned long lastMoveTime = 0; //
bool newRoom = true;
// Player properties properties
struct Player { int hp, x, y; };
Player player;
int dx, dy;
int newPlayerX;
int newPlayerY;
// enemy properties
struct Enemy { int hp, x, y; };
Enemy enemy1;
void setup() {
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
pinMode(UP_BUTTON, INPUT_PULLUP);
pinMode(LEFT_BUTTON, INPUT_PULLUP);
pinMode(DOWN_BUTTON, INPUT_PULLUP);
pinMode(RIGHT_BUTTON, INPUT_PULLUP);
pinMode(RESET_BUTTON, INPUT_PULLUP);
initializeGame();
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - lastMoveTime >= playerSpeed) {
if (digitalRead(UP_BUTTON) == LOW) {
dx = -1;
dy = 0;
movePlayer( -1, 0);
lastMoveTime = currentMillis;
}
if (digitalRead(LEFT_BUTTON) == LOW) {
dx = 0;
dy = -1;
movePlayer( 0, -1);
lastMoveTime = currentMillis;
}
if (digitalRead(DOWN_BUTTON) == LOW) {
dx = 1;
dy = 0;
movePlayer( 1, 0);
lastMoveTime = currentMillis;
}
if (digitalRead(RIGHT_BUTTON) == LOW) {
dx = 0;
dy = 1;
movePlayer( 0, 1);
lastMoveTime = currentMillis;
}
FastLED.clear();
drawMap();
drawPlayer();
FastLED.show();
delay(30);
}
}
// Initialize or reset game
void initializeGame() {
player.hp = 3;
player.x = 5;
player.y = 5;
dx = 0;
dy = -1; // Initial direction: moving up
currentMapX = 0;
currentMapY = 1;
loadMap(map102);
}
// Move Player
void movePlayer(int xM, int yM) {
newPlayerY=player.y+yM;
newPlayerX=player.x+xM;
if( leds[matrix[newPlayerX][newPlayerY]] == false or leds[matrix[newPlayerX][newPlayerY]] == CRGB::SandyBrown) {
player.y = newPlayerY; player.x = newPlayerX;
}
else if (leds[matrix[newPlayerX][newPlayerY]] == CRGB::Red) {
// heal up!
newPlayerY = player.y-yM;
newPlayerX = player.x-xM;
if( leds[matrix[newPlayerX][newPlayerY]] == false) {
player.y = newPlayerY; player.x = newPlayerX;
}
}
else if (leds[matrix[newPlayerX][newPlayerY]] == CRGB::Yellow) {
//move to new map
int newMapX = currentMapX + dx;
int newMapY = currentMapY + dy;
int newMap = mapsWorld[newMapX][newMapY];
if (dx == 1) {
player.x = 1;
}
if (dx == -1) {
player.x = 7;
}
if (dy == 1) {
player.y = 1;
}
if (dy == -1) {
player.y = 10;
}
//newMap = currentMap[x][y];
changeMap(newMap);
currentMapX = newMapX;
currentMapY = newMapY;
}
}
//Draw Maps
void drawMap() {
int x;
int y;
for( x = 0; x < 9; x++ ){
for( y = 0; y < 12; y++ ){
if (currentMap[x][y] == 1) { leds[matrix[x][y]] = CRGB::Green; }
if (currentMap[x][y] == 2) { leds[matrix[x][y]] = CRGB::Red; }
if (currentMap[x][y] == 3) { leds[matrix[x][y]] = CRGB::Yellow; }
if (currentMap[x][y] == 4) { leds[matrix[x][y]] = CRGB::SandyBrown; }
if (currentMap[x][y] >= 100) { leds[matrix[x][y]] = CRGB::Yellow; }
}
}
}
//Draw scripts
void drawPlayer() {
leds[matrix[player.x][player.y]] = CRGB::Blue;
}
void changeMap(int mapID){
int mID=mapID;
switch(mID){
case 101:
loadMap(map101);
break;
case 102:
loadMap(map102);
break;
case 103:
loadMap(map103);
break;
case 104:
loadMap(map104);
break;
case 105:
loadMap(map105);
break;
case 106:
loadMap(map106);
break;
case 107:
loadMap(map107);
break;
case 108:
loadMap(map108);
break;
case 109:
loadMap(map109);
break;
case 110:
loadMap(map110);
break;
case 201:
loadMap(map201);
break;
case 202:
loadMap(map202);
break;
}
}
void loadMap(int arr[9][12]) {
int x;
int y;
for( x = 0; x < 9; x++ ){
for( y = 0; y < 12; y++ ){
currentMap[x][y] = arr[x][y];
}
}
}