restrukture data
This commit is contained in:
parent
e29a23cc02
commit
ce1b800f37
2 changed files with 0 additions and 317 deletions
302
VSCode/main.cpp
302
VSCode/main.cpp
|
@ -1,302 +0,0 @@
|
||||||
#include <Arduino.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Player 1: x = 0
|
|
||||||
* Player 2: x = X_MAX-1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PIN_LED_MATRIX 2
|
|
||||||
#define PIN_JOYSTICK_1_BUTTON 6
|
|
||||||
#define PIN_JOYSTICK_2_BUTTON 7
|
|
||||||
#define PIN_PIEZO 11
|
|
||||||
#define PIN_JOYSTICK_1_Y A0
|
|
||||||
#define PIN_JOYSTICK_2_Y A1
|
|
||||||
|
|
||||||
#define JOYSTICK_OFFSET_MIN 200
|
|
||||||
#define JOYSTICK_OFFSET_MAX 700
|
|
||||||
|
|
||||||
#define DEBOUNCE_TIME 300 // in ms
|
|
||||||
|
|
||||||
#define X_MAX 10
|
|
||||||
#define Y_MAX 20
|
|
||||||
|
|
||||||
#define GAME_DELAY 80 // in ms
|
|
||||||
#define BALL_DELAY_MAX 350 // in ms
|
|
||||||
#define BALL_DELAY_MIN 50 // in ms
|
|
||||||
#define BALL_DELAY_STEP 5 // in ms
|
|
||||||
|
|
||||||
#define PLAYER_AMOUNT 2
|
|
||||||
#define PLAYER_1 0
|
|
||||||
#define PLAYER_2 1
|
|
||||||
|
|
||||||
#define PADDLE_WIDTH 3
|
|
||||||
|
|
||||||
#define PADDLE_MOVE_NONE 0
|
|
||||||
#define PADDLE_MOVE_UP 1
|
|
||||||
#define PADDLE_MOVE_DOWN 2
|
|
||||||
|
|
||||||
#define LED_TYPE_OFF 1
|
|
||||||
#define LED_TYPE_PADDLE 2
|
|
||||||
#define LED_TYPE_BALL 3
|
|
||||||
#define LED_TYPE_BALL_RED 4
|
|
||||||
|
|
||||||
#define TONE_PLAYER 1
|
|
||||||
#define TONE_WALL 2
|
|
||||||
#define TONE_BUZZ 3
|
|
||||||
|
|
||||||
#define GAME_STATE_RUNNING 1
|
|
||||||
#define GAME_STATE_END 2
|
|
||||||
#define GAME_STATE_INIT 3
|
|
||||||
|
|
||||||
#include <Adafruit_NeoPixel.h>
|
|
||||||
|
|
||||||
struct Coords {
|
|
||||||
byte x;
|
|
||||||
byte y;
|
|
||||||
};
|
|
||||||
|
|
||||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(X_MAX * Y_MAX, PIN_LED_MATRIX, NEO_GRB + NEO_KHZ800);
|
|
||||||
bool buttonPressed = false;
|
|
||||||
byte gameState;
|
|
||||||
byte joystickPins[PLAYER_AMOUNT] = {PIN_JOYSTICK_1_Y, PIN_JOYSTICK_2_Y};
|
|
||||||
Coords paddles[PLAYER_AMOUNT][PADDLE_WIDTH];
|
|
||||||
Coords ball;
|
|
||||||
int ballMovement[2];
|
|
||||||
unsigned int ballDelay;
|
|
||||||
unsigned long lastDrawUpdate = 0;
|
|
||||||
unsigned long lastBallUpdate = 0;
|
|
||||||
unsigned long lastButtonClick = 0;
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
pinMode(PIN_JOYSTICK_1_Y, INPUT);
|
|
||||||
pinMode(PIN_JOYSTICK_1_BUTTON, INPUT_PULLUP);
|
|
||||||
pinMode(PIN_JOYSTICK_2_Y, INPUT);
|
|
||||||
pinMode(PIN_JOYSTICK_2_BUTTON, INPUT_PULLUP);
|
|
||||||
pixels.begin();
|
|
||||||
resetLEDs();
|
|
||||||
gameState = GAME_STATE_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
switch(gameState) {
|
|
||||||
case GAME_STATE_INIT:
|
|
||||||
initGame();
|
|
||||||
break;
|
|
||||||
case GAME_STATE_RUNNING:
|
|
||||||
updateBall();
|
|
||||||
updateGame();
|
|
||||||
break;
|
|
||||||
case GAME_STATE_END:
|
|
||||||
if (isButtonPressed()) {
|
|
||||||
gameState = GAME_STATE_INIT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initGame()
|
|
||||||
{
|
|
||||||
resetLEDs();
|
|
||||||
lastButtonClick = millis();
|
|
||||||
|
|
||||||
ball.x = 1;
|
|
||||||
ball.y = (Y_MAX/2) - (PADDLE_WIDTH/2) + 1;
|
|
||||||
ballMovement[0] = 1;
|
|
||||||
ballMovement[1] = -1;
|
|
||||||
ballDelay = BALL_DELAY_MAX;
|
|
||||||
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
paddles[PLAYER_1][i].x = 0;
|
|
||||||
paddles[PLAYER_1][i].y = (Y_MAX/2) - (PADDLE_WIDTH/2) + i;
|
|
||||||
paddles[PLAYER_2][i].x = X_MAX - 1;
|
|
||||||
paddles[PLAYER_2][i].y = paddles[PLAYER_1][i].y;
|
|
||||||
}
|
|
||||||
|
|
||||||
gameState = GAME_STATE_RUNNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateBall()
|
|
||||||
{
|
|
||||||
bool hitBall = false;
|
|
||||||
if ((millis() - lastBallUpdate) < ballDelay) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastBallUpdate = millis();
|
|
||||||
toggleLed(ball.x, ball.y, LED_TYPE_OFF);
|
|
||||||
|
|
||||||
// collision detection for player 1
|
|
||||||
if (ballMovement[0] == -1 && ball.x == 1) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
if (paddles[PLAYER_1][i].y == ball.y) {
|
|
||||||
hitBall = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// collision detection for player 2
|
|
||||||
if (ballMovement[0] == 1 && ball.x == X_MAX-2) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
if (paddles[PLAYER_2][i].y == ball.y) {
|
|
||||||
hitBall = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hitBall == true) {
|
|
||||||
ballMovement[0] *= -1;
|
|
||||||
playTone(TONE_PLAYER);
|
|
||||||
if (ballDelay > BALL_DELAY_MIN) {
|
|
||||||
ballDelay -= BALL_DELAY_STEP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ball.x += ballMovement[0];
|
|
||||||
ball.y += ballMovement[1];
|
|
||||||
|
|
||||||
if (ball.x <=0 || ball.x >= X_MAX-1) {
|
|
||||||
endGame();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ball.y <= 0 || ball.y >= Y_MAX-1) {
|
|
||||||
ballMovement[1] *= -1;
|
|
||||||
playTone(TONE_WALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleLed(ball.x, ball.y, LED_TYPE_BALL);
|
|
||||||
pixels.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void endGame()
|
|
||||||
{
|
|
||||||
gameState = GAME_STATE_END;
|
|
||||||
toggleLed(ball.x, ball.y, LED_TYPE_BALL_RED);
|
|
||||||
pixels.show();
|
|
||||||
playTone(TONE_BUZZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateGame()
|
|
||||||
{
|
|
||||||
if ((millis() - lastDrawUpdate) < GAME_DELAY) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastDrawUpdate = millis();
|
|
||||||
|
|
||||||
// turn off paddle LEDs
|
|
||||||
for(byte p=0; p<PLAYER_AMOUNT; p++) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
toggleLed(paddles[p][i].x, paddles[p][i].y, LED_TYPE_OFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// move paddles
|
|
||||||
for(byte p=0; p<PLAYER_AMOUNT; p++) {
|
|
||||||
byte movement = getPlayerMovement(p);
|
|
||||||
if (movement == PADDLE_MOVE_UP && paddles[p][PADDLE_WIDTH-1].y < (Y_MAX-1)) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
paddles[p][i].y++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (movement == PADDLE_MOVE_DOWN && paddles[p][0].y > 0) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
paddles[p][i].y--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// show paddle LEDs
|
|
||||||
for(byte p=0; p<PLAYER_AMOUNT; p++) {
|
|
||||||
for(byte i=0; i<PADDLE_WIDTH; i++) {
|
|
||||||
toggleLed(paddles[p][i].x, paddles[p][i].y, LED_TYPE_PADDLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pixels.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte getPlayerMovement(byte playerId)
|
|
||||||
{
|
|
||||||
int value = analogRead(joystickPins[playerId]);
|
|
||||||
if (value < JOYSTICK_OFFSET_MIN) {
|
|
||||||
if (playerId == PLAYER_2) {
|
|
||||||
return PADDLE_MOVE_DOWN;
|
|
||||||
} else {
|
|
||||||
return PADDLE_MOVE_UP;
|
|
||||||
}
|
|
||||||
} else if (value > JOYSTICK_OFFSET_MAX) {
|
|
||||||
if (playerId == PLAYER_2) {
|
|
||||||
return PADDLE_MOVE_UP;
|
|
||||||
} else {
|
|
||||||
return PADDLE_MOVE_DOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PADDLE_MOVE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isButtonPressed()
|
|
||||||
{
|
|
||||||
if ((millis() - lastButtonClick) < DEBOUNCE_TIME) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (digitalRead(PIN_JOYSTICK_1_BUTTON) == LOW) {
|
|
||||||
lastButtonClick = millis();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (digitalRead(PIN_JOYSTICK_2_BUTTON) == LOW) {
|
|
||||||
lastButtonClick = millis();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetLEDs()
|
|
||||||
{
|
|
||||||
for(byte i=0; i<X_MAX*Y_MAX; i++) {
|
|
||||||
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
|
|
||||||
}
|
|
||||||
pixels.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void toggleLed(byte x, byte y, byte type)
|
|
||||||
{
|
|
||||||
byte ledIndex = y * X_MAX + x;
|
|
||||||
uint32_t color;
|
|
||||||
|
|
||||||
switch(type) {
|
|
||||||
case LED_TYPE_PADDLE:
|
|
||||||
color = pixels.Color(0, 8, 8);
|
|
||||||
break;
|
|
||||||
case LED_TYPE_BALL_RED:
|
|
||||||
color = pixels.Color(12, 0, 0);
|
|
||||||
break;
|
|
||||||
case LED_TYPE_BALL:
|
|
||||||
color = pixels.Color(0, 10, 0);
|
|
||||||
break;
|
|
||||||
case LED_TYPE_OFF:
|
|
||||||
color = pixels.Color(0, 0, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixels.setPixelColor(ledIndex, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void playTone(byte type)
|
|
||||||
{
|
|
||||||
switch(type) {
|
|
||||||
case TONE_PLAYER:
|
|
||||||
tone(PIN_PIEZO, 440, 50);
|
|
||||||
break;
|
|
||||||
case TONE_WALL:
|
|
||||||
tone(PIN_PIEZO, 550, 50);
|
|
||||||
break;
|
|
||||||
case TONE_BUZZ:
|
|
||||||
for(byte i=0; i<20; i++) {
|
|
||||||
tone(PIN_PIEZO, 220-i*10, 50);
|
|
||||||
delay(50);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
; PlatformIO Project Configuration File
|
|
||||||
;
|
|
||||||
; Build options: build flags, source filter
|
|
||||||
; Upload options: custom upload port, speed and extra flags
|
|
||||||
; Library options: dependencies, extra library storages
|
|
||||||
; Advanced options: extra scripting
|
|
||||||
;
|
|
||||||
; Please visit documentation for the other options and examples
|
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
|
||||||
|
|
||||||
[env:uno]
|
|
||||||
platform = atmelavr
|
|
||||||
board = uno
|
|
||||||
framework = arduino
|
|
||||||
lib_deps = adafruit/Adafruit NeoPixel@^1.10.4
|
|
Loading…
Reference in a new issue