GDG Logo

Game Dev with React Workshop

Bullet Component

The Bullet component manages individual bullets in the game, handling their display and collision detection with obstacles. Each bullet can destroy obstacles and increase the player's score.

1. File Declaration and Imports

import { useAtom } from 'jotai';
import React, { useEffect } from 'react';
import { bulletsAtom, obstaclesAtom, scoreAtom } from '../store/atom';

File setup and imports: - `useAtom` from Jotai for state management - React and useEffect for component functionality - Three state atoms for managing bullets, obstacles, and score

2. Component Declaration and State Setup

const Bullet = ({ x, y, id }) => {
  const [, setObstacles] = useAtom(obstaclesAtom);
  const [, setBullets] = useAtom(bulletsAtom);
  const [, setScore] = useAtom(scoreAtom);

Component initialization: - Receives x, y coordinates and unique id as props - Sets up state setters using Jotai's useAtom - Only destructures setters as we don't need the state values directly

3. Collision Detection Effect

  useEffect(() => {
    const checkBulletCollision = () => {
      setObstacles(prevObstacles => 
        prevObstacles.filter(obstacle => {
          const collision = 
            x < obstacle.x + 20 &&
            x + 4 > obstacle.x &&
            y < obstacle.y + 20 &&
            y + 10 > obstacle.y;
          
          if (collision) {
            setBullets(prev => prev.filter(bullet => bullet.id !== id));
            setScore(prev => prev + 10);
            return false;
          }
          return true;
        })
      );
    };

    const collisionInterval = setInterval(checkBulletCollision, 16);
    return () => clearInterval(collisionInterval);
  }, [x, y, id, setBullets, setObstacles, setScore]);

Collision detection implementation: - Sets up continuous collision checking at 60 FPS (16ms intervals) - Checks for overlap between bullet and obstacles using precise dimensions: • Bullet: 4px width, 10px height • Obstacle: 20px width, 20px height - On collision: • Removes the bullet from game state • Increases score by 10 points • Removes the hit obstacle - Includes cleanup function to prevent memory leaks - Dependencies track position changes and state setters

4. Component Render

  return (
    <div 
      className="bullet"
      style={{ 
        left: `${x}px`,
        top: `${y}px`
      }}
    />
  );
};

export default Bullet;

Component rendering: - Renders a div with 'bullet' class for styling - Positions bullet using absolute positioning with x, y coordinates - Exports component for use in GameBoard