Vibe Coding: สร้างเกม Breakout สุดคลาสสิกด้วยพลัง AI เอเจนท์

Vibe coding คือวิธีการสร้างซอฟต์แวร์รูปแบบใหม่ที่แท้จริง ไม่ใช่แค่การเปลี่ยนชื่อเรียกเดิมๆ โดยคำนี้ถูกนิยามขึ้นโดย Andrej Karpathy ในต้นปี 2025 เพื่ออธิบายกระบวนการที่เราบอกความต้องการด้วยภาษาธรรมชาติ แล้วปล่อยให้เอเจนท์ AI จัดการทั้งการเขียนโค้ด การรัน และการปรับแก้แทนการพิมพ์เองทุกบรรทัด
ความนิยมของคำนี้พุ่งสูงจนพจนานุกรม Collins ยกให้เป็น คำแห่งปีสำหรับปี 2025 และภายในปี 2026 วิธีนี้ได้กลายเป็นมาตรฐานใหม่ในการสร้างซอฟต์แวร์จริงในอุตสาหกรรมไปแล้ว
บทความนี้จะพาคุณไปทำโปรเจกต์ vibe coding ของจริง ตั้งแต่เริ่มต้นจนจบด้วยการสร้างเกมอาร์เคด Breakout โดยใช้ AI ช่วยสร้างทุกส่วน พร้อมอธิบายโค้ดและทดสอบระบบฟิสิกส์การชน เงื่อนไขการชนะและแพ้ เพื่อยืนยันว่าโค้ดทุกบรรทัดทำงานได้สมบูรณ์ ไม่ใช่แค่การคาดเดา
Vibe Coding คืออะไร?
คำอธิบายเชิงกลไกนั้นง่ายมาก คือคุณบอกเป้าหมาย แล้วเอเจนท์ AI จะสร้างโค้ดตามนั้น คุณเพียงตรวจสอบและปรับปรุงซ้ำจนกว่าจะพอใจ สิ่งที่เปลี่ยนไปคือความฉลาดของเอเจนท์ในปัจจุบันที่ไม่ได้ทำแค่เติมคำ (autocomplete) แต่สามารถอ่านโปรเจกต์ทั้งหมด แก้ไขไฟล์ รันโค้ด และซ่อมแซมจุดที่พังได้เอง แม้แต่บริษัทระดับโลกอย่าง Airbnb ยัง รายงานว่าขณะนี้ AI เขียนโค้ดใหม่ประมาณ 60% ของโค้ดทั้งหมด
เครื่องมือยอดนิยมในปัจจุบันที่ควรเลือกใช้มีดังนี้:
- Claude Code เอเจนท์บนเทอร์มินัลที่เหมาะกับการเขียนและทดสอบโค้ดในโฟลเดอร์โปรเจกต์โดยตรง
- Cursor เอดิเตอร์ที่สร้างมาเพื่อ AI โดยเฉพาะ สำหรับผู้ที่ต้องการพลังใน IDE ที่คุ้นเคย
- Replit Agent เหมาะสำหรับมือใหม่ เพราะจะแสดงแผนการทำงานและเหตุผลเบื้องหลังให้เห็นชัดเจน
- Bolt.new และ v0 ทางลัดในการสร้างต้นแบบ (Prototype) สำหรับคนที่ไม่ต้องการยุ่งกับเทอร์มินัล
เกมที่เรากำลังจะสร้าง: Breakout
Atari วางจำหน่าย Breakout เมื่อวันที่ 13 พฤษภาคม 1976 โดยเป็นผลงานของวิศวกรหนุ่มชื่อ Steve Wozniak และ Steve Jobs ก่อนที่ทั้งคู่จะร่วมกันก่อตั้ง Apple ในปีเดียวกัน ตรรกะฮาร์ดแวร์ของเกมนี้ยังส่งอิทธิพลต่อการออกแบบ Apple II รุ่นดั้งเดิมอีกด้วย
กฎของเกมนั้นเรียบง่ายแต่มีตรรกะที่น่าสนใจ คือการควบคุมไม้พายด้านล่างเพื่อสะท้อนลูกบอลไปทำลายกำแพงอิฐด้านบน หากลูกบอลตกลงพื้นจะเสียชีวิต และต้องทำลายอิฐให้หมดเพื่อชนะ
สิ่งที่ต้องเตรียม
คุณต้องการเพียงเว็บเบราว์เซอร์ เอดิเตอร์ข้อความ และผู้ช่วย AI หนึ่งตัว บทเรียนนี้จะสร้างผ่านไฟล์ HTML เพียงไฟล์เดียวโดยไม่ต้องติดตั้งเฟรมเวิร์กเพิ่มเติม
สำหรับการใช้ Claude Code ให้ติดตั้งด้วย npm install -g @anthropic-ai/claude-code แล้วรัน claude ในโฟลเดอร์โปรเจกต์ ส่วนเครื่องมืออื่นๆ สามารถใช้ Prompt เดียวกันได้เลย โดยดูโค้ดฉบับเต็มได้ที่ repo
ขั้นตอนที่ 1: Canvas และโครงร่างเกม
Prompt: *"Create a single HTML file for a Breakout game. Set up an HTML5 canvas 480 pixels wide and 400 pixels tall, centered on the page, with a dark background. Add a heading, and placeholder text elements for score and lives above the canvas. Don't add any game logic yet, just the skeleton."
<canvas id="gameCanvas" width="480" height="400"></canvas>
<div id="hud">
<span id="score">Score: 0</span>
<span id="lives">Lives: 3</span>
</div>การเริ่มจากโครงร่างช่วยให้คุณยืนยันความถูกต้องของโครงสร้างหน้าเว็บก่อนเพิ่มตรรกะ ซึ่งสำคัญมากในการตรวจจับจุดผิดพลาดเมื่อใช้ AI เขียนโค้ด
ขั้นตอนที่ 2: ไม้พาย (Paddle)
Prompt: *"Add a paddle: an 80x10 pixel rectangle near the bottom of the canvas. Make it move left and right with the arrow keys, and keep it from moving off either edge of the canvas."
const paddle = { width: 80, height: 10, x: (canvas.width - 80) / 2, y: canvas.height - 20, speed: 7, dx: 0 };
const keys = { left: false, right: false };
document.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") keys.left = true;
if (e.key === "ArrowRight") keys.right = true;
});
document.addEventListener("keyup", (e) => {
if (e.key === "ArrowLeft") keys.left = false;
if (e.key === "ArrowRight") keys.right = false;
});
function updatePaddle() {
if (keys.left) paddle.dx = -paddle.speed;
else if (keys.right) paddle.dx = paddle.speed;
else paddle.dx = 0;
paddle.x += paddle.dx;
paddle.x = Math.max(0, Math.min(canvas.width - paddle.width, paddle.x));
}การใช้ Math.max และ Math.min ช่วยจำกัดขอบเขตไม่ให้ไม้พายเลื่อนหลุดออกนอกจอ ซึ่งเป็นบั๊กที่มักจะถูกลืมบ่อยครั้ง
ขั้นตอนที่ 3: ลูกบอลและระบบฟิสิกส์
Prompt: *"Add a ball: a small circle that starts near the bottom center of the canvas and moves diagonally. Make it bounce off the left, right, and top walls."
const ball = { x: canvas.width / 2, y: canvas.height - 30, radius: 6, speed: 4, dx: 3, dy: -3 };
function updateBall() {
ball.x += ball.dx;
ball.y += ball.dy;
if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) ball.dx *= -1;
if (ball.y - ball.radius < 0) ball.dy *= -1;
}ค่า dx และ dy คือตัวกำหนดทิศทางในแต่ละเฟรม การใช้ radius มาคำนวณช่วยให้ลูกบอลเด้งเมื่อขอบสัมผัสกำแพง ไม่ใช่จุดกึ่งกลาง
ขั้นตอนที่ 4: ตารางอิฐ
Prompt: *"Add a grid of bricks: 4 rows of 7 bricks each, near the top of the canvas, with small gaps between them. Each brick should track whether it's been destroyed."
const brickInfo = { rows: 4, cols: 7, width: 55, height: 18, padding: 8, offsetTop: 40, offsetLeft: 20 };
let bricks = [];
function buildBricks() {
bricks = [];
for (let r = 0; r < brickInfo.rows; r++) {
for (let c = 0; c < brickInfo.cols; c++) {
bricks.push({
x: brickInfo.offsetLeft + c * (brickInfo.width + brickInfo.padding),
y: brickInfo.offsetTop + r * (brickInfo.height + brickInfo.padding),
width: brickInfo.width, height: brickInfo.height, destroyed: false,
});
}
}
}การใช้ลูปสร้างตารางช่วยประหยัดเวลา และสถานะ destroyed: false จะเป็นหัวใจสำคัญในการตรวจสอบเงื่อนไขในขั้นตอนถัดไป
ขั้นตอนที่ 5: การตรวจจับการชน
Prompt: *"Add collision detection: the ball should bounce off the paddle at an angle depending on where it hits (center bounces straight up, edges bounce at an angle), and destroy any brick it touches while bouncing away. A destroyed brick should never be hit again."
function ballHitsPaddle(ball, paddle) {
return (
ball.y + ball.radius >= paddle.y &&
ball.y - ball.radius <= paddle.y + paddle.height &&
ball.x >= paddle.x && ball.x <= paddle.x + paddle.width
);
}
function paddleBounceAngle(ball, paddle) {
const hitPos = (ball.x - (paddle.x + paddle.width / 2)) / (paddle.width / 2);
const clamped = Math.max(-1, Math.min(1, hitPos));
return clamped * (Math.PI / 3); // up to 60 degrees at the paddle's edges
}
function brickCollision(ball, brick) {
if (brick.destroyed) return false;
return (
ball.x + ball.radius > brick.x && ball.x - ball.radius < brick.x + brick.width &&
ball.y + ball.radius > brick.y && ball.y - ball.radius < brick.y + brick.height
);
}การใส่ if (brick.destroyed) return false เป็นสิ่งสำคัญมาก เพื่อป้องกันไม่ให้ลูกบอลไปเด้งกับอิฐล่องหนที่ถูกทำลายไปแล้ว
ขั้นตอนที่ 6: คะแนนและชีวิต
Prompt: *"Wire the collision logic into the main update loop: increase the score by 10 for each brick destroyed, and lose a life when the ball falls past the paddle. Reset the ball's position after losing a life, unless lives reach zero."
for (const brick of bricks) {
if (brickCollision(ball, brick)) {
brick.destroyed = true;
ball.dy *= -1;
score += 10;
scoreEl.textContent = `Score: ${score}`;
break; // resolve only one brick per frame
}
}
if (ball.y - ball.radius > canvas.height) {
lives -= 1;
livesEl.textContent = `Lives: ${lives}`;
if (lives <= 0) {
gameOver = true;
} else {
resetBallAndPaddle();
}
}คำสั่ง break ช่วยให้ระบบฟิสิกส์แม่นยำขึ้นโดยจัดการการชนเพียงหนึ่งครั้งต่อเฟรม เพื่อไม่ให้ทิศทางลูกบอลผิดเพี้ยนเมื่อโดนอิฐสองก้อนพร้อมกัน
ขั้นตอนที่ 7: สถานะการชนะและแพ้
Prompt: *"Add a win condition when every brick is destroyed, and stop the game loop entirely once the game is won or lost, displaying a message either way."
if (bricks.every((b) => b.destroyed)) {
gameWon = true;
messageEl.textContent = "You Win! Refresh to play again.";
}
function loop() {
if (!gameOver && !gameWon) {
updatePaddle();
updateBall();
}
draw();
requestAnimationFrame(loop);
}การใช้ Array.every() ช่วยให้ตรวจสอบสถานะอิฐทุกก้อนได้อย่างสะอาดตา และฟังก์ชัน loop จะหยุดอัปเดตตำแหน่งเมื่อจบเกมแต่ยังคงแสดงผลภาพสุดท้ายเอาไว้
การปล่อยแอปพลิเคชัน
เมื่อพัฒนาเสร็จ คุณสามารถนำเกมขึ้นออนไลน์ได้ฟรีผ่าน GitHub Pages ซึ่งเป็นวิธีที่ง่ายที่สุด หรือใช้ Netlify สำหรับการลากวางไฟล์โดยไม่ต้องใช้ Git และหากต้องการเจาะกลุ่มคนเล่นเกมโดยตรง itch.io ก็เป็นทางเลือกที่ยอดเยี่ยม
บทสรุป
Vibe coding ไม่ใช่การลดความสำคัญของการทำความเข้าใจโค้ด แต่เป็นการเปลี่ยนหน้าที่จากการพิมพ์งานซ้ำซ้อน ไปเป็นการตรวจสอบและตั้งคำถามกับสิ่งที่ AI ส่งกลับมา ทักษะที่สำคัญคือการดูว่า guard clause หรือการจำกัดขอบเขตต่างๆ ทำงานถูกต้องหรือไม่ เพื่อให้มั่นใจว่าโปรเจกต์ของคุณจะทำงานได้จริงในระยะยาว
ความคิดเห็น (0)
เข้าสู่ระบบเพื่อร่วมแสดงความเห็น
สมัครสมาชิกมาเป็นคนแรกที่แสดงความเห็นกันเลยโบร
