Monday, January 13, 2025

Space Shooter Game Lilygo TTGO ESP32

 

Untuk bermain permainan ini, korang memerlukan 2 butang untuk mengawal pesawat angkasa.

Manakala tembakannya adalah auto, so kita hanya perlu kawal sahaja.

Untuk sambung 2 butang kawalan kiri kanan tu, 

- sambung butang ke pin GPIO0 (kiri) dan GPIO35 (kanan)

dan pastikan kedua-dua butang itu di gnd kan. Dalam video di bawah saya tiada butang tu.

Maka saya tap sajalah... hahahaha.


jika berminat, dibawah ini adalah scriptnya. have fun!!!.

-------------------------------------------------------------------------------------------------------------------

#include <Wire.h>

#include <SPI.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>


#define OLED_MOSI   21    

#define OLED_CLK    22    

#define OLED_DC     15    

#define OLED_CS     13    

#define OLED_RESET  14    

#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

#define BUTTON_LEFT 0     // Butang kiri (GPIO0)

#define BUTTON_RIGHT 35   // Butang kanan (GPIO35)


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, 

  OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);


// Struktur untuk pesawat pemain

struct Player {

  int x = SCREEN_WIDTH/2;

  int y = SCREEN_HEIGHT-10;

  int width = 8;

  int height = 8;

  int score = 0;

  int lives = 3;

};


// Struktur untuk peluru

struct Bullet {

  int x = -1;

  int y = -1;

  bool active = false;

};


// Struktur untuk musuh

struct Enemy {

  int x;

  int y;

  bool active = false;

};


Player player;

Bullet bullet;

Enemy enemies[3];

unsigned long lastEnemySpawn = 0;

unsigned long lastBulletFired = 0;


void setup() {

  Serial.begin(115200);

  

  // Setup butang

  pinMode(BUTTON_LEFT, INPUT_PULLUP);

  pinMode(BUTTON_RIGHT, INPUT_PULLUP);

  

  if (!display.begin(SSD1306_SWITCHCAPVCC)) {

    Serial.println(F("OLED initialization failed"));

    while (1);

  }

  

  // Mulakan permainan

  initGame();

}


void initGame() {

  display.clearDisplay();

  display.setTextSize(1);

  display.setTextColor(SSD1306_WHITE);

  

  // Reset kedudukan musuh

  for(int i = 0; i < 3; i++) {

    enemies[i].active = false;

  }

  

  // Reset pemain

  player.x = SCREEN_WIDTH/2;

  player.score = 0;

  player.lives = 3;

}


void loop() {

  // Baca input

  handleInput();

  

  // Update game state

  updateGame();

  

  // Lukis skrin

  drawGame();

  

  delay(50);

}


void handleInput() {

  // Gerakkan pemain ke kiri

  if(digitalRead(BUTTON_LEFT) == LOW) {

    player.x = max(player.width/2, player.x - 2);

  }

  

  // Gerakkan pemain ke kanan

  if(digitalRead(BUTTON_RIGHT) == LOW) {

    player.x = min(SCREEN_WIDTH - player.width/2, player.x + 2);

  }

  

  // Tembak peluru (automatik)

  if(!bullet.active && millis() - lastBulletFired > 500) {

    bullet.x = player.x;

    bullet.y = player.y - 5;

    bullet.active = true;

    lastBulletFired = millis();

  }

}


void updateGame() {

  // Update peluru

  if(bullet.active) {

    bullet.y -= 3;

    if(bullet.y < 0) bullet.active = false;

  }

  

  // Spawn musuh baharu

  if(millis() - lastEnemySpawn > 2000) {

    for(int i = 0; i < 3; i++) {

      if(!enemies[i].active) {

        enemies[i].x = random(10, SCREEN_WIDTH-10);

        enemies[i].y = 0;

        enemies[i].active = true;

        lastEnemySpawn = millis();

        break;

      }

    }

  }

  

  // Update musuh

  for(int i = 0; i < 3; i++) {

    if(enemies[i].active) {

      enemies[i].y += 1;

      

      // Periksa perlanggaran dengan peluru

      if(bullet.active && 

         abs(bullet.x - enemies[i].x) < 8 && 

         abs(bullet.y - enemies[i].y) < 8) {

        enemies[i].active = false;

        bullet.active = false;

        player.score += 10;

      }

      

      // Periksa perlanggaran dengan pemain

      if(abs(enemies[i].x - player.x) < 8 && 

         abs(enemies[i].y - player.y) < 8) {

        enemies[i].active = false;

        player.lives--;

        if(player.lives <= 0) {

          initGame();

          return;

        }

      }

      

      // Reset musuh jika keluar skrin

      if(enemies[i].y > SCREEN_HEIGHT) {

        enemies[i].active = false;

      }

    }

  }

}


void drawGame() {

  display.clearDisplay();

  

  // Lukis pemain

  display.fillTriangle(

    player.x, player.y - 4,

    player.x - 4, player.y + 4,

    player.x + 4, player.y + 4,

    SSD1306_WHITE);

  

  // Lukis peluru

  if(bullet.active) {

    display.drawPixel(bullet.x, bullet.y, SSD1306_WHITE);

  }

  

  // Lukis musuh

  for(int i = 0; i < 3; i++) {

    if(enemies[i].active) {

      display.drawRect(enemies[i].x - 4, enemies[i].y - 4, 8, 8, SSD1306_WHITE);

    }

  }

  

  // Papar skor dan nyawa

  display.setCursor(0,0);

  display.print("Score:");

  display.print(player.score);

  

  display.setCursor(SCREEN_WIDTH-30,0);

  for(int i = 0; i < player.lives; i++) {

    display.print("<3 ");

  }

  

  display.display();

}

-------------------------------------------------------------------------------------------------------------------------

Space Shooter Game Lilygo TTGO ESP32

  Untuk bermain permainan ini, korang memerlukan 2 butang untuk mengawal pesawat angkasa. Manakala tembakannya adalah auto, so kita hanya pe...