/*
* 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 quadcoptergame4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.Random;
public class QuadcopterGame4 extends JPanel implements ActionListener, KeyListener {
// Game Constants
private final int WIDTH = 800;
private final int HEIGHT = 600;
private Timer timer;
private int score = 0;
private boolean gameOver = false;
// Player Properties
private double playerX = 400, playerY = 300;
private double playerSpeed = 5;
private double rotorAngle = 0;
// Game Entities
private ArrayList<Point2D.Double> playerMissiles = new ArrayList<>();
private ArrayList<Enemy> enemies = new ArrayList<>();
private ArrayList<Point2D.Double> enemyMissiles = new ArrayList<>();
private Random rand = new Random();
public QuadcopterGame4() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
// Initialize 20 enemies
for (int i = 0; i < 20; i++) {
enemies.add(new Enemy(rand.nextInt(WIDTH), rand.nextInt(HEIGHT)));
}
// Game Loop (approx 60 FPS)
timer = new Timer(16, this);
timer.start();
// Enemy firing timer (every 2 seconds)
Timer fireTimer = new Timer(2000, e -> {
if (!enemies.isEmpty() && !gameOver) {
Enemy shooter = enemies.get(rand.nextInt(enemies.size()));
enemyMissiles.add(new Point2D.Double(shooter.x, shooter.y));
}
});
fireTimer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (gameOver) {
g2.setColor(Color.RED);
g2.setFont(new Font("Arial", Font.BOLD, 50));
g2.drawString("GAME OVER", WIDTH/2 - 150, HEIGHT/2);
g2.setFont(new Font("Arial", Font.PLAIN, 20));
g2.drawString("Final Score: " + score, WIDTH/2 - 60, HEIGHT/2 + 40);
return;
}
// Draw Score
g2.setColor(Color.WHITE);
g2.drawString("Score: " + score, 20, 30);
// Draw Player (Quadcopter)
drawQuadcopter(g2, playerX, playerY);
// Draw Player Missiles
g2.setColor(Color.YELLOW);
for (Point2D.Double m : playerMissiles) g2.fill(new Ellipse2D.Double(m.x, m.y, 5, 5));
// Draw Enemies
g2.setColor(Color.RED);
for (Enemy e : enemies) g2.fill(new Rectangle2D.Double(e.x, e.y, 20, 20));
// Draw Enemy Missiles
g2.setColor(Color.ORANGE);
for (Point2D.Double m : enemyMissiles) g2.fill(new Ellipse2D.Double(m.x, m.y, 8, 8));
}
private void drawQuadcopter(Graphics2D g2, double x, double y) {
g2.setColor(Color.CYAN);
rotorAngle += 0.5; // Spin speed
// Draw 4 Spokes and Rotors
int[][] offsets = {{-20,-20}, {20,-20}, {-20,20}, {20,20}};
for (int[] offset : offsets) {
double rx = x + offset[0];
double ry = y + offset[1];
g2.draw(new Line2D.Double(x, y, rx, ry));
// Spinning rotor effect
AffineTransform old = g2.getTransform();
g2.translate(rx, ry);
g2.rotate(rotorAngle);
g2.draw(new Ellipse2D.Double(-10, -10, 20, 20));
g2.draw(new Line2D.Double(-10, 0, 10, 0)); // Spoke inside rotor
g2.setTransform(old);
}
g2.fill(new Ellipse2D.Double(x-10, y-10, 20, 20)); // Body
}
@Override
public void actionPerformed(ActionEvent e) {
if (gameOver) return;
// Move Player Missiles
for (int i = 0; i < playerMissiles.size(); i++) {
playerMissiles.get(i).y -= 10;
if (playerMissiles.get(i).y < 0) playerMissiles.remove(i);
}
// Move Enemy Missiles
for (int i = 0; i < enemyMissiles.size(); i++) {
enemyMissiles.get(i).y += 5;
// Check Collision with Player
if (enemyMissiles.get(i).distance(playerX, playerY) < 20) gameOver = true;
if (enemyMissiles.get(i).y > HEIGHT) enemyMissiles.remove(i);
}
// Move Enemies and Check Collision
for (int i = 0; i < enemies.size(); i++) {
Enemy en = enemies.get(i);
en.update();
// Check Player Missile hit Enemy
for (int j = 0; j < playerMissiles.size(); j++) {
if (playerMissiles.get(j).distance(en.x, en.y) < 20) {
enemies.remove(i);
playerMissiles.remove(j);
score += 10;
break;
}
}
}
repaint();
}
// Controls
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_W) playerY -= playerSpeed;
if (key == KeyEvent.VK_S) playerY += playerSpeed;
if (key == KeyEvent.VK_A) playerX -= playerSpeed;
if (key == KeyEvent.VK_D) playerX += playerSpeed;
if (key == KeyEvent.VK_SPACE) playerMissiles.add(new Point2D.Double(playerX, playerY));
}
// Inner class for Enemy behavior
class Enemy {
double x, y, dx, dy;
Enemy(double x, double y) {
this.x = x; this.y = y;
this.dx = (rand.nextDouble() - 0.5) * 4;
this.dy = (rand.nextDouble() - 0.5) * 4;
}
void update() {
x += dx; y += dy;
if (x < 0 || x > WIDTH) dx *= -1;
if (y < 0 || y > HEIGHT) dy *= -1;
}
}
// Boilers
@Override public void keyReleased(KeyEvent e) {}
@Override public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
JFrame frame = new JFrame("Quadcopter Combat");
QuadcopterGame4 game = new QuadcopterGame4();
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}