בניית משחק פשוט בדפדפן עם Canvas API

Canvas API מספק דרך עוצמתית ליצירת גרפיקה ואנימציות בדפדפן. במדריך זה, נלמד כיצד לבנות משחק פשוט אך מהנה בשם "תפוס את הכדור" באמצעות Canvas API ו-JavaScript. המשחק יכלול כדור נע, שחקן שניתן לשלוט בו, וניקוד. (התמונות להמחשה בלבד ולא משקפות את המשחק)

מבוא

Canvas API מספק דרך עוצמתית ליצירת גרפיקה ואנימציות בדפדפן. במדריך זה, נלמד כיצד לבנות משחק פשוט אך מהנה בשם "תפוס את הכדור" באמצעות Canvas API ו-JavaScript. המשחק יכלול כדור נע, שחקן שניתן לשלוט בו, וניקוד.


Image

שלב 1: הכנת הסביבה

נתחיל ביצירת קובץ HTML בסיסי:

<!DOCTYPE html>
<html lang="he" dir="rtl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>תפוס את הכדור</title>
    <style>
        canvas {
            border: 1px solid black;
            display: block;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
    <script src="game.js"></script>
</body>
</html>

שלב 2: יצירת הקנבס והגדרת משתנים בסיסיים

כעת ניצור קובץ game.js ונתחיל לכתוב את הלוגיקה של המשחק:

// קבלת הקנבס והקונטקסט
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

// הגדרת משתנים גלובליים
let score = 0;
let gameLoop;
const FPS = 60;

// הגדרת השחקן
const player = {
    x: canvas.width / 2,
    y: canvas.height - 50,
    width: 100,
    height: 20,
    color: '#0095DD',
    speed: 7
};

// הגדרת הכדור
const ball = {
    x: canvas.width / 2,
    y: 0,
    radius: 10,
    color: '#FF0000',
    speedY: 5
};

שלב 3: יצירת פונקציות ציור בסיסיות

נוסיף פונקציות לציור השחקן והכדור:

// ציור השחקן
function drawPlayer() {
    ctx.beginPath();
    ctx.rect(player.x, player.y, player.width, player.height);
    ctx.fillStyle = player.color;
    ctx.fill();
    ctx.closePath();
}

// ציור הכדור
function drawBall() {
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
    ctx.fillStyle = ball.color;
    ctx.fill();
    ctx.closePath();
}

// ציור הניקוד
function drawScore() {
    ctx.font = '16px Arial';
    ctx.fillStyle = '#0095DD';
    ctx.fillText('ניקוד: ' + score, 8, 20);
}

שלב 4: יצירת לוגיקת המשחק

כעת נוסיף את הלוגיקה הבסיסית של המשחק:

// עדכון מיקום הכדור
function updateBallPosition() {
    ball.y += ball.speedY;

    // בדיקת התנגשות עם השחקן
    if (ball.y + ball.radius > player.y &&
        ball.x > player.x &&
        ball.x < player.x + player.width) {
        ball.speedY = -ball.speedY;
        score++;
    }

    // בדיקת יציאה מהמסך
    if (ball.y + ball.radius > canvas.height) {
        resetBall();
    }
}

// איפוס מיקום הכדור
function resetBall() {
    ball.x = Math.random() * canvas.width;
    ball.y = 0;
}

// הזזת השחקן
function movePlayer(direction) {
    if (direction === 'left' && player.x > 0) {
        player.x -= player.speed;
    } else if (direction === 'right' && player.x + player.width < canvas.width) {
        player.x += player.speed;
    }
}

// פונקציית הציור הראשית
function draw() {
    // ניקוי הקנבס
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    drawPlayer();
    drawBall();
    drawScore();
    updateBallPosition();
}

// לולאת המשחק
function gameLoop() {
    draw();
    requestAnimationFrame(gameLoop);
}

שלב 5: הוספת שליטה במקלדת

נוסיף אפשרות לשלוט בשחקן באמצעות המקלדת:

// מאזין אירועי מקלדת
document.addEventListener('keydown', (e) => {
    if (e.key === 'ArrowLeft') {
        movePlayer('left');
    } else if (e.key === 'ArrowRight') {
        movePlayer('right');
    }
});

שלב 6: התחלת המשחק

לבסוף, נפעיל את המשחק:

// התחלת המשחק
gameLoop();

שלב 7: שיפורים והרחבות

כעת שיש לנו משחק בסיסי עובד, נוכל להוסיף כמה שיפורים:

7.1 הוספת רמות קושי

נוסיף רמות קושי שישפיעו על מהירות הכדור:

let difficulty = 1;

function increaseDifficulty() {
    difficulty += 0.1;
    ball.speedY = 5 * difficulty;
}

// עדכון פונקציית updateBallPosition
function updateBallPosition() {
    // ... הקוד הקיים ...
    if (ball.y + ball.radius > player.y &&
        ball.x > player.x &&
        ball.x < player.x + player.width) {
        ball.speedY = -ball.speedY;
        score++;
        increaseDifficulty(); // הוספת קושי בכל פעם שהשחקן תופס את הכדור
    }
    // ... המשך הקוד הקיים ...
}

7.2 הוספת אפקטים קוליים

נוסיף אפקטים קוליים למשחק:

const hitSound = new Audio('hit.mp3');
const missSound = new Audio('miss.mp3');

// עדכון פונקציית updateBallPosition
function updateBallPosition() {
    // ... הקוד הקיים ...
    if (ball.y + ball.radius > player.y &&
        ball.x > player.x &&
        ball.x < player.x + player.width) {
        ball.speedY = -ball.speedY;
        score++;
        increaseDifficulty();
        hitSound.play(); // השמעת צליל פגיעה
    }

    if (ball.y + ball.radius > canvas.height) {
        resetBall();
        missSound.play(); // השמעת צליל החמצה
    }
    // ... המשך הקוד הקיים ...
}

7.3 הוספת אנימציית רקע

נוסיף אנימציית רקע פשוטה למשחק:

const stars = [];

// יצירת כוכבים
for (let i = 0; i < 100; i++) {
    stars.push({
        x: Math.random() * canvas.width,
        y: Math.random() * canvas.height,
        radius: Math.random() * 3,
        speed: Math.random() * 0.5 + 0.1
    });
}

// ציור הכוכבים
function drawStars() {
    ctx.fillStyle = 'white';
    stars.forEach(star => {
        ctx.beginPath();
        ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2);
        ctx.fill();
    });
}

// עדכון מיקום הכוכבים
function updateStars() {
    stars.forEach(star => {
        star.y += star.speed;
        if (star.y > canvas.height) {
            star.y = 0;
        }
    });
}

// עדכון פונקציית draw
function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    // ציור רקע שחור
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    drawStars();
    updateStars();
    drawPlayer();
    drawBall();
    drawScore();
    updateBallPosition();
}

7.4 הוספת מסך פתיחה ומסך סיום

נוסיף מסכי פתיחה וסיום למשחק:

let gameState = 'start'; // 'start', 'play', 'end'

function drawStartScreen() {
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.font = '30px Arial';
    ctx.fillStyle = 'white';
    ctx.textAlign = 'center';
    ctx.fillText('תפוס את הכדור', canvas.width / 2, canvas.height / 2);
    ctx.font = '20px Arial';
    ctx.fillText('לחץ על מקש כלשהו להתחלה', canvas.width / 2, canvas.height / 2 + 50);
}

function drawEndScreen() {
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.font = '30px Arial';
    ctx.fillStyle = 'white';
    ctx.textAlign = 'center';
    ctx.fillText('המשחק נגמר', canvas.width / 2, canvas.height / 2);
    ctx.font = '20px Arial';
    ctx.fillText('הניקוד שלך: ' + score, canvas.width / 2, canvas.height / 2 + 50);
    ctx.fillText('לחץ על מקש כלשהו לשחק שוב', canvas.width / 2, canvas.height / 2 + 100);
}

// עדכון לולאת המשחק
function gameLoop() {
    if (gameState === 'start') {
        drawStartScreen();
    } else if (gameState === 'play') {
        draw();
    } else if (gameState === 'end') {
        drawEndScreen();
    }
    requestAnimationFrame(gameLoop);
}

// עדכון מאזין אירועי המקלדת
document.addEventListener('keydown', (e) => {
    if (gameState === 'start') {
        gameState = 'play';
    } else if (gameState === 'play') {
        if (e.key === 'ArrowLeft') {
            movePlayer('left');
        } else if (e.key === 'ArrowRight') {
            movePlayer('right');
        }
    } else if (gameState === 'end') {
        gameState = 'play';
        score = 0;
        difficulty = 1;
        resetBall();
    }
});

// עדכון פונקציית resetBall
function resetBall() {
    ball.x = Math.random() * canvas.width;
    ball.y = 0;
    if (gameState === 'play') {
        gameState = 'end';
    }
}

Image

סיכום

במדריך זה יצרנו משחק פשוט אך מהנה בשם "תפוס את הכדור" באמצעות Canvas API ו-JavaScript. למדנו כיצד:

1. להגדיר את סביבת המשחק עם HTML ו-Canvas

2. ליצור אובייקטים בסיסיים כמו שחקן וכדור

3. לצייר אלמנטים על הקנבס

4. ליישם לוגיקת משחק בסיסית

5. להוסיף שליטה במקלדת

6. לשפר את המשחק עם רמות קושי, אפקטים קוליים ואנימציות רקע

7. להוסיף מסכי פתיחה וסיום למשחק

זהו בסיס מצוין להמשך פיתוח ושיפור המשחק. ניתן להוסיף תכונות נוספות כגון:

  • מערכת חיים
  • כוח-על זמני
  • טבלת שיאים
  • אפשרויות התאמה אישית לשחקן
  • זכרו, פיתוח משחקים הוא תהליך איטרטיבי. התחילו עם גרסה בסיסית, בדקו אותה, קבלו משוב ושפרו בהתאם. עם הזמן והניסיון, תוכלו ליצור משחקים מורכבים ומרשימים יותר.

    בהצלחה בפיתוח המשחקים שלכם!

    יתכן שחלק מהתמונות בדף זה נלקחו מהאתר freepik.com
    שיתוף