From 6e21069d02b589acc6513a7d7fc954b4cc1b0b08 Mon Sep 17 00:00:00 2001 From: julian T Date: Sun, 30 Dec 2018 17:22:37 +0100 Subject: DOne --- Jetris.ino | 161 ++++++++++++++++++++++++++++++++++++++++++++---------------- drawing.h | 5 +- drawing.ino | 3 +- sprites.h | 3 +- sprites.ino | 2 + 5 files changed, 129 insertions(+), 45 deletions(-) diff --git a/Jetris.ino b/Jetris.ino index 6ecc80a..b600178 100644 --- a/Jetris.ino +++ b/Jetris.ino @@ -1,25 +1,31 @@ #include "drawing.h" #include "sprites.h" +/* Compile settings */ +#define DEBUG_TO_SERIAL 1 +#define RENDER_TO_SERIAL 0 + +/* Pin definitions */ #define LEFT_PIN 2 #define RIGHT_PIN 4 #define DROP_PIN 11 #define ROTATE_PIN 10 +#define BUZZ_PIN 6 -#define CLICK_TIME 200 -#define FALL_TIME 300 - -#define DEBUG_TO_SERIAL 1 -#define RENDER_TO_SERIAL 0 +/* Timing */ +#define CLICK_TIME 100 +#define FALL_TIME 500 +#define DIFF 0.98 void setup() { -#if DEBUG_TO_SERIAL == 1 or RENDER_TO_SERIAL == 1 Serial.begin(115200); Serial.println("Starting \n\n"); -#endif /* Prepare the random generator */ randomSeed( analogRead(0) ); + + /* First random is always 0(dont know why) */ + random(7); /* Init pins */ pinMode(CS, OUTPUT); @@ -30,13 +36,13 @@ void setup() { pinMode(DROP_PIN, INPUT_PULLUP); pinMode(ROTATE_PIN, INPUT_PULLUP); + /* Init displays */ initDisplays(0); initDisplays(1); + /* Init game */ initSprites(); initGame(); - - } void loop() { @@ -51,6 +57,7 @@ void loop() { struct Sprite *cur_block; int x_pos, y_pos, score; +int drop_speed = FALL_TIME; void initGame() { initBlock(); @@ -60,13 +67,14 @@ void gameLoop() { static long loop_time; - handleButtons(); + /* Combine inputs */ + handleInputs( inputFromButtons() | inputFromSerial() ); - if( millis() - loop_time < FALL_TIME) + if( millis() - loop_time < drop_speed) return; /* Move the cur_block */ - if( checkCollision(0, 1) ){ + if( checkCollision(0, 1, cur_block) ){ drawSprite(buttonLayer, x_pos, y_pos, cur_block); /* Debug information */ @@ -100,7 +108,7 @@ int initBlock() { y_pos = 0; x_pos = 4 - cur_block->width/2; - return checkCollision(0, 0); + return checkCollision(0, 0, cur_block); } void moveBlock(int x_move, int y_move) { @@ -116,18 +124,18 @@ void moveBlock(int x_move, int y_move) { } /* Returns 1 if there is collision in specified direction */ -int checkCollision(int xMove, int yMove) { +int checkCollision(int xMove, int yMove, struct Sprite *block) { /* New position */ int xNew = x_pos + xMove; int yNew = y_pos + yMove; - for( int i = 0; i < cur_block->height; i++ ) { - if( (cur_block->buff[i] >> xNew) & buttonLayer[i + yNew] ) + for( int i = 0; i < block->height; i++ ) { + if( (block->buff[i] >> xNew) & buttonLayer[i + yNew] ) return 1; } /* Check if border is hit */ - if( xNew + cur_block->width > 8 || xNew < 0 || yNew + cur_block->height > 16 || yNew < 0 ) + if( xNew + block->width > 8 || xNew < 0 || yNew + block->height > 16 || yNew < 0 ) return 1; return 0; @@ -145,7 +153,7 @@ int rotateBlock() { void dropBlock() { /* Move down until it hits something */ - while( !checkCollision(0, 1) ) { + while( !checkCollision(0, 1, cur_block) ) { moveBlock(0, 1); /* Add delay to make falling effect */ @@ -164,37 +172,58 @@ void handleFullRows(int start) { buttonLayer[15 - j] = buttonLayer[14 - j]; } - /* Increase score */ + /* Increase score and make sound */ score++; + tone(BUZZ_PIN, 880, 200); + + /* Lower falling speed */ + drop_speed *= DIFF; } else { i++; } } } -void endGame() { - /* Slowly clear screen */ - for( int i = 0; i < 16; i++ ) { - buttonLayer[15 - i] = topLayer[15 - i] = 0; - renderAll(); - delay(100); - } +void printScore(int score) { - /* Fill button of screen with score */ + /* There are 8 dots per row. Find number of rows and whats left */ int xFill = score % 8; int yFill = score / 8; int y = 0; + #if DEBUG_TO_SERIAL == 1 Serial.print("Finished with score "); Serial.println(score); #endif + /* Fill out rows */ for( y = 0; y < yFill; y++ ){ buttonLayer[15 - y] = 0xFF; } + /* Fill out leftover dots on last row */ for( int x = 0; x < xFill; x++ ){ buttonLayer[15 - y] = buttonLayer[15 - y] | ( 1 << x ); } +} + +const int endTone[] = {880, 622, 415, 415}; + +void endGame() { + /* Slowly clear screen */ + for( int i = 0; i < 16; i++ ) { + buttonLayer[15 - i] = topLayer[15 - i] = 0; + renderAll(); + + /* End tone*/ + if(i % 4 == 0) { + tone(BUZZ_PIN, endTone[i/4]); + } + delay(100); + } + noTone(BUZZ_PIN); + + /* Fill button of screen with score */ + printScore(score); /* Replicate the DVD gliding logo thing */ @@ -204,10 +233,10 @@ void endGame() { y_pos = 3; while(1){ - if( checkCollision(xV, 0) ) { + if( checkCollision(xV, 0, cur_block) ) { xV *= -1; } - if( checkCollision(0, yV) ) { + if( checkCollision(0, yV, cur_block) ) { yV *= -1; } @@ -231,36 +260,84 @@ void renderAll() { */ unsigned long leftLast, rightLast, dropLast, rotateLast; -void handleButtons() { +#define LEFT_MASK 0b10000000 +#define RIGHT_MASK 0b01000000 +#define ROTATE_MASK 0b00100000 +#define DROP_MASK 0b00010000 + +uint8_t inputFromButtons() { + + uint8_t is = 0; + /* Read from switches */ - int leftState = !digitalRead(LEFT_PIN); - int rightState = !digitalRead(RIGHT_PIN); - int dropState = !digitalRead(DROP_PIN); - int rotateState = !digitalRead(ROTATE_PIN); + is |= LEFT_MASK * !digitalRead(LEFT_PIN); + is |= RIGHT_MASK * !digitalRead(RIGHT_PIN); + is |= ROTATE_MASK * !digitalRead(ROTATE_PIN); + is |= DROP_MASK * !digitalRead(DROP_PIN); + + return is; +} + +uint8_t inputFromSerial() { + + uint8_t is = 0; + + /* Read all input */ + while( Serial.available() ) { + /* Read character */ + char c = Serial.read(); + + switch( c ) { + case 'd': + is |= LEFT_MASK; + break; + case 'a': + is |= RIGHT_MASK; + break; + case 'w': + is |= ROTATE_MASK; + break; + case ' ': + is |= DROP_MASK; + break; + default: + /* Send help */ + Serial.println("a: left, d: right, w: rotate, space: drop"); + } + } + + return is; +} + +void handleInputs(uint8_t is) { /* Check if last click is over 100 ms */ - if( leftState && millis() - leftLast > CLICK_TIME ) { + if( ( is & LEFT_MASK ) && millis() - leftLast > CLICK_TIME ) { leftLast = millis(); /* Move left */ - if( !checkCollision(1, 0) ) + if( !checkCollision(1, 0, cur_block) ) moveBlock(1, 0); } /* Repeat for others buttons */ - if( rightState && millis() - rightLast > CLICK_TIME ) { + if( ( is & RIGHT_MASK ) && millis() - rightLast > CLICK_TIME ) { rightLast = millis(); - if( !checkCollision(-1, 0) ) + if( !checkCollision(-1, 0, cur_block) ) moveBlock(-1, 0); } - if( dropState && millis() - dropLast > CLICK_TIME + 100 ){ + if( ( is & DROP_MASK ) && millis() - dropLast > CLICK_TIME/2 ){ dropLast = millis(); - dropBlock(); + if( !checkCollision(0, 1, cur_block) ) + moveBlock(0, 1); } - if( rotateState && millis() - rotateLast > CLICK_TIME + 100 ){ + if( ( is & ROTATE_MASK ) && millis() - rotateLast > CLICK_TIME*2 ){ rotateLast = millis(); - rotateBlock(); + if( !checkCollision(0, 0, cur_block->rotateNext ) ) + rotateBlock(); } } + + diff --git a/drawing.h b/drawing.h index 24a033a..058d6c7 100644 --- a/drawing.h +++ b/drawing.h @@ -2,11 +2,14 @@ #ifndef drawing #define drawing +/* Display settings */ #define BUFF_HEIGHT 16 #define REDRAW_TIME 1000 #define NUM_DISPLAY 2 + +/* Pin difinitions */ #define CLK 5 -#define CS 6 +#define CS 12 #define DATA_IN 3 /* Layers */ diff --git a/drawing.ino b/drawing.ino index 4bfbb30..35a8586 100644 --- a/drawing.ino +++ b/drawing.ino @@ -82,7 +82,8 @@ void renderToSerial() { } } -/* Write a register to specified display */ +/* Write a register to specified display + * A static function is only available in this file */ static void writeCommand(int display, uint8_t addr, uint8_t data) { /* Chip select low */ digitalWrite(CS, LOW); diff --git a/sprites.h b/sprites.h index e3f8300..b4074a2 100644 --- a/sprites.h +++ b/sprites.h @@ -11,8 +11,9 @@ struct Sprite { struct Sprite *rotateNext; }; +void initSprites(); - +/* The rotateNext reference is set up i the initSprite function */ struct Sprite ball = { { 0b11100000, diff --git a/sprites.ino b/sprites.ino index 54f8aa5..0f3d1bf 100644 --- a/sprites.ino +++ b/sprites.ino @@ -1,6 +1,8 @@ #include "sprites.h" void initSprites() { + /* The sprites work by having a reference to the rotated block + * Had some issues with linking them up i .h files, thus this is done here */ iBlock.rotateNext = &iBlockR; iBlockR.rotateNext = &iBlock; -- cgit v1.2.3