Technical Implementation Details

Real-Time Event Handling:

const unwatchBombs = client.watchContractEvent({
  address: CONTRACT_ADDRESS,
  abi: CONTRACT_ABI,
  eventName: "AreaBombed",
  onLogs: (logs) => {
    for (const log of logs) {
      const { x, y, radius } = log.args;
      // Update canvas state in real-time
      // Update animation Rocket and Boom
      clearPixelArea(Number(x), Number(y), Number(radius));
    }
  }
});

Listen event on blockchain confirm and handle event on game play.

Rocket Strike Logic Explanation:

//Rocket Interface and Thruster Particle
interface Rocket {
  x: number;          // position X
  y: number;          // position Y  
  dx: number;         // Velocity X 
  dy: number;         // Velocity Y 
  angle: number;      //  (degrees)
  trail: TrailPoint[]; // Array TrailPoint
  thrusterParticles: ThrusterParticle[]; // Particles
}
interface ThrusterParticle {
  x, y: number;       
  dx, dy: number;     
  life: number;       
  maxLife: number;
  size: number;       
}

Target Vector Calculation:

// Caculation spawn point to target
const deltaX = targetX - startX;
const deltaY = targetY - startY;
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

// Normalize vector and apply speed
const speed = 1;
const dx = (deltaX / distance) * speed; // Unit vector * speed
const dy = (deltaY / distance) * speed;

// Caculation angle rocket sprite
const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);

Trail System:

const newTrail = [
  { x: prev.x, y: prev.y, opacity: 1 },    // Current position
  ...prev.trail.map(t => ({
    ...t,
    opacity: t.opacity * 0.9               // Fade existing trail points
  }))
].slice(0, 8);                            // Keep only 8 recent points
.filter(t => t.opacity > 0.1);

More details in my project on github

Last updated