main.js

1 lines UTF-8 Unix (LF)
1
/** 
 * @preserve Made by mos@dbwebb.se
 *
 * Using code from example programs:
 * - example/getSize
 * - example/fillWithDivs
 * - example on classList?
 */
window.lawnMower = (function(){
    'use strict';

    var windowWidth     = window.innerWidth,
        windowHeight    = window.innerHeight,
        lawnArea        = document.getElementById("lawnArea"),
        lawnMower       = document.getElementById("lawnMower"),
        lawnMowerAudio  = document.getElementById("lawnMowerAudio"),
        lawnMowerWidth  = lawnMower.offsetWidth,
        lawnMowerHeight = lawnMower.offsetHeight,
        lawnMowerPosX   = 0,
        lawnMowerPosY   = 0,
        lawnMaxX        = 0,
        lawnMaxY        = 0,
        lawnMowerSpeed  = 30,
        lawnMowerDirection = 0, // degrees
        lawnMowerGear   = 0, 
        lawnMowerSound  = true, 
        lawnMowerEngine = false,
        lawnMowerRunState = false,
        lastGameTick    = null,
        td              = null,
        gameLoopId      = null,
        lawnLevel       = {
            "level1":       0,
            "level2":       0,
            "doneLevel1":   0,
            "doneLlevel2":  0
        };

    //console.log("Browser area are width x height: " + windowWidth + " x " + windowHeight);



    /**
     * Create a lawn id.
     */
    var createLawnId = function (x, y) {
        if (x > lawnMaxX) {
            lawnMaxX = x;            
        }

        if (y > lawnMaxY) {
            lawnMaxY = y;            
        }

        return "pos" + x + "x" + y;
    };



    /**
     * Get a lawn id from any position
     */
    var getLawnId = function (x, y) {
        var x1 = 0,
            y1 = 0;

        if( x !== 0) {
            x1 = Math.floor(x / 10) * 10;
        }

        if (y !== 0) {
            y1 = Math.floor(y / 10) * 10;
        }

        if (x1 > lawnMaxX) {
            x1 = lawnMaxX;
        }

        if (y1 > lawnMaxY) {
            y1 = lawnMaxY;
        }

        return "pos" + x1 + "x" + y1;
    };



    /**
     * Check what item the mower is upon and take action.
     */
    var collisionDetection = function (id) {
        var element = document.getElementById(id);

        if (element.classList.contains("border")) {
            return handlerBorderDetected();
        }        
        else if (element.classList.contains("level2")) {
            element.classList.remove("level2");
            lawnLevel.level2--;
            return true;
        }        
        else if (element.classList.contains("level1")) {
            element.classList.remove("level1");
            lawnLevel.level1--;
            return true;
        }

        return true;
    };




    /**
     * Check what item the mower is upon and take action.
     */
    var handlerBorderDetected = function () {

        console.log("Border detected");

        return false;
    };



    /**
     * Check what item the mower is upon and take action.
     */
    var collisionDetectionMower = function (x, y) {
        var id1 = null,
            id2 = null,
            id3 = null,
            id4 = null,
            test1 = null,
            test2 = null,
            test3 = null,
            test4 = null;

        x = Math.round(x + lawnMowerWidth / 2);
        y = Math.round(y + lawnMowerHeight / 2);
        id1 = getLawnId(x-10, y);
        id2 = getLawnId(x, y-10);
        id3 = getLawnId(x+10, y);
        id4 = getLawnId(x, y+10);
        test1 = collisionDetection(id1);
        test2 = collisionDetection(id2);
        test3 = collisionDetection(id3);
        test4 = collisionDetection(id4);

        return test1 && test2 && test3 && test4;
    };



    /**
     * Place out the border as a rectangle relative mower position.
     */
    var drawBorderRectangle = function (startX, startY, endX, endY) {
        var x = null,
            y = null,
            element = null,
            id = null,
            x1 = null,
            x2 = null,
            y1 = null,
            y2 = null;

        console.log("Drawing a rectangle border.");

        x1 = Math.floor(lawnMowerPosX + lawnMowerWidth / 2 + startX * 10);
        y1 = Math.floor(lawnMowerPosY + lawnMowerHeight / 2 + startY * 10);

        x2 = x1 + endX * 10;
        y2 = y1 + endY * 10;

        for (x = x1; x <= x2; x += 10) {

            id = getLawnId(x, y1);
            element = document.getElementById(id);
            element.classList.add("border");

            id = getLawnId(x, y2);
            element = document.getElementById(id);
            element.classList.add("border");
        }

        for (y = y1; y <= y2; y += 10) {

            id = getLawnId(x1, y);
            element = document.getElementById(id);
            element.classList.add("border");

            id = getLawnId(x2, y);
            element = document.getElementById(id);
            element.classList.add("border");
        }

        console.log("Done drawing border.");
    };



    /**
     * Place out the grassplants to make a lawn.
     */
    var initLawn = function () {
        var x = null,
            y = null,
            element = null,
            i = 0;

        console.log("Planting grass plants on the lawn... please wait...");

        for (x = 0; x <= windowWidth - 10; x+=10) {
            for (y = 0; y <= windowHeight - 10; y+=10) {
                element = document.createElement("div");
                lawnLevel.level1++;
                lawnLevel.level2++;
                element.classList.add("grass", "level1", "level2");
                element.id  = createLawnId(x, y);
                element.style.top  = y + "px";
                element.style.left = x + "px";
                lawnArea.appendChild(element);
                i++;
            }
        }

        console.log("Done. Inited lawn by placing " + i + " grass plants.");
    };



    /**
     * Move - or place out - the grasslawner.
     */
    var placeLawnMower = function (x, y) {

        // Provide default values to missing arguments
        x = (x === undefined) ? windowWidth / 2 : x;
        y = (y === undefined) ? windowHeight / 2 : y;

        console.log("Placing the lawn mower with its center at position x, y: " + x + ", " + y);

        // Respect the size of the lawn mower when placing it
        lawnMowerPosX = Math.round(x - lawnMowerWidth / 2);
        lawnMowerPosY = Math.round(y - lawnMowerHeight / 2);

        console.log("Lawn mower has dimensions of width x height: " + lawnMowerWidth + " x " + lawnMowerHeight);
        console.log("Placing the lawn mower at left, top: " + lawnMowerPosX + ", " + lawnMowerPosY);
        
        lawnMowerMove(lawnMowerPosX, lawnMowerPosY);

        console.log("Done.");
    };



    /**
     * Set speed for lawn mower, if argument is sent. Return current speed.
     */
    var setSpeed = function (speed) {
        if (speed >= 1 && speed <= 100) {
            lawnMowerSpeed = speed;
            console.log("Set speed to " + lawnMowerSpeed);
        }

        console.log("Current speed is " + lawnMowerSpeed);
        return lawnMowerSpeed;
    };



    /**
     * Set direction for lawn mower, where its front points, if argument is present. 
     * Return current value.
     */
    var setDirection = function (direction) {
        if (direction >= -360 && direction <= 360) {
            lawnMowerDirection = direction;
            lawnMower.style.transform = "rotate(" + lawnMowerDirection + "deg)";
            console.log("Set direction to " + lawnMowerDirection);
        }

        console.log("Current direction is " + lawnMowerDirection);
        return lawnMowerDirection;
    };



    /**
     * Set the gear 0 (neutral), back=-1 or forward=1. 
     */
    var setGear = function (gear) {
        console.log("Gear is: " + lawnMowerGear);

        if (gear === -1 || gear === 0 || gear === 1) {
            lawnMowerGear = gear;
            console.log("Setting gear to:" + lawnMowerGear);
            console.log("Available gears are: 0 (neutral), back=-1 or forward=1");
        }

        return lawnMowerGear;
    };



    /**
     * Start the sound (true), or shut it off (false). The sound can only be on when the engine is started.
     */
    var setSound = function (level) {
        
        level = level || !lawnMowerSound;

        console.log("Sound is: " + lawnMowerSound);

        if (level === false) {
            // Shut off sound
            lawnMowerSound = level;
            console.log("Pausing sound.");
            lawnMowerAudio.pause();
        }
        //else if (level === true && lawnMowerEngine === true && lawnMowerSound === false) {
        else if (level === true && lawnMowerEngine === true) {
            // Start sound
            lawnMowerSound = level;
            console.log("Playing sound.");
            lawnMowerAudio.play();
        }

        console.log("Setting sound to:" + lawnMowerSound);

        return lawnMowerSound;
    };



    /**
     * Start engine. 
     */
    var startEngine = function () {
        lawnMowerEngine = true;
        setGear(0);
        setSound(true);
        console.log("Started engine, brumm, brumm");
    };



    /**
     * Start engine. 
     */
    var stopEngine = function () {
        lawnMowerEngine = false;
        setGear(0);
        setSound(false);
        console.log("Stopped engine. The silence is golden.");
    };



    /**
     * Move forward or backward where direction is 1 or -1
     */
    var moveMower = function (td, direction) {
        var radians = lawnMowerDirection * Math.PI / 180,
            lookaheadX = 0,
            lookaheadY = 0;

        if (!lawnMowerEngine) {
            console.log("Can not move, the engine is not started.");
            return false;
        }

        lookaheadX = lawnMowerPosX + direction * lawnMowerSpeed * Math.cos(radians) * td;
        lookaheadY = lawnMowerPosY + direction * lawnMowerSpeed * Math.sin(radians) * td;
        
        if (!collisionDetectionMower(lookaheadX, lookaheadY)) {
            console.log("Can not move in direction " + direction + ". Setting gear to neutral.");
            setGear(0);
            return false;
        }

        lawnMowerPosX = lookaheadX;
        lawnMowerPosY = lookaheadY;

        lawnMowerMove();

        return true;
    };



    /**
     * Move forward. 
     */
    var moveForward = function (td) {
        return moveMower(td, 1);
    };



    /**
     * Move backward. 
     */
    var moveBackward = function (td) {
        return moveMower(td, -1);
    };



    /**
     * Move lawn mower to current position. 
     */
    var lawnMowerMove = function () {
        lawnMower.style.left = lawnMowerPosX + "px";
        lawnMower.style.top  = lawnMowerPosY + "px";
    };



    /**
     * Current state of the lawn mower. 
     */
    var lawnMowerStatus = function () {
        console.log("Engine is on: " + lawnMowerEngine);
        console.log("Run state is on: " + lawnMowerRunState);
        console.log("Speed is: " + lawnMowerSpeed);
        console.log("Direction is: " + lawnMowerDirection);
        console.log("Position is x,y: " + lawnMowerPosX + ", " + lawnMowerPosX);
        console.log("Gear is: " + lawnMowerGear);
        console.log("Sound is on: " + lawnMowerSound);
        console.log("Lawn level is: ");
        console.log(lawnLevel);
    };



    /**
     * Make the lawn mower go by itself. 
     */
    var lawnMowerRun = function (run) {
        if (!lawnMowerEngine) {
            console.log("Can not run, the engine is not started.");
            return;
        }
        
        lawnMowerRunState = (run === undefined) ? !lawnMowerRunState : run;

        console.log("Run state is " + lawnMowerRunState);

        if (lawnMowerRunState) {
            gameLoopId = window.requestAnimationFrame(gameLoop);
            console.log("Gameloop started");
        } else {
            console.log("Stopping runstate");
        }
    };



    /**
     * The game loop. 
     */
    var gameLoop = function () {
        var now = Date.now();
        td = (now - (lastGameTick || now)) / 1000;
        lastGameTick = now;

        if (lawnMowerEngine === false || lawnMowerRunState === false) {
            window.cancelAnimationFrame(gameLoopId);
            td = null;
            lastGameTick = null;
            console.log("Engine/Runstate was stopped, gameloop is cancelled");
            return;
        }

        gameLoopId = window.requestAnimationFrame(gameLoop);
        update(td);
    };



    /**
     * Update one game tick. 
     */
    var update = function (td) {

        if (lawnMowerGear === 1) {
            moveForward(td);
        } else if (lawnMowerGear === -1) {
            moveBackward(td);
        }
    };



    /**
     * Click to make lawn mower go in a specific direction. 
     */
    lawnArea.addEventListener("click", function (event) {
        var theta;

        console.log("Clicked with the mouse at x,y: " + event.clientX + ", " + event.clientY);
        theta = Math.atan2(event.clientY - lawnMowerPosY, event.clientX - lawnMowerPosX);
        setDirection(theta * 180 / Math.PI);
    });




    /**
     * Click to make lawn mower go in a specific direction. 
     */
    document.addEventListener("keydown", function (event) {
        var key;

        // Get which key was pressed       
        key = event.keyCode || event.which;
        console.log("Pressed key: " + key); 

        switch (key) {
            case 49: // 1
                console.log("Toggle start and stop");
                if (lawnMowerEngine) {
                    stopEngine();
                } else {
                    startEngine();
                }
            break;

            case 50: // 2
                console.log("Toggle run and paus");
                lawnMowerRun();
            break;

            case 51: // 3
                console.log("Gear forward");
                setGear(1);
            break;

            case 52: // 4
                console.log("Gear neutral");
                setGear(0);
            break;

            case 53: // 5
                console.log("Gear back");
                setGear(-1);
            break;

            case 54: // 6
                console.log("Display status");
                lawnMowerStatus();
            break;

            case 48: // 0
                console.log("Toggle sound");
                setSound();
            break;

            case 72: // h
                console.log("Display helptext");
                help();
            break;

            case 37: // Left arrow
            case 65: // a
                console.log("Turn left");
                setDirection(lawnMowerDirection - 15);
            break;

            case 39: // Right arrow
            case 68: // d
                console.log("Turn right");
                setDirection(lawnMowerDirection + 15);
            break;

            case 38: // Up  arrow
                console.log("Increase throttle");
                setSpeed(lawnMowerSpeed + 5);
            break;

            case 40: // Down arrow
                console.log("Decrease throttle");
                setSpeed(lawnMowerSpeed - 5);
            break;
        }
    });



    // längd gått
    // tid passerad
    // procent klippt
    // gräns
    // gränsavkännare


    /**
     * The game loop. 
     */
    var help = function () {
        console.log(" ");
        console.log("HELP ON USAGE");
        console.log("The lawn mower object is stored as:");
        console.log("- window.lanMover");
        console.log("- m (shortcut to window.lanMover)");
        console.log(" ");
        console.log("Functions to use on the object:");
        console.log(" lawnMover.init()     // Inits the lawnmover with the environment.");
        console.log(" lawnMover.place()    // Places the lawnMover at its start position.");
        console.log(" lawnMover.start()    // (1) Start the engine.");
        console.log(" lawnMover.stop()     // (1) Stop the engine.");
        console.log(" lawnMover.run()      // (2) Move and cut the grass, or paus if already running.");
        console.log(" lawnMover.gear(val)  // (3, 4, 5) Change gear. val is integer -1, 0, 1");
        console.log(" lawnMover.speed(val) // (arrow up, arrow down) Change speed). val is integer -1, 0, 1");
        console.log(" lawnMover.status()   // (6) Show the current status.");
        console.log(" lawnMover.sound(val) // (0) Use sound by setting val to true or false.");
        console.log(" lawnMover.help()     // Display this helptext.");
        console.log(" ");
        console.log("Mouse and keyboard connections:");
        console.log(" left-click mouse  // Change direction.");
    };



    /**
     * All done, return object exposing functions and variables to the outside world.
     */ 
    console.log("Lawn mower is ready!");
    console.log(help());

    return {
        "element":      lawnMower,
        "speed":        setSpeed,
        //"direction":    setDirection,
        "init":         initLawn,
        "place":        placeLawnMower,
        "start":        startEngine,
        "stop":         stopEngine,
        //"forward":      moveForward,
        //"back":         moveBackward,
        "run":          lawnMowerRun,
        "gear":         setGear,
        "sound":        setSound,
        "status":       lawnMowerStatus,
        "border":       drawBorderRectangle,
        "help":         help
    };
})();



/**
 * Now you can use the lawnmover by callings its functions from the console.
 */
//window.lawnMower.init();
//window.lawnMower.place();

var m = window.lawnMower;

m.init();
m.place();
//m.start();
//m.sound(false);
//m.run();
m.border(-20, -20, 40, 40);

//lawnMower.run();