blockBreaker/main.c

212 lines
6.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include<unistd.h>
#include<stdbool.h>
#define SCREEN_WIDTH 11
#define SCREEN_HEIGHT 20
#define PADDLE_SIZE 2
#define SLEEP_TIME_MS 100 * 1000
#define PADDLE_HEIGHT SCREEN_HEIGHT-4
#define Y_BLOCK_LAYERS 10
#define X_BLOCK_LAYERS SCREEN_WIDTH
uint8_t screen[SCREEN_WIDTH][SCREEN_HEIGHT];
enum PIXEL_TYPE {
PIXEL_EMPTY=0u,
PIXEL_BALL=1u,
PIXEL_BLOCK=2u,
PIXEL_PADDLE_MIDDLE=3u,
PIXEL_PADDLE_LEFT=4u,
PIXEL_PADDLE_RIGHT=5u
} PIXEL_TYPE;
void clearScreen() {
for (int y = 0; y < SCREEN_HEIGHT; y++) {
for (int x=0; x<SCREEN_WIDTH; x++) {
screen[x][y]=PIXEL_EMPTY;
}
}
printf("\e[1;1H\e[2J");//clear the screen of the prev frame
}
typedef struct ballStruct {
uint8_t xPOS;
uint8_t yPOS;
int8_t xVEL;
int8_t yVEL;
} Ball_t;
struct Paddle {
uint8_t location;
uint8_t paddleSize;
} paddle= {.location=(SCREEN_WIDTH/2),.paddleSize=PADDLE_SIZE};
typedef struct block {
uint8_t xLocation;
uint8_t yLocation;
bool visable;
} Block_t;
bool ballOnXEdge(Ball_t ball){
if(ball.xPOS==0) return true;
if (ball.xPOS==SCREEN_WIDTH-1) return true;
return false;
}
int main() {
Ball_t ball = {.xPOS=0,.yPOS=0,.xVEL=0,.yVEL=0};
time_t UNIXTIME = time(NULL);
srand(UNIXTIME); //seed random number with time at run time
Block_t blockArr[X_BLOCK_LAYERS][Y_BLOCK_LAYERS];
bool blockFlushHit = false; //used to show if the ball has hit a block vertically or horizontally
//init blockArr array
for (int x=0; x< X_BLOCK_LAYERS; x++) {
for (int y=0; y<Y_BLOCK_LAYERS; y++) {
blockArr[x][y]=(Block_t) {
.xLocation =x,.yLocation=y,.visable=true
};
}
}
ball.xPOS=rand()% SCREEN_WIDTH;
ball.yPOS= PADDLE_HEIGHT-1;
ball.xVEL=1;
ball.yVEL=1;
while(true) {
usleep(SLEEP_TIME_MS);
clearScreen();
blockFlushHit = false;
//draw blocks
for (int x = 0; x<X_BLOCK_LAYERS; x++) {
for (int y =0; y<Y_BLOCK_LAYERS; y++) {
if(blockArr[x][y].visable==true) {
screen[x][y]=PIXEL_BLOCK;
}
}
}
/* //draw paddel
screen[paddle.location][PADDLE_HEIGHT]=PIXEL_PADDLE_MIDDLE;
for(int x= 0; x<=PADDLE_SIZE; x++) {
screen[paddle.location-x][PADDLE_HEIGHT]=PIXEL_PADDLE_LEFT;
screen[paddle.location+x][PADDLE_HEIGHT]=PIXEL_PADDLE_RIGHT;
} */
for (int x=0-PADDLE_SIZE;x<PADDLE_SIZE;x++){
if(x==0-PADDLE_SIZE){
screen[paddle.location+x][PADDLE_HEIGHT]=PIXEL_PADDLE_LEFT;
} else if (x==PADDLE_SIZE-1){
screen[paddle.location+x][PADDLE_HEIGHT]=PIXEL_PADDLE_RIGHT;
} else {
screen[paddle.location+x][PADDLE_HEIGHT]=PIXEL_PADDLE_MIDDLE;
}
}
//draw ball
screen[ball.xPOS][ball.yPOS]=PIXEL_BALL;
//render step
for (int x =0; x<=SCREEN_WIDTH; x++) {
printf("--"); //top border
}
printf("\n");
for (int y = 0; y < SCREEN_HEIGHT; y++) {
printf("|");
for (int x=0; x<SCREEN_WIDTH; x++) {
if (screen[x][y]==PIXEL_EMPTY) {
printf(" ");
} else if(screen[x][y]==PIXEL_BLOCK) {
printf("[]");
} else if (screen[x][y]==PIXEL_BALL) {
printf("<>");
} else if(screen[x][y]==PIXEL_PADDLE_MIDDLE) {
printf("==");
} else if(screen[x][y]==PIXEL_PADDLE_LEFT){
printf("<=");
} else if(screen[x][y]==PIXEL_PADDLE_RIGHT){
printf("=>");
}
}
printf("|\n");
}
for (int x =0; x<=SCREEN_WIDTH; x++) {
printf("--");
}
printf("\n");
//detect when ball hits the edge of the screen
if (ball.xPOS==0||ball.xPOS==(SCREEN_WIDTH-1)) {
ball.xVEL=ball.xVEL*-1;
}
if (ball.yPOS==0||ball.yPOS==(SCREEN_HEIGHT-1)) {
ball.yVEL=ball.yVEL*-1;
}
//detect when ball hits a block
if (screen[ball.xPOS+ball.xVEL][ball.yPOS]==PIXEL_BLOCK) {
blockArr[ball.xPOS+ball.xVEL][ball.yPOS].visable=false;
ball.xVEL = ball.xVEL *-1;
blockFlushHit=true;
}
if (screen[ball.xPOS][ball.yPOS+ball.yVEL]==PIXEL_BLOCK) {
blockArr[ball.xPOS][ball.yPOS+ball.yVEL].visable=false;
ball.yVEL = ball.yVEL *-1;
blockFlushHit=true;
}
if (screen[ball.xPOS+ball.xVEL][ball.yPOS+ball.yVEL]==PIXEL_BLOCK&&blockFlushHit==false) {
blockArr[ball.xPOS+ball.xVEL][ball.yPOS+ball.yVEL].visable=false;
if(ballOnXEdge(ball)==false) {
ball.xVEL = ball.xVEL *-1;
}
if (ball.yPOS!=0) {
ball.yVEL=ball.yVEL *-1;
}
}
//detect when ball hits paddle
if(screen[ball.xPOS+ball.xVEL][ball.yPOS]==PIXEL_PADDLE_MIDDLE) {
ball.xVEL = ball.xVEL *-1;
}
if (screen[ball.xPOS][ball.yPOS+ball.yVEL]== PIXEL_PADDLE_MIDDLE) { //hit detection y direction
ball.yVEL= ball.yVEL*-1;
}
if (screen[ball.xPOS+ball.xVEL][ball.yPOS+ball.yVEL]==PIXEL_PADDLE_MIDDLE) { //diagonal hit detection
ball.xVEL = ball.xVEL *-1;
ball.yVEL=ball.yVEL *-1;
}
//paddle left
if (screen[ball.xPOS+ball.xVEL][ball.yPOS+ball.yVEL]==PIXEL_PADDLE_LEFT) { //diagonal hit detection
if(ball.xVEL==-1){
ball.xVEL=-1;
} else if (ball.xVEL==0){
ball.xVEL=-1;
} else {
ball.xVEL=-1;
}
ball.yVEL=ball.yVEL *-1;
}
//paddle right
if (screen[ball.xPOS+ball.xVEL][ball.yPOS+ball.yVEL]==PIXEL_PADDLE_RIGHT) { //diagonal hit detection
if (ball.xVEL==-1){ //moving left
ball.xVEL=1;
} else if (ball.xVEL==0){ //moving straight down
ball.xVEL=1;
} else { //moving right
ball.xVEL=1;
}
ball.yVEL=ball.yVEL *-1;
}
//update ball position
ball.xPOS=ball.xPOS+ball.xVEL;
ball.yPOS= ball.yPOS+ball.yVEL;
}
}