Escapa

Escapa is a classic reaction game, and uses most functions of the MC engine.

Code

// MC Library
// Escapa Example
// 03 Jan 2019


window.onload = (function() {

// AQUIRE HTML DOM CANVAS REFERENCE
//     HTML has to have a HTML5 canvas element tagged as "canvas"
var c=document.getElementById("canvas");

//////////////////////////
// INITIALISE MC Engine //
//////////////////////////
// CHOOSE 1 // 

// CHOICE 1: Canvas Size fixed by HTML
MC.init(c);

// CHOICE 2: Full Window Option (Canvas will be resized to fit window)
//MC.init(c,"fullWindow");

///////////////////////////
// END OF Initialisation //
///////////////////////////
//-----------------------------------------------------------------------------
//////////////////////////
// VARIABLE DECLARATION //
//////////////////////////

// screenset up .. 900x700 canvas ... 500x500 central game bounds
MC.canvas.setSize(900,700);
MC.game.setBounds(1/7,6/7,2/9,7/9);

// Game state tracker
var Screen = 0; // 0 = Start (awaiting click to start). 1 = Game Running.  2 = Finished awaiting restart

// required variables
var time = 0;
var oldTime = 0;
var bestTime = 0;
var velocities = [200,250,300,350,400,450];
var offset = new MC.Point();
var instructions1 = "Welcome to Escapa.  Click and drag the red square to start";
var instructions2 = "Dodge the black walls and blue blocks as long as you can";
var instructions3 = "Click anywhere to reset";
// Typefaces to be used
var typeWhite = new MC.Typeface("Trebuchet MS",20,"White");
var typeBlack = new MC.Typeface("Trebuchet MS",26,"Black");
// "Reset Button"
var button = new MC.ConBox();
button.setValues({ width: 120,
                   height: 32,
                   text: "Reset Record",
                   pos: new MC.Point(MC.canvas.right - 60, MC.canvas.top - 29),
                   onClick: function () {bestTime = 0;},
                   colorBody: new MC.Color(0,0,0,0)  });
//SpriteBins
var walls = new MC.SpriteBin();
var blocks = new MC.SpriteBin();

// Sprite Generation (do one, clone and customise, clone and customise etc .. then push to SpriteBin)
/////
// Walls
////
var twall = new MC.Sprite({type: "rect",
                          size1: 500,
                          size2: 50,
                          fillColor: "Black",
                          edgeColor: null,
                          edgeWidth: 0,
                          mobile: false,
                          pos: new MC.Point(MC.canvas.midX,MC.canvas.top + 25)
                           });
var bwall = twall.clone();
bwall.setValues({   pos: new MC.Point(MC.canvas.midX,MC.canvas.bottom - 25) });

var lwall = twall.clone();
lwall.setValues({   size1: 50,
                    size2: 500,
                    pos: new MC.Point(MC.canvas.left + 25,MC.canvas.midY)
                });

var rwall = lwall.clone();
rwall.setValues({   pos: new MC.Point(MC.canvas.right - 25,MC.canvas.midY)  });

walls.push(twall,bwall,lwall,rwall);

/////
// Blocks
////
var block1 = new MC.Sprite({type: "rect",
                           size1: 70,
                           size2: 70,
                           fillColor: "DarkBlue",
                           edgeColor: null,
                           edgeBounce: true,   
                            });
var block2 = block1.clone();
    block2.setValues({  size2: 50});
var block3 = block1.clone();
    block3.setValues({  size1: 35 });
var block4 = block1.clone();
    block4.setValues ({ size1: 120,
                        size2: 20, });
blocks.push(block1,block2,block3,block4);

/////
// Player
////
var player = new MC.Sprite({
                            type: "rect",
                            size1: 40,
                            size2: 40,
                            fillColor: "DarkRed",
                            edgeColor: null
                            });
// Game Reset Call .. this one to "initialise" the game
reset();

///////////////////
// GAME FUNCTION DECLARATIONS
//////////////////

// Customise the Engine mouse Event Listener
MC.mouse.onClickL = function () {
    // did we click the button?                        
    button.checkClick();
    
    // game starts
    if (Screen == 0 && player.hit(MC.game.mouse)) { 
        offset = player.pos.clone().minus(MC.game.mouse);
        Screen = 1;
        MC.game.paused = false;
        time = 0;
    }
    
    // game over awaiting reset
    if (Screen == 2) { 
        reset();
    }

};

// Reset (positions and velocities to start, variables as required)
function reset() {
    // Blocks back to start positions
    block1.setValues({  vel: new MC.Point(40,35),
                        pos: new MC.Point (MC.canvas.left + 110, MC.canvas.top + 110) });
    block2.setValues({  pos: new MC.Point (MC.canvas.right - 160, MC.canvas.top + 90),
                        vel: new MC.Point(-35,40)   });
    block3.setValues({  pos: new MC.Point(MC.canvas.left + 90, MC.canvas.bottom - 110),
                        vel: new MC.Point(35,-40)   });
    block4.setValues({  pos: new MC.Point(MC.canvas.right - 110, MC.canvas.bottom - 110),
                        vel: new MC.Point(-40,-35)  });
    // Blocks back to start Velocity
    setVelocities(velocities[0]);
    
    // Player back to middle
    player.moveTo(new MC.Point(MC.canvas.midX,MC.canvas.midY));
    
    // Paused game - Deltatime not refreshed
    MC.game.paused = true;
    
    Screen = 0;
    time = 0;
    oldTime = 0;
}

// gameOver
function gameOver() {
    Screen = 2;
    MC.game.paused = true;
}

// Called in GameLoop() .. changes block velocity on 5 second increments
function checkForSpeedChange() {
    var v = 0;
    var change = false;
    if (time >= 5 && oldTime < 5) {
        v = velocities[1];
        change = true;
    }
    else if (time >= 10 && oldTime < 10) {
        v = velocities[2];
        change = true;
    }
    else if (time >= 15 && oldTime < 15) {
        v = velocities[3];
        change = true;
    }
    else if (time >= 20 && oldTime < 20) {
        v = velocities[4];
        change = true;
    }
    else if (time >= 25 && oldTime < 25) {
        v = velocities[5];
        change = true;
    }
    if (change) {
        setVelocities(v);
    }
}

// called by above and Reset ... sets the actual block velocities
function setVelocities (value) {
    block1.vel.setLength(value);
    block2.vel.setLength(value);
    block3.vel.setLength(value);
    block4.vel.setLength(value);
}

//////////////////////////
// END OF declarations  //
//////////////////////////
//-----------------------------------------------------------------------------
//////////////////////////
//      GAME LOOP       //
//////////////////////////
// first call, request subsequently made within
gameLoop(); 

function gameLoop() {

    requestAnimationFrame(gameLoop);   
    // Essential to update MC.game to ensure MC.game.deltaTime is available
    MC.game.update();
    
    // physicsUpdate Loop
    for (var z = 0; z < MC.game.physicsUpdates; z++)
    {
        blocks.update();
        
        if (Screen == 1) {
            player.moveTo(MC.game.mouse.clone().add(offset));
            if (player.hit(walls) || player.hit(blocks) ) {
                gameOver();
            }
            oldTime = time;
            time += MC.game.deltaTime;
            checkForSpeedChange();            
            bestTime = MC.maths.maxOf(time,bestTime);
        }
    }
    
    // Once only per frame button/GUI update
    button.update();
    
    // Add Render / Draw Code here
    MC.draw.clearCanvas("Olive");   // All canvas to "Olive"
    MC.draw.clearInBounds("Ivory"); // Game in-bounds set to "Ivory"
    
    // SpriteBins, Sprites and Button Renders
    walls.render();
    blocks.render();
    player.render();
    button.render();
    
    // Text Banners
    var t = time.toFixed(2);
    var t2 = bestTime.toFixed(2);
    MC.draw.text("Time: "+t, new MC.Point(MC.canvas.left + 3, MC.canvas.bottom - 3),typeWhite);
    MC.draw.text("Session record: "+t2+" secs", new MC.Point(MC.canvas.left + 3, 85),typeBlack);
    if (Screen == 0) {
        MC.draw.text(instructions1,new MC.Point(100,635),typeBlack);
        MC.draw.text(instructions2,new MC.Point(100,665),typeBlack);
    }
    if (Screen == 2) {
        MC.draw.text(instructions3,new MC.Point(100,650),typeBlack);
    }
}

}); // EoF