פיתוח משחקים ב JavaScript – מבוסס על משחק סופר 8 – חלק 4

17/03/2013

no comments

בפוסט הקודם חלק 3 – פיתוח משחקים ב – JavaScript דיברנו על איך להזיז את הדמות במרחב המשחק ואיך לשנות את כיון התמונה שתתאים לכיון שהדמות הולכת אליו.

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

image image image

בפוסט זה נשתמש בספריה נוספת שנקראת – PreloadJS, שגם שייכת לסט הספריות של CreateJS. (עד עכשיו השתמשנו ב – EASEJS שגם משתייכת לשם)

ספריית PreloadJS, מאפשרת טעינה של קבצי מוסיקה, תמונות ברקע ומאפשרת לנו לשלוט מתי כל חלקי המשחק נטענו בהצלחה.

נוסיף לדף שלנו את הקריאה הבאה, אשר תאפשר לנו להשתמש ביכולות הטעינה של PreloadJS.

 <script type="text/javascript" src="js/preloadjs-0.3.0.min.js"></script>

כעת נוסיף פונקצייה חדשה בשם start ונוסיף אליה את הקוד הבא:

function start() {           
    manifest = [
        { src: "assets/sky.png", id: "sky" },
        { src: "assets/ground.png", id: "ground" },
        { src: "assets/logo.png", id: "sun" },
        { src: "assets/hill.png", id: "hill" }
    ];

    loader = new createjs.LoadQueue(false);
    loader.onFileLoad = handleFileLoad;
    loader.onComplete = handleComplete;
    loader.loadManifest(manifest);
}

עפי שניתן לראות בדוגמא מעלה, אנחנו מגדירים קובץ manifest (כמובן זה לא חייב להיות השם), בו אנחנו מגדירים את כל התכנים שאנו מעוניינים לטעון עבור המשחק.

כאשר ההורדה תסתיים נעבור לפונקציית handleComplete, עבור כל תוכן שנטען בהצלחה נגיע ל – handleFileLoad ובה נוסיף את התוכן החדש למערך התמונות שלנו.

var assets = [];
function handleFileLoad(event) {
    assets.push(event.item);
}

לפני שנמשיך לאיך מציגים את התמונות הנוספות אציג את הרקעים שנשתמש בהם:

רצפה image כפי שניתן לראות מהתמונה מדובר על חלק קטן של הריצפה – אנחנו נראה איך לשכפל אותו בצורה קלה על מנת ליצור רצפה רצופה לאורך המשחק.
הרים SNAGHTML99495bb  
שמש (לוגו של Super 8) image  
שמיים

image

 

אחרי שכל הקבצים נטענו והוכנסו למערך  assets, אשר להתחיל למקם אותם על המסך.

נוסיף את פונקציית handleComplete, ונרוץ על כל האובייקטים שהוכנסו ל – assets, ספריית PreloadJS לא רק טענה את התמונות ברקע אלא גם שייכה אותם לקבוצות לפי סוג הקובץ וכל אובייקט שנטען קיבל מאפיין ייחודי (id), בשורות הראשונות אנחנו נוציא את מאפיין ה – id של כל אובייקט שנטען ונשתמש בפונקציית getResult על מנת לקבל את האובייקט.

כאשר נגיע לאובייקט – ground, אנחנו רוצים לצייר רצפה לאורך כל אורך המשחק שלנו, אז ראשית ניצור אובייקט חדש מסוג – Shape ונצייר עליו את התמונה, שימו לב שאורך התמונה ה – w שמציין את אורך המשחק (Canvas), התוצאה שאנחנו נראה לא תהיה מריחה של התמונה ל – 600 פיקסלים אלא שיכפול של התמונה לאורך זה.

לבסוף נוסיף את אובייקט ה – ground ל – stage (כפי שעשינו בפוסטים קודמים) ונתחיל את שעון המשחק.

דוגמא 1

 

function handleComplete() {
    buildPlayerSprite();

    for (var i = 0; i < assets.length; i++) {
        var item = assets[i];
        var _id = item.id;
        var result = loader.getResult(_id);

        if (item.type == createjs.LoadQueue.IMAGE) {
            var bmp = new createjs.Bitmap(result);
        }

        switch (_id) {          
            case "ground":
                ground = new createjs.Shape();
                var g = ground.graphics;
                g.beginBitmapFill(result);
                g.drawRect(0, 0, w, 79);
                ground.y = h - 79;
                break;          
        }
    }

    stage.addChild(ground, player);

    player.gotoAndPlay("walk_h");
    
    var fieldValue = id("fps");
    var fps = parseInt(fieldValue.value);

    createjs.Ticker.setFPS(fps);
    createjs.Ticker.useRAF = true;
    createjs.Ticker.addEventListener("tick", tick);
}

דוגמא 1

image

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

בתוך פונקציית tick, נוסיף את השורה הבאה – אשר תזיז את הרצפה 10 פיקסלים לאחור.

function tick() {
          var outside = w + 20;
        var position = player.x + player.vX;

        player.x = (position >= outside) ? -200 : position;
        ground.x = (ground.x - 10);

    }
    stage.update();
}

דוגמא – 2

עכשיו אפשר לראות את הרצפה מתקדמת יחד עם תזוזת הדמות אבל היא חתוכה בהתחלה שלה, מה שצריך לעשות הוא להגדיל את רוחב הרצפה בצורה הבאה:

case "ground":
    ground = new createjs.Shape();
    var g = ground.graphics;
    g.beginBitmapFill(result);
    g.drawRect(0, 0, w+330, 79);
    ground.y = h - 79;
    break;

פשוט הוספתי עוד 330 פיקסלים לרוחב התמונה, אבל גם זה לא פתור את הבעיה, אחרי הכל הרצפה עדיין תעלם מהמסך, נוסיף את השורה הבא תחת פונקציית tick ובעזרת מודולו של תוספת הרוחב שהוספנו נדאג שה – x לעולם לא יצא מגבולות המסך.

ground.x = (ground.x - 10) % 330;

דוגמא – 3

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

* שימו לב שנרשמתי ל – stage.addEventListener("stagemousedown,  אשר יאפשר לנו לדעת מתי לחצו על ב – Canvas ונוכל לבצע פעולות קפיצה.

function handleComplete() {
    buildPlayerSprite();

    for (var i = 0; i < assets.length; i++) {
        var item = assets[i];
        var _id = item.id;
        var result = loader.getResult(_id);

        if (item.type == createjs.LoadQueue.IMAGE) {
            var bmp = new createjs.Bitmap(result);
        }

        switch (_id) {
            case "sky":
                var g = new createjs.Graphics()
                g.beginBitmapFill(result);
                g.drawRect(0, 0, w * 2, h)
                sky = new createjs.Shape(g);
                break;
            case "ground":
                ground = new createjs.Shape();
                var g = ground.graphics;
                g.beginBitmapFill(result);
                g.drawRect(0, 0, w + 330, 79);
                ground.y = h - 79;
                break;
            case "hill":
                hill = new createjs.Shape(new createjs.Graphics().beginBitmapFill(result).drawRect(0, 0, w, 159));
                hill.x = 0;
                hill.scaleX = 3;
                hill.y = 163;
                break;
            case "sun":
                var g = new createjs.Graphics();
                g.beginBitmapFill(result);
                g.drawRect(0, 0, 129, 129);
                sun = new createjs.Shape(g);
                sun.x = w;
                sun.y = 37;
                break;
        }
    }

    stage.addChild(sky, ground, hill, sun, player);

    player.gotoAndPlay("walk_h");
    stage.addEventListener("stagemousedown", function () {
        play("jump_h");
    });

    var fieldValue = id("fps");
    var fps = parseInt(fieldValue.value);

    createjs.Ticker.setFPS(fps);
    createjs.Ticker.useRAF = true;
    createjs.Ticker.addEventListener("tick", tick);
}

לבסוף נשנה את פונקציית tick, שתזיז את שאר האובייקטים במשחק.

ב – tick יש חישוב של outside , כלומר מתי האובייקט נמצא מחוץ למסך, כאשר נראה שאובייקט יצא החוצה נוכל להחזיר אותו ע”י שינוי מאפיין – x

function tick() {
    if (_action.indexOf("walk") != -1 || _action.indexOf("jump") != -1) {

        var outside = w + 20;
        var position = player.x + player.vX;

        player.x = (position >= outside) ? -200 : position;

        sky.x = (sky.x - 5) % w;
        hill.x = (hill.x - 2) % w;
        ground.x = (ground.x - 10) % 330;

        sun.x = (sun.x - 1);
        if (sun.x <= -135) { sun.x = outside + 50; }

    }
    stage.update();
}

לדוגמא המלאה

Add comment
facebook linkedin twitter email

Leave a Reply