Sitemap
G2P AKA Trigger

G2P AKA Trigger

Membangun Game Simulator AC-130 dengan HTML5 Canvas dan Web Audio API

3 min readOct 28, 2026

--

Mengembangkan game arcade shooter 2D dengan sudut pandang dari atas (top-down) sering kali menghadapi tantangan visual agar tidak terasa terlalu datar. Pada proyek Gunship Strike ini, saya menyimulasikan pengalaman menjadi operator senjata udara AC-130 ala Call of Duty: Modern Warfare 3 menggunakan HTML5 Canvas murni, JavaScript Vanilla, dan Web Audio API tanpa library eksternal.

Berikut adalah penjelasan arsitektur teknis dan beberapa fungsi utama yang membangun mekanisme game ini.

1. Sistem Kamera Mengorbit Otomatis (Auto Orbiting Camera)

Pesawat AC-130 Spectre bertugas mengelilingi area sasaran secara konstan dalam pola melingkar. Untuk menyimulasikan pergerakan ini pada viewport 2D, posisi kamera (cameraX, cameraY) dihitung menggunakan trigonometri dasar berdasarkan sudut putar pesawat yang terus bertambah.

JavaScript

function gameLoop() {
if (!isPlaying) return;
    // Pergerakan sudut orbit pesawat
flightAngle += orbitSpeed;
cameraX = (WORLD_SIZE / 2) + Math.cos(flightAngle) * orbitRadius;
cameraY = (WORLD_SIZE / 2) + Math.sin(flightAngle) * orbitRadius;
drawRenderWorld();
// ...
animationId = requestAnimationFrame(gameLoop);
}
  • WORLD_SIZE: Peta berukuran 4000x4000 piksel yang jauh lebih luas dari layar pemain.
  • flightAngle: Sudut rotasi yang diperbarui setiap frame untuk menentukan vektor pergeseran kamera mengelilingi titik pusat dunia.

2. Proyeksi Kedalaman Pseudo-3D dan Konversi Koordinat

Untuk memberikan efek tiga dimensi pada objek bangunan dan rumah di atas bidang 2D, koordinat world space diubah ke screen space. Selanjutnya, posisi dinding samping dihitung menggunakan offset proyeksi perpektif (parallax depth projection).

Get G2P AKA Trigger’s stories in your inbox

Join Medium for free to get updates from this writer.

JavaScript

// Konversi koordinat World ke Screen
function worldToScreen(wx, wy) {
return {
x: wx - cameraX + canvas.width / 2,
y: wy - cameraY + canvas.height / 2
};
}
// Proyeksi Dinding Gedung Pseudo-3D
const offX = (pos.x - canvas.width / 2) * (b.height3D / 500);
const offY = (pos.y - canvas.height / 2) * (b.height3D / 500);
ctx.fillStyle = b.wallColor;
ctx.beginPath();
ctx.moveTo(pos.x - b.w/2, pos.y - b.h/2);
ctx.lineTo(pos.x + b.w/2, pos.y - b.h/2);
ctx.lineTo(pos.x + b.w/2 + offX, pos.y - b.h/2 + offY);
ctx.lineTo(pos.x - b.w/2 + offX, pos.y - b.h/2 + offY);
ctx.fill();

Fungsi kalkulasi offX dan offY memanfaatkan jarak titik gedung dari pusat layar dikalikan atribut tinggi objek (height3D). Efek ini membuat dinding bangunan terlihat miring menjauhi pusat kamera secara dinamis saat pesawat mengorbit.

3. Urutan Layer Rendering untuk Occlusion

Penataan urutan gambar pada metode drawRenderWorld() sangat krusial untuk mencegah kecacatan visual seperti kendaraan yang melintas di atas atap gedung.

JavaScript

// Pipeline Rendering Berurutan
1. Terran & Sungai (Rivers)
2. Jalan Raya (Roads + Lane Markings)
3. Jembatan & Kawah Bekas Ledakan (Bridges & Craters)
4. Kendaraan Bergerak (Moving Targets)
5. Bangunan & Rumah Pseudo-3D (Buildings & Static Targets)
6. Partikel Ledakan & Serpihan (Particles)

Dengan menggambar MovingEntity sebelum buildings, kendaraan yang melintas tepat di sebelah gedung akan tertutup oleh proyeksi dinding 3D secara realistis.

4. Sintesis Efek Suara Prosedural (Web Audio API)

Game ini tidak menggunakan berkas audio eksternal (.mp3 atau .wav). Semua efek suara seperti tembakan, jeritan target, dan derau static radio dihasilkan secara prosedural menggunakan osilator dan modulasi noise buffer.

JavaScript

if (type === 'radio') {
const bufferSize = audioCtx.sampleRate * 0.35;
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
const data = buffer.getChannelData(0);

// Generasi White Noise
for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;
    const noise = audioCtx.createBufferSource();
noise.buffer = buffer;

// Bandpass Filter untuk karakteristik radio komunikasi
const filter = audioCtx.createBiquadFilter();
filter.type = 'bandpass';
filter.frequency.value = 1400;

noise.connect(filter);
filter.connect(gainNode);
noise.start();
}

Modulasi frekuensi pita pertengahan (bandpass filter) pada white noise acak menciptakan karakteristik suara transmisi radio militer yang khas tanpa perlu memuat aset audio tambahan.

Pengembangan game HTML5 Canvas tanpa engine pihak ketiga memberikan kendali penuh terhadap optimasi performa render loop dan pemrosesan sistem objek di layar.

Press enter or click to view image in full size

--

--