#include <FastLED.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "wiring_private.h"
#define MFLAG GPIOR0
#define ADC_DONE 0
volatile uint16_t aRead;
volatile bool ledState = false;
float period = 1;
int stepMove = 0;
int indexBallStart = 0;
int indexRacket = 0;
volatile int indexBall = 0;
volatile bool onOff = false; // start e off del gioco
#define LED_PIN 8
#define NUM_LEDS 32
#define LED_TYPE WS2812B
#define VERT_PIN A0
#define HORZ_PIN A1
#define SEL_PIN 2
//valori di movimento della pallina
//SAREBBE MEGLIO METTE SOLO I VALORI POSITIVI ?
#define move1 3
#define move2 -3
#define move3 4
#define move4 -4
#define move5 5
#define move6 -5
//Pareti dell'insieme di led
int rightWall[8] = { 4, 8, 12, 16, 20, 24 };
int leftWall[8] = { 7, 11, 15, 19, 23, 27 };
int topWall[8] = { 28, 29, 30, 31 };
int bottomWall[8] = { 0, 1, 2, 3 };
CRGB leds[NUM_LEDS];//imposta un array che possiamo manipolare per impostare/cancellare i dati dei led
//volatile bool buttonPressed = false;
// ISR per INT0 (pin 2)
ISR(INT0_vect) {
//buttonPressed = true;
onOff = !onOff;
// si impostano le posizioni iniziali della rachetta e della palla a inizio gioco
indexBall = randomNum(31,28);
leds[indexRacket] = CRGB::White;
leds[indexBall] = CRGB::Gold;
FastLED.show();
PORTB |= (1 << PORTB5);
}
void setup(){
FastLED.addLeds<LED_TYPE, LED_PIN>(leds, NUM_LEDS);
Serial.begin(9600);
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
//pinMode(SEL_PIN, INPUT_PULLUP);
DDRD &= ~(1 << DDD2); // Clear PD2 to input
PORTD |= (1 << PORTD2); // Enable pull-up resistor on PD2
// Configurare INT0 per generare un interrupt su un fronte di discesa
EICRA |= (1 << ISC01); // ISC01=1, ISC00=0: Interrupt on falling edge
EICRA &= ~(1 << ISC00);
// Abilitare l'interrupt per INT0
EIMSK |= (1 << INT0); // Enable INT0
// Abilitare gli interrupt globali
sei();
}
void loop(){
int horz = analogRead(HORZ_PIN);
int vert = analogRead(VERT_PIN);
//FASE 1 : IMPOSTAZIONE DELLE POSIZIONI INIZIALI
/*if (digitalRead(SEL_PIN) == 0) {
onOff = !onOff;
// si impostano le posizioni iniziali della rachetta e della palla a inizio gioco
indexBall = randomNum(31,28);
leds[indexRacket] = CRGB::White;
leds[indexBall] = CRGB::Gold;
FastLED.show();
delay(250);
}*/
/*
if (buttonPressed) {
onOff = !onOff;
// si impostano le posizioni iniziali della rachetta e della palla a inizio gioco
indexBall = randomNum(31,28);
leds[indexRacket] = CRGB::White;
leds[indexBall] = CRGB::Gold;
FastLED.show();
buttonPressed = false;
}*/
//FASE 2 : SVOLGIMENTO DEL GIOCO
if(onOff){
Serial.println("ciao");
//Serial.println(onOff);
//levetta del joystick a sinistra
if(horz == 1023 && vert == 512){
moveSxRacket();
delay(250);
}
//levetta del joystick a destra
if(horz == 0 && vert == 512){
moveDxRacket();
delay(250);
}
ControlStepMove();
moveBall();
delay(500);
}
}
//FUNZIONI-----------------------------------------------------------------------------------
//movimento a sinistra della racchetta
void moveSxRacket() {
indexRacket++;
if (indexRacket > 3) {
indexRacket = 3;
}
leds[indexRacket] = CRGB::White;
FastLED.show();
if (indexRacket <= 3) {
leds[indexRacket - 1] = CRGB::Black;
FastLED.show();
}
}
// mivimento a destra della racchetta
void moveDxRacket() {
indexRacket--;
if (indexRacket < 0) {
indexRacket = 0;
}
leds[indexRacket] = CRGB::White;
FastLED.show();
if (indexRacket >= 0) {
leds[indexRacket + 1] = CRGB::Black;
FastLED.show();
}
}
// creazione di un numero casuale per la scelta casuale tra due numeri
int randomNum(int num1, int num2) {
randomSeed(millis());
int randomIndex = random(0,2);
int chosenNumber = (randomIndex == 0) ? num1 : num2;
return chosenNumber;
}
//Movimento generico della pallina
void moveBall() {
int prevIndexBall = indexBall;
indexBall = indexBall + stepMove;
leds[prevIndexBall] = CRGB::Black;
leds[indexBall] = CRGB::Gold;
FastLED.show();
}
void ControlStepMove() {
//Controllo se la pallina sta rimbalzando nella parete destra
bool flagWDx = contains(rightWall, 6, indexBall);
if (flagWDx){
if (stepMove == move6) {
stepMove = move2;
}
else if (stepMove == move1){
stepMove = move5;
}
}
//Controllo se la pallina sta rimbalzando nella parete sinistra
bool flagWSx = contains(leftWall, 6, indexBall);
if (flagWSx) {
if (stepMove == move2) {
stepMove = move6;
}
else if (stepMove == move5){
stepMove = move1;
}
}
//Controllo se la pallina sta rimbalzando nella parete in alto
bool flagTop = contains(topWall, 4, indexBall);
if (flagTop) {
if (indexBall == 28) {
stepMove = move2;
}
else if (indexBall == 31) {
stepMove = move6;
}
else{
if (stepMove == move1) {
stepMove = move6;
}
else if (stepMove == move5) {
stepMove = move2;
}
}
}
//Controllo se la pallina sta rimbalzando in basso e se viene intercettata dalla racchetta
bool flagBottom = contains(bottomWall, 4, indexBall);
if (flagBottom) {
if (indexBall == indexRacket) {
if (indexBall == 3) {
stepMove = move1;
}
else if (indexBall == 0) {
stepMove = move5;
}
else {
if (stepMove == move6) {
stepMove = move1;
}
else if (stepMove == move2) {
stepMove = move5;
}
}
}
else {
onOff != onOff; //fine partita
}
}
}
//FUNZIONI BASE
bool contains(int arr[], int size, int number) {
for (int i = 0; i < size; i++) {
if (arr[i] == number) {
return true;
}
}
return false;
}