In this project, we will build an exciting AI Hand Gesture Shooting Game using Python, OpenCV, and MediaPipe. Instead of using a mouse, you will control the crosshair with your finger and shoot using a pinch gesture ๐ค.
๐งฐ 1. Hardware Required
- ๐ป Laptop / PC (Windows recommended)
- ๐ท ESP32-CAM Module (Recommended for smart AI projects)
- ๐ USB to TTL Converter (for programming ESP32-CAM)
- ⚡ Jumper Wires
- ๐ถ WiFi Connection
๐ Recommended Module: ESP32-CAM (OV2640 Camera)
๐ 2. Python Libraries Required
Open Command Prompt and install the following libraries:
pip install opencv-python mediapipe
That’s it! Now you're ready to run the AI game ๐
๐ง 3. Complete Python Code
import cv2
import mediapipe as mp
import random
import math
import time
# =============================
# SETUP HAND TRACKING
# =============================
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1)
mp_draw = mp.solutions.drawing_utils
cap = cv2.VideoCapture(0)
# Fullscreen mode
cv2.namedWindow("AI Shooting Game", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("AI Shooting Game", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
# =============================
# GAME VARIABLES
# =============================
score = 0
disc_radius = 30
disc_speed = 6
disc_x = 0
disc_y = 200
last_shot_time = 0
cooldown = 0.5 # time between shots
# Create new disc
def new_disc(width, height):
x = 0
y = random.randint(100, height - 100)
return x, y
# =============================
# MAIN LOOP
# =============================
while True:
success, frame = cap.read()
if not success:
break
frame = cv2.flip(frame, 1)
height, width, _ = frame.shape
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = hands.process(rgb)
cross_x = width // 2
cross_y = height // 2
shoot = False
# =============================
# HAND DETECTION
# =============================
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
landmarks = hand_landmarks.landmark
# INDEX FINGER TIP (8)
index_tip = landmarks[8]
cross_x = int(index_tip.x * width)
cross_y = int(index_tip.y * height)
# THUMB TIP (4)
thumb_tip = landmarks[4]
thumb_x = int(thumb_tip.x * width)
thumb_y = int(thumb_tip.y * height)
# Draw green circle on index
cv2.circle(frame, (cross_x, cross_y), 12, (0, 255, 0), -1)
# Draw blue circle on thumb
cv2.circle(frame, (thumb_x, thumb_y), 12, (255, 0, 0), -1)
# -------- PINCH DETECTION --------
distance = math.sqrt((cross_x - thumb_x)**2 +
(cross_y - thumb_y)**2)
if distance < 40: # Sensitivity
current_time = time.time()
if current_time - last_shot_time > cooldown:
shoot = True
last_shot_time = current_time
# =============================
# DISC MOVEMENT
# =============================
disc_x += disc_speed
if disc_x > width:
disc_x, disc_y = new_disc(width, height)
# Draw flying disc
cv2.circle(frame, (disc_x, disc_y), disc_radius, (255, 200, 0), -1)
cv2.circle(frame, (disc_x, disc_y), disc_radius, (0, 0, 0), 3)
# =============================
# SHOOT CHECK
# =============================
if shoot:
distance_to_disc = math.sqrt((cross_x - disc_x)**2 +
(cross_y - disc_y)**2)
if distance_to_disc < disc_radius:
score += 1
disc_x, disc_y = new_disc(width, height)
# Small shoot flash
cv2.putText(frame, "SHOOT!",
(cross_x - 40, cross_y - 40),
cv2.FONT_HERSHEY_SIMPLEX,
1,
(0, 255, 255),
3)
# =============================
# DRAW RED CROSSHAIR
# =============================
cv2.line(frame, (cross_x - 20, cross_y),
(cross_x + 20, cross_y), (0, 0, 255), 2)
cv2.line(frame, (cross_x, cross_y - 20),
(cross_x, cross_y + 20), (0, 0, 255), 2)
cv2.circle(frame, (cross_x, cross_y), 8, (0, 0, 255), 2)
# =============================
# DISPLAY SCORE
# =============================
cv2.putText(frame, "Score: " + str(score),
(50, 70),
cv2.FONT_HERSHEY_SIMPLEX,
1.5,
(0, 255, 0),
3)
cv2.imshow("AI Shooting Game", frame)
# ESC to exit
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()
๐ 4. Code Explanation (Block by Block)
๐ Import Libraries
import cv2 import mediapipe as mp import random import math import time
✅ cv2 → Used for video processing ✅ mediapipe → Used for hand tracking ✅ random → To generate random disc positions ✅ math → For distance calculation ✅ time → For shooting cooldown system
๐ Setup Hand Tracking
mp_hands = mp.solutions.hands hands = mp_hands.Hands(max_num_hands=1) mp_draw = mp.solutions.drawing_utils
This initializes MediaPipe Hand Detection. We detect only one hand for better performance.
๐ Game Variables
score = 0 disc_radius = 30 disc_speed = 6
๐ฏ score → Stores player score ๐ฏ disc_radius → Size of target ๐ฏ disc_speed → Speed of flying disc
๐ Pinch Detection (Shoot Logic)
distance = math.sqrt((cross_x - thumb_x)**2 +
(cross_y - thumb_y)**2)
if distance < 40:
shoot = True
๐ค When thumb and index finger come close, distance becomes small → system triggers SHOOT.
๐ Disc Movement
disc_x += disc_speed
if disc_x > width:
disc_x, disc_y = new_disc(width, height)
The disc keeps moving horizontally. If it goes outside the screen → new disc appears randomly.
๐ Hit Detection
if distance_to_disc < disc_radius:
score += 1
If crosshair touches disc → Score increases ๐
๐ฎ How the Game Works
- ๐ Move index finger to control crosshair
- ๐ Pinch thumb + index to shoot
- ๐ Hit the flying disc
- ๐ Score increases
- ๐ Press ESC to exit
๐ Why Use ESP32-CAM?
- ๐ท Low cost AI camera module
- ๐ถ Wireless streaming
- ๐ค Perfect for robotics projects
- ๐ Ideal for school & college AI demos
๐ Get your ESP32-CAM here: ๐ฅ Buy ESP32-CAM Now
๐ก Future Improvements
- ๐ซ Add gun sound effects
- ๐ฏ Add multiple targets
- ⏱ Add timer mode
- ๐ Add leaderboard
๐ข Final Words
This project is perfect for students learning AI + Computer Vision + Python. If you enjoyed this tutorial, share it with your friends and try building it using ESP32-CAM for advanced learning!
Happy Coding ๐
Comments