Sabtu, 02 Mei 2026

JAVA - Quadcopter Game 4

 



/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
 */
package quadcoptergame5;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.Timer;

public class QuadcopterGame5 extends JPanel implements ActionListener, KeyListener {
    Timer timer;
    int quadX = 400, quadY = 300;
    int score = 0;
    boolean gameOver = false;
    double angle = 0; // untuk rotasi baling-baling

    ArrayList<Rectangle> enemies = new ArrayList<>();
    ArrayList<Rectangle> missiles = new ArrayList<>();
    ArrayList<Rectangle> enemyMissiles = new ArrayList<>();
    Random rand = new Random();

    public QuadcopterGame5() {
        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.BLACK);
        timer = new Timer(30, this);
        timer.start();
        addKeyListener(this);
        setFocusable(true);

        // Buat 20 musuh acak
        for (int i = 0; i < 20; i++) {
            enemies.add(new Rectangle(rand.nextInt(700), rand.nextInt(500), 20, 20));
        }

        // Timer untuk musuh menembak setiap 1 detik
        new Timer(1000, e -> {
            if (!enemies.isEmpty()) {
                Rectangle enemy = enemies.get(rand.nextInt(enemies.size()));
                enemyMissiles.add(new Rectangle(enemy.x, enemy.y, 5, 10));
            }
        }).start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        if (gameOver) {
            g.setColor(Color.RED);
            g.setFont(new Font("Arial", Font.BOLD, 40));
            g.drawString("GAME OVER", 300, 300);
            return;
        }

        // Gambar quadcopter (badan + 4 baling-baling berputar)
        g.setColor(Color.CYAN);
        g.drawOval(quadX, quadY, 30, 30);

        int cx = quadX + 15, cy = quadY + 15;
        int radius = 40;
        for (int i = 0; i < 4; i++) {
            double theta = angle + i * Math.PI / 2;
            int x = (int)(cx + radius * Math.cos(theta));
            int y = (int)(cy + radius * Math.sin(theta));
            //g.drawLine(cx, cy, x, y);
            g.drawOval(x-10, y-10, 20, 20);
        }

        // Gambar musuh
        g.setColor(Color.GREEN);
        for (Rectangle enemy : enemies) {
            g.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
        }

        // Gambar misil quadcopter
        g.setColor(Color.YELLOW);
        for (Rectangle m : missiles) {
            g.fillRect(m.x, m.y, m.width, m.height);
        }

        // Gambar misil musuh
        g.setColor(Color.RED);
        for (Rectangle em : enemyMissiles) {
            g.fillRect(em.x, em.y, em.width, em.height);
        }

        // Skor
        g.setColor(Color.WHITE);
        g.drawString("Score: " + score, 10, 20);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        angle += 0.1; // rotasi baling-baling

        // Update posisi misil quadcopter
        for (Rectangle m : missiles) {
            m.y -= 10;
        }
        missiles.removeIf(m -> m.y < 0);

        // Update posisi musuh (bergerak acak halus)
        for (Rectangle enemy : enemies) {
            enemy.x += rand.nextInt(3) - 1;
            enemy.y += rand.nextInt(3) - 1;
            if (enemy.x < 0) enemy.x = 0;
            if (enemy.y < 0) enemy.y = 0;
            if (enemy.x > 780) enemy.x = 780;
            if (enemy.y > 580) enemy.y = 580;
        }

        // Update misil musuh
        for (Rectangle em : enemyMissiles) {
            em.y += 5;
            if (em.intersects(new Rectangle(quadX, quadY, 30, 30))) {
                gameOver = true;
            }
        }

        // Cek tabrakan misil dengan musuh
        Iterator<Rectangle> itM = missiles.iterator();
        while (itM.hasNext()) {
            Rectangle m = itM.next();
            Iterator<Rectangle> itE = enemies.iterator();
            while (itE.hasNext()) {
                Rectangle enemy = itE.next();
                if (m.intersects(enemy)) {
                    itM.remove();
                    itE.remove();
                    score++;
                    break;
                }
            }
        }

        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (gameOver) return;
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_W) quadY -= 10;
        if (key == KeyEvent.VK_S) quadY += 10;
        if (key == KeyEvent.VK_A) quadX -= 10;
        if (key == KeyEvent.VK_D) quadX += 10;
        if (key == KeyEvent.VK_SPACE) {
            missiles.add(new Rectangle(quadX+10, quadY, 5, 10));
        }
    }

    @Override public void keyReleased(KeyEvent e) {}
    @Override public void keyTyped(KeyEvent e) {}

    public static void main(String[] args) {
        JFrame frame = new JFrame("Quadcopter Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new QuadcopterGame5());
        frame.pack();
        frame.setVisible(true);
    }
}




Tidak ada komentar: