Cách tạo game Chém hoa quả bằng Gemini AI

Nếu vài năm trước, việc tự tay làm ra một tựa game nghe còn khá xa lạ với dân không chuyên, thì giờ đây mọi thứ đã khác. Chỉ với vài cú click và một chút sáng tạo, AI đang biến những ý tưởng của bạn thành sản phẩm có thể chơi được ngay.

Nhưng chắc hẳn nhiều bạn đang băn khoăn rằng tôi không biết gì về lập trình thì có thể tạo ra một game hoàn chỉnh chơi được hay không? Hãy đi tìm câu trả lời trong bài viết hướng dẫn tạo game Chém hoa quả dưới đây của GameVui, đây là một tựa game quen thuộc từ hàng chục năm nay với ưu điểm là dễ chơi, cấu hình nhẹ.

Hướng dẫn tạo game Chém hoa quả bằng AI

Bước 1: Trước tiên, bạn hãy vào ứng dụng Gemini rồi viết câu lệnh hãy viết Prompt tạo game Chém hoa quả

hãy viết prompt tạo game html Chém hoa quả chơi màn hình ngang trên máy tính và điện thoại

Viết Prompt tạo game chém hoa quả

Bước 2: Bạn sao chép Prompt sau rồi dán vào Gemini để nó tạo cho bạn một game Chém hoa quả

Chủ đề: Tạo game HTML5 "Chém hoa quả" chơi trên trình duyệt.

Yêu cầu kỹ thuật:

Ngôn ngữ: Sử dụng HTML5, CSS3 và Javascript thuần (Canvas API). Viết tất cả trong một file duy nhất để dễ kiểm tra.

Giao diện & Trải nghiệm (UX/UI):

Thiết kế màn hình ngang (Landscape). Tự động co giãn theo kích thước màn hình (Responsive).

Nền (Background) màu gỗ tối hoặc hình ảnh trang nhã.

Hiển thị Điểm số (Score) ở góc trên bên trái và Số mạng (Lives - tối đa 3) ở góc trên bên phải.

Logic Game:

Cơ chế bay: Hoa quả (các hình tròn màu sắc khác nhau) bay từ dưới màn hình lên với vận tốc và góc ngẫu nhiên, chịu tác động của trọng lực để rơi xuống.

Cơ chế chém: Người dùng sử dụng chuột (PC) hoặc vuốt màn hình (Mobile). Khi vuốt, phải có hiệu ứng "đường kiếm" (blade trail) đi theo.

Va chạm: Nếu đường chém cắt ngang hoa quả, hoa quả sẽ vỡ làm đôi và biến mất, cộng 1 điểm. Thêm hiệu ứng hạt (particles) văng ra như nước ép.

Vật cản: Thỉnh thoảng xuất hiện Bom. Nếu chém trúng bom -> Game Over ngay lập tức.

Điều kiện thua: Nếu để lọt một quả rơi xuống dưới mà chưa chém -> Mất 1 mạng. Hết 3 mạng -> Game Over.

Tương thích:

Hỗ trợ đồng thời cả sự kiện MouseEvent và TouchEvent.

Thêm nút "Start Game" ở đầu và "Restart" khi thua.

Bước 3: Sau đó, Gemini sẽ phân tích Prompt của bạn và xử lý tạo game Chém hoa quả. Khi hoàn thành, bạn sẽ nhận được đoạn mã như dưới đây

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Fruit Ninja - HTML5 Canvas</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            user-select: none;
            -webkit-tap-highlight-color: transparent;
        }

        body {
            background-color: #1a1a1a;
            overflow: hidden;
            font-family: 'Arial', sans-serif;
            color: white;
        }

        #game-container {
            position: relative;
            width: 100vw;
            height: 100vh;
            /* Nền màu gỗ tối */
            background: radial-gradient(circle, #4a2c1a 0%, #2a180d 100%);
            display: flex;
            justify-content: center;
            align-items: center;
        }

        canvas {
            display: block;
        }

        /* Giao diện UI */
        .ui-layer {
            position: absolute;
            top: 20px;
            width: 100%;
            padding: 0 30px;
            display: flex;
            justify-content: space-between;
            pointer-events: none;
            font-size: 24px;
            font-weight: bold;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
        }

        #lives { color: #ff4757; }
        #score { color: #eccc68; }

        /* Menu */
        .overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 10;
        }

        h1 {
            font-size: 60px;
            margin-bottom: 20px;
            color: #ffbe76;
            text-transform: uppercase;
            letter-spacing: 5px;
        }

        .btn {
            padding: 15px 40px;
            font-size: 24px;
            background: #6ab04c;
            border: none;
            border-radius: 50px;
            color: white;
            cursor: pointer;
            transition: transform 0.2s, background 0.2s;
        }

        .btn:hover {
            background: #badc58;
            transform: scale(1.1);
        }

        #game-over-screen { display: none; }
    </style>
</head>
<body>

<div id="game-container">
    <canvas id="gameCanvas"></canvas>

    <!-- UI -->
    <div class="ui-layer">
        <div id="score">SCORE: 0</div>
        <div id="lives">LIVES: 3</div>
    </div>

    <!-- Start Screen -->
    <div id="start-screen" class="overlay">
        <h1>FRUIT SLICE</h1>
        <button class="btn" onclick="startGame()">START GAME</button>
    </div>

    <!-- Game Over Screen -->
    <div id="game-over-screen" class="overlay">
        <h1 style="color: #eb4d4b;">GAME OVER</h1>
        <div id="final-score" style="font-size: 24px; margin-bottom: 20px;">Score: 0</div>
        <button class="btn" onclick="startGame()">RESTART</button>
    </div>
</div>

<script>
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const scoreElement = document.getElementById('score');
    const livesElement = document.getElementById('lives');
    const startScreen = document.getElementById('start-screen');
    const gameOverScreen = document.getElementById('game-over-screen');
    const finalScoreElement = document.getElementById('final-score');

    let score = 0;
    let lives = 3;
    let gameActive = false;
    let fruits = [];
    let particles = [];
    let blade = { points: [] };
    let gravity = 0.15;

    // Cấu hình loại quả
    const fruitTypes = [
        { color: '#ff4757', name: 'apple' },
        { color: '#ffa502', name: 'orange' },
        { color: '#2ed573', name: 'watermelon' },
        { color: '#eccc68', name: 'banana' },
        { color: '#1e90ff', name: 'berry' }
    ];

    // Khởi tạo kích thước canvas
    function resize() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    window.addEventListener('resize', resize);
    resize();

    // Đối tượng Hoa Quả
    class Fruit {
        constructor(isBomb = false) {
            this.isBomb = isBomb;
            this.radius = isBomb ? 35 : 40;
            this.x = Math.random() * (canvas.width - 100) + 50;
            this.y = canvas.height + this.radius;
            this.color = isBomb ? '#000' : fruitTypes[Math.floor(Math.random() * fruitTypes.length)].color;
            
            // Lực bay lên
            this.vx = (Math.random() - 0.5) * 8;
            this.vy = -(Math.random() * 6 + 12);
            this.sliced = false;
        }

        update() {
            this.vy += gravity;
            this.x += this.vx;
            this.y += this.vy;

            // Kiểm tra rớt khỏi màn hình
            if (this.y > canvas.height + 100 && !this.sliced) {
                if (!this.isBomb) {
                    lives--;
                    updateUI();
                    if (lives <= 0) endGame();
                }
                return true; // Đánh dấu để xóa
            }
            return false;
        }

        draw() {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
            ctx.fillStyle = this.color;
            ctx.fill();
            ctx.closePath();

            // Nếu là bom, vẽ thêm ký hiệu
            if (this.isBomb) {
                ctx.fillStyle = 'red';
                ctx.font = '20px Arial';
                ctx.fillText('💣', this.x - 12, this.y + 7);
            }
        }
    }

    // Hiệu ứng nước ép (Hạt)
    class Particle {
        constructor(x, y, color) {
            this.x = x;
            this.y = y;
            this.color = color;
            this.radius = Math.random() * 4 + 2;
            this.vx = (Math.random() - 0.5) * 10;
            this.vy = (Math.random() - 0.5) * 10;
            this.alpha = 1;
        }

        update() {
            this.x += this.vx;
            this.y += this.vy;
            this.alpha -= 0.02;
        }

        draw() {
            ctx.save();
            ctx.globalAlpha = this.alpha;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
            ctx.fillStyle = this.color;
            ctx.fill();
            ctx.restore();
        }
    }

    // Xử lý sự kiện chuột/vuốt
    let isDrawing = false;

    function handleStart(e) {
        isDrawing = true;
        blade.points = [];
        addPoint(e);
    }

    function handleMove(e) {
        if (!isDrawing) return;
        addPoint(e);
        checkSlice();
    }

    function handleEnd() {
        isDrawing = false;
        setTimeout(() => blade.points = [], 100);
    }

    function addPoint(e) {
        const rect = canvas.getBoundingClientRect();
        const x = (e.touches ? e.touches[0].clientX : e.clientX) - rect.left;
        const y = (e.touches ? e.touches[0].clientY : e.clientY) - rect.top;
        blade.points.push({ x, y, time: Date.now() });
        if (blade.points.length > 10) blade.points.shift();
    }

    // Kiểm tra va chạm giữa đường chém và quả
    function checkSlice() {
        if (blade.points.length < 2) return;
        
        const p1 = blade.points[blade.points.length - 2];
        const p2 = blade.points[blade.points.length - 1];

        fruits.forEach((fruit, index) => {
            if (fruit.sliced) return;

            // Tính khoảng cách từ quả tới điểm chém cuối
            const dist = Math.hypot(fruit.x - p2.x, fruit.y - p2.y);
            if (dist < fruit.radius) {
                if (fruit.isBomb) {
                    endGame();
                } else {
                    fruit.sliced = true;
                    score++;
                    updateUI();
                    createParticles(fruit.x, fruit.y, fruit.color);
                }
            }
        });
    }

    function createParticles(x, y, color) {
        for (let i = 0; i < 15; i++) {
            particles.push(new Particle(x, y, color));
        }
    }

    function updateUI() {
        scoreElement.innerText = `SCORE: ${score}`;
        livesElement.innerText = `LIVES: ${lives}`;
    }

    function spawnFruit() {
        if (!gameActive) return;
        const isBomb = Math.random() < 0.2; // 20% xuất hiện bom
        fruits.push(new Fruit(isBomb));
        
        // Tăng độ khó theo thời gian
        let nextSpawn = Math.max(400, 1500 - (score * 10));
        setTimeout(spawnFruit, nextSpawn);
    }

    function startGame() {
        score = 0;
        lives = 3;
        fruits = [];
        particles = [];
        gameActive = true;
        updateUI();
        startScreen.style.display = 'none';
        gameOverScreen.style.display = 'none';
        spawnFruit();
        animate();
    }

    function endGame() {
        gameActive = false;
        gameOverScreen.style.display = 'flex';
        finalScoreElement.innerText = `Score: ${score}`;
    }

    function drawBlade() {
        if (blade.points.length < 2) return;
        ctx.beginPath();
        ctx.strokeStyle = 'white';
        ctx.lineWidth = 5;
        ctx.lineCap = 'round';
        ctx.moveTo(blade.points[0].x, blade.points[0].y);
        for (let i = 1; i < blade.points.length; i++) {
            ctx.lineTo(blade.points[i].x, blade.points[i].y);
        }
        ctx.stroke();
        ctx.closePath();
    }

    function animate() {
        if (!gameActive && fruits.length === 0) return;

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Cập nhật và vẽ hoa quả
        for (let i = fruits.length - 1; i >= 0; i--) {
            if (fruits[i].update()) {
                fruits.splice(i, 1);
            } else if (fruits[i].sliced) {
                fruits.splice(i, 1);
            } else {
                fruits[i].draw();
            }
        }

        // Cập nhật và vẽ hạt nước ép
        for (let i = particles.length - 1; i >= 0; i--) {
            particles[i].update();
            if (particles[i].alpha <= 0) {
                particles.splice(i, 1);
            } else {
                particles[i].draw();
            }
        }

        drawBlade();

        if (gameActive) requestAnimationFrame(animate);
    }

    // Đăng ký sự kiện
    canvas.addEventListener('mousedown', handleStart);
    window.addEventListener('mousemove', handleMove);
    window.addEventListener('mouseup', handleEnd);

    canvas.addEventListener('touchstart', (e) => { e.preventDefault(); handleStart(e); }, {passive: false});
    canvas.addEventListener('touchmove', (e) => { e.preventDefault(); handleMove(e); }, {passive: false});
    canvas.addEventListener('touchend', handleEnd);

</script>

</body>
</html>

Bước 4: Bạn hãy sao chép đoạn mã ở trên vào Notepad rồi lưu thành file chemhoaqua.html

Lưu đoạn mã của Gemini vào Notepad

Bước 5: Bạn click chuột phải vào file chemhoaqua.html rồi chọn Open With/Google Chrome để mở game trên trình duyệt Chrome.

Mở game bằng Chrome

Bước 6: Bạn tải hình ảnh các loại quả như dưa hấu, cam, táo, bom, dưa chuột, chuối dưới dạng PNG (nền trong suốt) về máy. Sau đó, copy các file này vào cùng thư mục với file chemhoaqua.html

Tải hình ảnh các loại quả

Bước 7: Bên cạnh đó, bạn cũng tải một số file âm thanh, nhạc nền rồi copy tất cả vào thư mục game Chém hoa quả cùng với file chem-hoa-qua.html ở trên.

Copy file hình ảnh, âm thanh vào thư mục game Chém hoa quả

Bước 8: Bạn hãy sao chép đoạn mã hoàn chỉnh dưới đây (gồm cả hình ảnh và âm thanh) vào file chem-hoa-qua.html

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Fruit Ninja Master - Fixed Version</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; user-select: none; touch-action: none; }
        body { 
            overflow: hidden; background-color: #1a0f0f; 
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            position: fixed; width: 100%; height: 100%;
        }
        #game-container { position: relative; width: 100vw; height: 100vh; background: #231212; }
        canvas { display: block; }

        /* HUD */
        #ui-layer {
            position: absolute; top: 20px; left: 20px; right: 20px;
            pointer-events: none; display: flex; justify-content: space-between;
            color: #fff; font-size: 32px; font-weight: 900;
            text-shadow: 2px 2px 10px rgba(0,0,0,0.8);
        }
        .lives { color: #ff4757; letter-spacing: 5px; }

        /* Screens */
        .overlay-screen {
            position: absolute; top: 50%; left: 50%;
            transform: translate(-50%, -50%); background: rgba(0,0,0,0.9);
            padding: 40px; border-radius: 25px; text-align: center; color: white;
            border: 4px solid #f1c40f; min-width: 320px; z-index: 100;
        }
        #game-over { display: none; }

        button {
            margin-top: 25px; padding: 15px 45px; font-size: 24px; font-weight: bold;
            background: linear-gradient(to bottom, #f39c12, #e67e22);
            color: white; border: none; border-radius: 50px;
            cursor: pointer; box-shadow: 0 5px 0 #a04000;
        }
        button:active { transform: translateY(3px); box-shadow: 0 2px 0 #a04000; }

        #orientation-warning {
            display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0, 0, 0, 0.95); color: white; z-index: 1000;
            flex-direction: column; justify-content: center; align-items: center; text-align: center;
        }
        @media screen and (orientation: portrait) { #orientation-warning { display: flex; } }
    </style>
</head>
<body>

    <div id="game-container">
        <div id="ui-layer">
            <div id="score">SCORE: 0</div>
            <div id="lives" class="lives">❤❤❤</div>
        </div>

        <canvas id="gameCanvas"></canvas>

        <div id="start-screen" class="overlay-screen">
            <h1 style="color: #f1c40f; font-size: 50px; margin-bottom: 10px;">FRUIT NINJA</h1>
            <p>Chém thật nhanh - Tránh quả bom!</p>
            <button onclick="startGame()">BẮT ĐẦU</button>
        </div>

        <div id="game-over" class="overlay-screen">
            <h1 style="color: #ff4757; font-size: 48px;">GAME OVER</h1>
            <p id="final-score" style="font-size: 24px; margin: 15px 0;">Điểm của bạn: 0</p>
            <button onclick="resetGame()">CHƠI LẠI</button>
        </div>
    </div>

    <div id="orientation-warning">
        <div style="font-size: 60px;">🔄</div>
        <h2>HÃY XOAY NGANG MÀN HÌNH</h2>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        
        // --- TÀI NGUYÊN ---
        const assets = {
            images: { apple: 'tao.png', orange: 'cam.png', waterm: 'dua-hau.png', bomb: 'bom.png' },
            sounds: { bg: 'nhac-nen.mp3', slash: 'chem.mp3', explode: 'bom-no.mp3', lose: 'thua.mp3' }
        };

        const imgs = {};
        const snds = {};
        let score = 0;
        let lives = 3;
        let isGameOver = true;
        let fruits = [];
        let particles = [];
        let bladeTrail = [];
        const GRAVITY = 0.15;

        // Load Assets
        function loadAssets() {
            for (let k in assets.images) { imgs[k] = new Image(); imgs[k].src = assets.images[k]; }
            for (let k in assets.sounds) { snds[k] = new Audio(assets.sounds[k]); if(k==='bg') snds[k].loop = true; }
        }
        loadAssets();

        function resize() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        window.addEventListener('resize', resize);
        resize();

        // --- CÁC HÀM LOGIC QUAN TRỌNG (ĐÃ FIX LỖI) ---
        
        function loseLife() {
            if (isGameOver) return;
            lives--;
            document.getElementById('lives').innerText = "❤".repeat(Math.max(0, lives));
            if (lives <= 0) endGame();
        }

        function endGame() {
            isGameOver = true;
            snds.bg.pause();
            snds.lose.play();
            document.getElementById('game-over').style.display = 'block';
            document.getElementById('final-score').innerText = `Điểm của bạn: ${score}`;
        }

        function startGame() {
            document.getElementById('start-screen').style.display = 'none';
            resetGame();
        }

        function resetGame() {
            score = 0; lives = 3; isGameOver = false; fruits = []; particles = [];
            document.getElementById('score').innerText = `SCORE: 0`;
            document.getElementById('lives').innerText = "❤❤❤";
            document.getElementById('game-over').style.display = 'none';
            snds.bg.currentTime = 0;
            snds.bg.play().catch(() => {});
        }

        // --- ĐỐI TƯỢNG ---
        class Fruit {
            constructor() {
                const types = [
                    { img: imgs.apple, color: '#ff4d4d', isBomb: false },
                    { img: imgs.orange, color: '#ffa502', isBomb: false },
                    { img: imgs.waterm, color: '#2ed573', isBomb: false },
                    { img: imgs.bomb, color: '#333', isBomb: true }
                ];
                const type = Math.random() < 0.18 ? types[3] : types[Math.floor(Math.random() * 3)];
                
                this.img = type.img;
                this.color = type.color;
                this.isBomb = type.isBomb;
                this.size = 85;
                this.x = Math.random() * (canvas.width - 100) + 50;
                this.y = canvas.height + 50;
                this.vx = (this.x < canvas.width/2 ? 1 : -1) * (Math.random() * 3 + 1.5);
                this.vy = -(Math.random() * 4 + 12);
                this.angle = 0;
                this.rot = (Math.random() - 0.5) * 0.1;
                this.sliced = false;
                this.sliceTime = 0;
            }

            update() {
                this.x += this.vx;
                this.y += this.vy;
                this.vy += GRAVITY;
                this.angle += this.rot;

                // Kiểm tra rơi mất quả
                if (this.y > canvas.height + 150 && !this.sliced) {
                    if (!this.isBomb) loseLife();
                    this.sliced = true; 
                }
            }

            draw() {
                ctx.save();
                ctx.translate(this.x, this.y);
                ctx.rotate(this.angle);

                if (!this.sliced) {
                    if (this.img.complete) ctx.drawImage(this.img, -this.size/2, -this.size/2, this.size, this.size);
                } else if (!this.isBomb) {
                    let drift = (Date.now() - this.sliceTime) / 4;
                    // Vẽ 2 nửa văng ra
                    ctx.save(); ctx.translate(-drift, 0); 
                    ctx.beginPath(); ctx.rect(-this.size/2, -this.size/2, this.size/2, this.size); ctx.clip();
                    ctx.drawImage(this.img, -this.size/2, -this.size/2, this.size, this.size); ctx.restore();

                    ctx.save(); ctx.translate(drift, 0); 
                    ctx.beginPath(); ctx.rect(0, -this.size/2, this.size/2, this.size); ctx.clip();
                    ctx.drawImage(this.img, -this.size/2, -this.size/2, this.size, this.size); ctx.restore();
                }
                ctx.restore();
            }
        }

        class Particle {
            constructor(x, y, color) {
                this.x = x; this.y = y; this.color = color;
                this.vx = (Math.random() - 0.5) * 12;
                this.vy = (Math.random() - 0.5) * 12;
                this.alpha = 1;
            }
            update() { this.x += this.vx; this.y += this.vy; this.alpha -= 0.03; }
            draw() {
                ctx.globalAlpha = this.alpha;
                ctx.fillStyle = this.color;
                ctx.beginPath(); ctx.arc(this.x, this.y, 4, 0, Math.PI*2); ctx.fill();
                ctx.globalAlpha = 1;
            }
        }

        // --- ĐIỀU KHIỂN ---
        let isTouching = false;
        function getPos(e) {
            const rect = canvas.getBoundingClientRect();
            const t = e.touches ? e.touches[0] : e;
            return {
                x: (t.clientX - rect.left) * (canvas.width / rect.width),
                y: (t.clientY - rect.top) * (canvas.height / rect.height)
            };
        }

        function handleMove(e) {
            if (!isTouching || isGameOver) return;
            const pos = getPos(e);
            bladeTrail.push({ x: pos.x, y: pos.y, time: Date.now() });

            fruits.forEach(f => {
                if (!f.sliced) {
                    const dist = Math.hypot(f.x - pos.x, f.y - pos.y);
                    if (dist < 55) { 
                        f.sliced = true;
                        f.sliceTime = Date.now();
                        if (f.isBomb) {
                            snds.explode.play(); endGame();
                        } else {
                            score += 10;
                            document.getElementById('score').innerText = `SCORE: ${score}`;
                            snds.slash.cloneNode().play();
                            for(let i=0; i<15; i++) particles.push(new Particle(f.x, f.y, f.color));
                        }
                    }
                }
            });
        }

        canvas.addEventListener('mousedown', () => isTouching = true);
        window.addEventListener('mouseup', () => isTouching = false);
        canvas.addEventListener('mousemove', handleMove);
        canvas.addEventListener('touchstart', (e) => { isTouching = true; handleMove(e); });
        canvas.addEventListener('touchmove', (e) => { e.preventDefault(); handleMove(e); }, {passive:false});
        window.addEventListener('touchend', () => isTouching = false);

        // --- VÒNG LẶP ---
        function loop() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            if (!isGameOver) {
                if (Math.random() < 0.035) fruits.push(new Fruit());

                // Vẽ Trail
                const now = Date.now();
                bladeTrail = bladeTrail.filter(p => now - p.time < 150);
                if(bladeTrail.length > 2) {
                    ctx.beginPath(); ctx.strokeStyle = "#fff"; ctx.lineWidth = 4;
                    ctx.moveTo(bladeTrail[0].x, bladeTrail[0].y);
                    for(let i=1; i<bladeTrail.length; i++) ctx.lineTo(bladeTrail[i].x, bladeTrail[i].y);
                    ctx.stroke();
                }

                fruits.forEach((f, i) => {
                    f.update(); f.draw();
                    if (f.y > canvas.height + 200) fruits.splice(i, 1);
                });

                particles.forEach((p, i) => {
                    p.update(); p.draw();
                    if (p.alpha <= 0) particles.splice(i, 1);
                });
            }
            requestAnimationFrame(loop);
        }
        loop();
    </script>
</body>
</html>

Lưu ý:

Bạn cần sửa tên file âm thanh, hình ảnh trong thư mục game theo đúng như sau

  • nhac-nen.mp3
  • chem.mp3
  • bom-no.mp3
  • thua.mp3
  • tao.png
  • cam.png
  • dua-hau.png
  • bom.png

Video hướng dẫn tạo game Chém hoa quả bằng Gemini

Thứ Tư, 08/04/2026 09:36
31 👨 20
0 Bình luận
Sắp xếp theo