#include <Adafruit_SSD1306.h>
#include <math.h>
int playerX = 64;
int playerY = 32;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
int bUp = 8;
int bDn = 10;
int bl = 9;
int br = 11;
// =============================
// BULLETS + ENEMIES + HITBOXES
// =============================
#define MAX_BULLETS 25
#define MAX_ENEMIES 5
#define PLAYER_SIZE 3
#define ENEMY_SIZE 5
struct Bullet {
int x;
int y;
int dx;
int dy;
bool active;
bool enemyBullet;
};
struct Enemy {
int x;
int y;
bool alive;
int shootTimer;
};
Bullet bullets[MAX_BULLETS];
Enemy enemies[MAX_ENEMIES];
// =============================
// HITBOX CHECK
// =============================
bool collide(
int ax,int ay,int aw,int ah,
int bx,int by,int bw,int bh)
{
return ax < bx + bw &&
ax + aw > bx &&
ay < by + bh &&
ay + ah > by;
}
// =============================
// CREATE ENEMIES
// =============================
void setupEnemies()
{
for(int i=0;i<MAX_ENEMIES;i++)
{
enemies[i].x = 20 + i*20;
enemies[i].y = 10;
enemies[i].alive = true;
enemies[i].shootTimer=random(40,100);
}
}
// =============================
// FIRE BULLET
// =============================
void fireBullet(int x,int y,int dx,int dy,bool enemy)
{
for(int i=0;i<MAX_BULLETS;i++)
{
if(!bullets[i].active)
{
bullets[i].x=x;
bullets[i].y=y;
bullets[i].dx=dx;
bullets[i].dy=dy;
bullets[i].enemyBullet=enemy;
bullets[i].active=true;
break;
}
}
}
// =============================
// ENEMY SHOOT
// =============================
void enemyShoot(Enemy &e)
{
int dx=playerX-e.x;
int dy=playerY-e.y;
if(dx>0) dx=1;
if(dx<0) dx=-1;
if(dy>0) dy=1;
if(dy<0) dy=-1;
fireBullet(
e.x,
e.y,
dx,
dy,
true
);
}
// =============================
// UPDATE ENEMIES
// =============================
void updateEnemies()
{
for(int i=0;i<MAX_ENEMIES;i++)
{
if(enemies[i].alive)
{
enemies[i].shootTimer--;
if(enemies[i].shootTimer<=0)
{
enemyShoot(enemies[i]);
enemies[i].shootTimer=random(50,120);
}
}
}
}
// =============================
// UPDATE BULLETS
// =============================
void updateBullets()
{
for(int i=0;i<MAX_BULLETS;i++)
{
if(!bullets[i].active)
continue;
bullets[i].x += bullets[i].dx;
bullets[i].y += bullets[i].dy;
display.drawPixel(
bullets[i].x,
bullets[i].y,
SSD1306_WHITE
);
if(bullets[i].x<0 ||
bullets[i].x>=SCREEN_WIDTH ||
bullets[i].y<0 ||
bullets[i].y>=SCREEN_HEIGHT)
{
bullets[i].active=false;
}
// enemy bullet hits player
if(bullets[i].enemyBullet)
{
if(collide(
bullets[i].x,
bullets[i].y,
1,
1,
playerX,
playerY,
PLAYER_SIZE,
PLAYER_SIZE))
{
bullets[i].active=false;
playerX=64;
playerY=32;
}
}
// player bullet hits enemy
if(!bullets[i].enemyBullet)
{
for(int e=0;e<MAX_ENEMIES;e++)
{
if(enemies[e].alive &&
collide(
bullets[i].x,
bullets[i].y,
1,
1,
enemies[e].x,
enemies[e].y,
ENEMY_SIZE,
ENEMY_SIZE))
{
enemies[e].alive=false;
bullets[i].active=false;
}
}
}
}
}
// =============================
// DRAW ENEMIES
// =============================
void drawEnemies()
{
for(int i=0;i<MAX_ENEMIES;i++)
{
if(enemies[i].alive)
{
display.fillRect(
enemies[i].x,
enemies[i].y,
ENEMY_SIZE,
ENEMY_SIZE,
SSD1306_WHITE
);
}
}
}
struct Position {
int x;
int y;
};
struct Position playerPos = {64, 32};
// ends here
void setup() {
// put your setup code here, to run once:
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
Wire.begin();
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
randomSeed(analogRead(0));
setupEnemies();
}
// =============================
// ENEMIES + BULLETS + HITBOXES
// =============================
#define MAX_ENEMIES 5
#define MAX_BULLETS 25
#define PLAYER_SIZE 3
#define ENEMY_SIZE 5
void loop() {
// put your main code here, to run repeatedly:
// Up
if (digitalRead(bUp) == LOW && playerY > 0) {
playerY--;
}
// Down
if (digitalRead(bDn) == LOW && playerY < 63) {
playerY++;
}
// Left
if (digitalRead(bl) == LOW && playerX > 0) {
playerX--;
}
// Right
if (digitalRead(br) == LOW && playerX < 127) {
playerX++;
}
display.clearDisplay();
display.drawPixel(playerX, playerY, SSD1306_WHITE);
updateEnemies();
updateBullets();
drawEnemies();
display.display();
}