#include "fb.h" #include "io.h" // The screen #define WIDTH 1920 #define HEIGHT 1080 #define MARGIN 75 #define VIRTWIDTH (WIDTH-(2*MARGIN)) #define FONT_BPG 8 // For the bricks #define ROWS 5 #define COLS 10 unsigned int bricks = ROWS * COLS; // Gameplay #define NUM_LIVES 3 // OBJECT TRACKING struct Object { unsigned int type; unsigned int x; unsigned int y; unsigned int width; unsigned int height; unsigned char alive; }; enum { OBJ_NONE = 0, OBJ_BRICK = 1, OBJ_PADDLE = 2, OBJ_BALL = 3 }; unsigned int numobjs = 0; struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)]; struct Object *ball; struct Object *paddle; void removeObject(struct Object *object) { drawRect(object->x, object->y, object->x + object->width, object->y + object->height, 0, 1); object->alive = 0; } void moveObject(struct Object *object, int xoff, int yoff) { moveRect(object->x, object->y, object->width, object->height, xoff, yoff, 0x00); object->x = object->x + xoff; object->y = object->y + yoff; } struct Object *objectAt(unsigned int x, unsigned int y) { for (int i=0; i= objects[i].x && x <= objects[i].x + objects[i].width) { if (y >= objects[i].y && y <= objects[i].y + objects[i].height) { if (&objects[i] != ball && objects[i].alive == 1) { return &objects[i]; } } } } return 0; } struct Object *detectCollision(int xoff, int yoff) { struct Object *collision; unsigned int x = ball->x + xoff; unsigned int y = ball->y + yoff; collision = objectAt(x,y); if (collision) return collision; collision = objectAt(x + ball->width, y); if (collision) return collision; collision = objectAt(x, y + ball->height); if (collision) return collision; collision = objectAt(x + ball->width, y + ball->height); if (collision) return collision; return 0; } // KEY HANDLER unsigned char getUart() { unsigned char ch = 0; if (uart_isReadByteReady()) ch = uart_readByte(); return ch; } // OBJECT INITIALISERS void initBricks() { int brickwidth = 32; int brickheight = 8; int brickspacer = 20; int brickcols[5] = { 0x01, 0x02, 0x0E, 0x04, 0x06 }; int ybrick = MARGIN + brickheight; for (int i=0; i 0 && bricks > 0) { // Get any waiting input and flush the buffer if ( ( ch = getUart() ) ) { if (ch == 'l') if (paddle->x + paddle->width + (paddle->width / 2) <= WIDTH-MARGIN) moveObject(paddle, paddle->width / 2, 0); if (ch == 'h') if (paddle->x >= MARGIN+(paddle->width / 2)) moveObject(paddle, -(paddle->width / 2), 0); } uart_loadOutputFifo(); // Are we going to hit anything? foundObject = detectCollision(velocity_x, velocity_y); if (foundObject) { if (foundObject == paddle) { velocity_y = -velocity_y; // Are we going to hit the side of the paddle if (ball->x + ball->width + velocity_x == paddle->x || ball->x + velocity_x == paddle->x + paddle->width) velocity_x = -velocity_x; } else if (foundObject->type == OBJ_BRICK) { removeObject(foundObject); velocity_y = -velocity_y; bricks--; points++; drawScoreboard(points, lives); } } wait_msec(4000); // Wait for a tenth of a second moveObject(ball, velocity_x, velocity_y); // Check we're in the game arena still if (ball->x + ball->width >= WIDTH-MARGIN) { velocity_x = -velocity_x; } else if (ball->x <= MARGIN) { velocity_x = -velocity_x; } else if (ball->y + ball->height >= HEIGHT-MARGIN) { lives--; removeObject(ball); removeObject(paddle); initBall(); initPaddle(); drawScoreboard(points, lives); } else if (ball->y <= MARGIN) { velocity_y = -velocity_y; } } int zoom = WIDTH/192; int strwidth = 10 * FONT_BPG * zoom; int strheight = FONT_BPG * zoom; if (bricks == 0) drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Well done!", 0x02, zoom); else drawString((WIDTH/2)-(strwidth/2), (HEIGHT/2)-(strheight/2), "Game over!", 0x04, zoom); }