about summary refs log blame commit diff stats
path: root/js/ship-game/game.js
blob: 44a5df02ba649ea276428de5c1b042666a702cb8 (plain) (tree)



























































                                                                                 

                                


                                                                                                         
 



















                                                                                      
         

                                                                                       
         
 






                                                                                                                                                   
             



                                                                                                                                                   
             

                                                                                                               
         


                                                                              
                   

     
 

                                                     
 




                         
 
                                    
 




                                  
 
                
 



                                                
 


                                                         
           








                              
 





                                                                 
         
                    
       



































                                                                           
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
canvas.style.display = "block";
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

let audio = new Audio('./zap.wav');
audio.preload = 'auto';

let audioLoaded = false;

audio.addEventListener('canplaythrough', function() {
    audioLoaded = true;
});

audio.addEventListener('error', function() {
    console.error('Error loading audio file');
});

const createTargets = () => {
    let targets = [];

    for(let i = 0; i < 10; i++) {
        let shape = getRandomShape();
        let radius = Math.random() * 50 + 20;
        let x = Math.random() * (canvas.width - 2 * radius - 120) + radius + 60;
        let y = Math.random() * (canvas.height - 2 * radius - 120) + radius + 60;
        let vx = (Math.random() - 0.5) * 10;
        let vy = (Math.random() - 0.5) * 10;

        targets.push({x, y, vx, vy, radius, shape});
    }

    return targets;
}

const getRandomShape = () => {
    const shapes = ['circle', 'pentagon', 'triangle', 'square'];
    const randomIndex = Math.floor(Math.random() * shapes.length);
    return shapes[randomIndex];
}

let score = 0;
const drawScore = () => {
    ctx.font = '20px Arial';
    ctx.fillStyle = 'white';
    ctx.fillText('Score: ' + score, 10, 30);
};

let level = 1;
const drawLevel = () => {
    ctx.font = '20px Arial';
    ctx.fillStyle = 'white';
    ctx.fillText('Level: ' + level, 10, 60);
}


let showHelp = false;
const drawHelp = () => {
    if(showHelp) {
        ctx.font = '20px Arial';
        ctx.fillStyle = 'white';
        ctx.fillText('Click to shoot. Press R to respawn targets. Press H to toggle help text.', 10, 50);
    }
}

const drawLine = (line) => {
    if (line && Date.now() - line.time < 500) {
        ctx.beginPath();
        ctx.moveTo(line.startX, line.startY);
        ctx.lineTo(line.endX, line.endY);
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 4;
        ctx.stroke();
    }
};

const colors = ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF'];

const drawTargets = (targets) => {
    for (let target of targets) {
        target.x += target.vx;
        target.y += target.vy;

        if (target.x - target.radius < 0 || target.x + target.radius > canvas.width) {
            target.vx = -target.vx;
        }
        if (target.y - target.radius < 0 || target.y + target.radius > canvas.height) {
            target.vy = -target.vy;
        }

        ctx.beginPath();
        if (target.shape === 'circle') {
            ctx.arc(target.x, target.y, target.radius, 0, Math.PI * 2);
        } else if (target.shape === 'pentagon') {
            ctx.moveTo(target.x + target.radius * Math.cos(0), target.y + target.radius * Math.sin(0));
            for (let i = 1; i <= 5; i++) {
                ctx.lineTo(target.x + target.radius * Math.cos(i * (Math.PI * 2) / 5), target.y + target.radius * Math.sin(i * (Math.PI * 2) / 5));
            }
        } else if (target.shape === 'triangle') {
            ctx.moveTo(target.x + target.radius * Math.cos(0), target.y + target.radius * Math.sin(0));
            for (let i = 1; i <= 3; i++) {
                ctx.lineTo(target.x + target.radius * Math.cos(i * (Math.PI * 2) / 3), target.y + target.radius * Math.sin(i * (Math.PI * 2) / 3));
            }
        } else if (target.shape === 'square') {
            ctx.rect(target.x - target.radius, target.y - target.radius, target.radius * 2, target.radius * 2);
        }
        
        const randomColor = colors[Math.floor(Math.random() * colors.length)];
        ctx.fillStyle = randomColor;
        ctx.fill();
    }
};

const gameLoop = () => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    drawScore();
    drawLevel();
    drawHelp();
    drawLine(line);
    drawTargets(targets);

    requestAnimationFrame(gameLoop);

    if (targets.length === 0) {
        level++;
        targets = createTargets();
    }
};

let line = null;

const handleInteraction = (e) => {
    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    if (audioLoaded) {
        audio.play().catch((error) => {
            console.error('Error playing audio:', error);
        });
    }

    line = {
        startX: 0,
        startY: canvas.height,
        endX: x,
        endY: y,
        time: Date.now()
    };

    targets = targets.filter((target) => {
        const dx = target.x - x;
        const dy = target.y - y;
        if (dx * dx + dy * dy <= target.radius * target.radius) {
            score++;
            return false;
        }
        return true;
    });
};

canvas.addEventListener('click', handleInteraction);
canvas.addEventListener('touchstart', function(e) {
    // Prevent the window from scrolling
    e.preventDefault();

    // A touch event can have multiple touches so we just get the first one
    e.clientX = e.touches[0].clientX;
    e.clientY = e.touches[0].clientY;

    handleInteraction(e);
}, { passive: false });

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

window.addEventListener('keydown', (e) => {
    if (e.key === 'r' || e.key === 'R') {
        targets = createTargets();
    }
});

window.addEventListener('keydown', (e) => {
    if (e.key === 'h' || e.key === 'H') {
        showHelp = !showHelp;
    } else if (e.key === 'r' || e.key === 'R') {
        targets = createTargets();
    }
});

let targets = createTargets();

gameLoop();