/*
Arduino | general-help
DarkStar — 7/21/25 at 9:01 PM
hi, I'm new to Arduino and I have this project that is a stacker block.
I need to connect a green led and speaker, where should I place it?
*/
#include "LedControl.h"
// Pins adjusted according to your connection:
// DATA (DIN) = 9, CLK = 11, CS = 10
LedControl lc = LedControl(11, 13, 10, 4);
// Function prototypes
void updateDisplay();
void updatePlacedBlockDisplay(int layerIndex);
bool checkButton();
void clearMovingBlock();
void displayMovingBlock();
void playSuccessSound();
void playGameOverSound();
void updateMaxPosition();
void placeBlock();
void displayLayer(int level);
// Constants
const int buttonPin = 12; // Button on pin 12
const int buzzerPin = 8; // Buzzer on pin 7
const int greenLedPin = 9; // Green LED on pin 2
const int blockColumns = 2; // Each block uses 2 columns
// Global variables
int currentWidth = 4;
int currentPos = -4;
int direction = 1;
int moveDelay = 150;
bool gameOver = false;
unsigned long lastMoveTime = 0;
int maxPosition = 0;
int buttonPressCount = 0;
int currentLayerCount = 0;
struct BlockLayer {
int position;
int width;
int startCol;
int colWidth;
};
BlockLayer layers[32];
void updateDisplay() {
for (int i = 0; i < 4; i++) {
lc.clearDisplay(i);
}
for (int i = 0; i < currentLayerCount; i++) {
int startCol = layers[i].startCol;
int colWidth = layers[i].colWidth;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int j = 0; j < layers[i].width; j++) {
int row = layers[i].position + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, true);
}
}
}
}
if (!gameOver) {
int startCol = currentLayerCount * blockColumns;
int colWidth = blockColumns;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int j = 0; j < currentWidth; j++) {
int row = currentPos + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, true);
}
}
}
}
}
void updatePlacedBlockDisplay(int layerIndex) {
int startCol = layers[layerIndex].startCol;
int colWidth = layers[layerIndex].colWidth;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int row = 0; row < 8; row++) {
lc.setLed(module, row, col, false);
}
for (int j = 0; j < layers[layerIndex].width; j++) {
int row = layers[layerIndex].position + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, true);
}
}
}
}
bool checkButton() {
if (digitalRead(buttonPin) == LOW) {
delay(20);
if (digitalRead(buttonPin) == LOW) {
while (digitalRead(buttonPin) == LOW) {}
return true;
}
}
return false;
}
void displayLayer(int level) {
int startCol = layers[level].startCol;
int colWidth = layers[level].colWidth;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int j = 0; j < layers[level].width; j++) {
int row = layers[level].position + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, true);
}
}
}
}
void displayMovingBlock() {
int startCol = currentLayerCount * blockColumns;
int colWidth = blockColumns;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int j = 0; j < currentWidth; j++) {
int row = currentPos + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, true);
}
}
}
}
void clearMovingBlock() {
int startCol = currentLayerCount * blockColumns;
int colWidth = blockColumns;
for (int colOffset = 0; colOffset < colWidth; colOffset++) {
int currentCol = startCol + colOffset;
int module = currentCol / 8;
int col = 7 - (currentCol % 8);
if (module >= 4) continue;
for (int j = 0; j < currentWidth; j++) {
int row = currentPos + j;
if (row >= 0 && row < 8) {
lc.setLed(module, row, col, false);
}
}
}
}
void playSuccessSound() {
tone(buzzerPin, 523, 100);
}
void playGameOverSound() {
tone(buzzerPin, 392, 200);
delay(200);
tone(buzzerPin, 349, 400);
delay(400);
}
void updateMaxPosition() {
maxPosition = 7 + currentWidth;
}
void placeBlock() { // timing.......................................
buttonPressCount++;
if (buttonPressCount == 4) {
moveDelay = 180;// 120
} else if (buttonPressCount == 8) {
moveDelay = 180;// 90
} else if (buttonPressCount == 12) {
moveDelay = 180;// 60
}
if (currentLayerCount == 0) {
layers[0].position = currentPos;
layers[0].width = currentWidth;
layers[0].startCol = 0;
layers[0].colWidth = blockColumns;
currentLayerCount = 1;
updateMaxPosition();
currentPos = random(-currentWidth, maxPosition + 1);
playSuccessSound();
updatePlacedBlockDisplay(0);
return;
}
int prevPos = layers[currentLayerCount - 1].position;
int prevWidth = layers[currentLayerCount - 1].width;
int overlapTop = max(prevPos, currentPos);
int overlapBottom = min(prevPos + prevWidth - 1, currentPos + currentWidth - 1);
if (overlapBottom < overlapTop) {
clearMovingBlock();
gameOver = true;
playGameOverSound();
digitalWrite(greenLedPin, LOW); // Make sure green LED is OFF when losing
return;
}
layers[currentLayerCount].position = overlapTop;
layers[currentLayerCount].width = overlapBottom - overlapTop + 1;
layers[currentLayerCount].startCol = currentLayerCount * blockColumns;
layers[currentLayerCount].colWidth = blockColumns;
currentWidth = overlapBottom - overlapTop + 1;
currentLayerCount++;
playSuccessSound();
int totalUsedCols = currentLayerCount * blockColumns;
if (totalUsedCols >= 32) {
gameOver = true;
digitalWrite(greenLedPin, HIGH); // Turn ON green LED on win
return;
}
updateMaxPosition();
currentPos = random(-currentWidth, maxPosition + 1);
updatePlacedBlockDisplay(currentLayerCount - 1);
}
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buzzerPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
digitalWrite(greenLedPin, LOW); // Turn OFF green LED on start
for (int i = 0; i < 4; i++) {
lc.shutdown(i, false);
lc.setIntensity(i, 8);
lc.clearDisplay(i);
}
currentLayerCount = 0;
currentPos = -currentWidth;
randomSeed(analogRead(0));
updateMaxPosition();
updateDisplay();
}
void loop() {
if (gameOver) {
static bool blinkState = false;
static unsigned long lastBlinkTime = 0;
if (millis() - lastBlinkTime > 500) {
lastBlinkTime = millis();
blinkState = !blinkState;
if (blinkState) {
updateDisplay();
} else {
for (int i = 0; i < 4; i++) {
lc.clearDisplay(i);
}
}
}
if (checkButton()) {
gameOver = false;
digitalWrite(greenLedPin, LOW); // Turn OFF green LED on reset
currentLayerCount = 0;
currentWidth = 4;
currentPos = -currentWidth;
moveDelay = 150;
direction = 1;
buttonPressCount = 0;
updateMaxPosition();
updateDisplay();
}
return;
}
unsigned long currentTime = millis();
if (currentTime - lastMoveTime > moveDelay) {
lastMoveTime = currentTime;
clearMovingBlock();
currentPos += direction;
if (currentPos < -currentWidth) {
int overshoot = (-currentWidth) - currentPos;
currentPos = -currentWidth + overshoot;
direction = -direction;
} else if (currentPos > maxPosition) {
int overshoot = currentPos - maxPosition;
currentPos = maxPosition - overshoot - (currentWidth - 1);
direction = -direction;
}
displayMovingBlock();
}
if (checkButton()) {
placeBlock();
}
}
5v 2A
External
Power