SOURCE

console 命令行工具 X clear

                    
>
console
/****** 2017/7/19   by cK-round ******/

var canvas = document.getElementById("canvas"),
    submit = document.getElementById("submit"),
    h3 = document.getElementsByTagName("h3"),
    infor = document.getElementById("box3"),
    p = infor.getElementsByTagName("p"),
    w = 550,
    h = 690,
    circles = [],
    timer,
    timer2,
    timer3,
    timer4,
    flage = false,
    lKey = false,
    rKey = false,
    tKey = false,
    bKey = false,
    timestamp1,
    timestamp2;

// 创建背景(canvastext)对象
var ctx = canvas.getContext("2d");

// 创建渐变
var bgcChange = ctx.createLinearGradient(0, h, 0, 0);
bgcChange.addColorStop(0, "#aaa");
bgcChange.addColorStop(1, "#fff");

// 填充渐变
ctx.fillStyle = bgcChange;
ctx.fillRect(0, 0, w, h);

submit.onclick = function() {
    clearInterval(timer);
    clearTimeout(timer2);
    //clearTimeout(timer3);
    clearInterval(timer4);
    canvas.style.cursor = "none";
    infor.style.display = "none";
    var setBallNum = document.getElementById("ballNum1"),
        setRadius = document.getElementById("radius1"),
        setSpeed = document.getElementById("speed1"),
        ballNum, r, speed;
    circles.splice(0, circles.length);
    r = parseInt(setRadius.value);

    var minX = r,
        maxX = w - r,
        minY = r,
        maxY = h - r;

    ballNum = parseInt(setBallNum.value);
    speed = parseFloat(setSpeed.value);

    if (isNaN(speed) || isNaN(ballNum) || isNaN(r) || speed <= 0 || ballNum <= 0 || r <= 0) {
        h3[0].innerHTML = '提示:请输入有效参数!';
    } else {
        timestamp1 = new Date().getHours() * 3600 + new Date().getMinutes() * 60 +
            new Date().getSeconds() + new Date().getMilliseconds() / 1000;
        h3[0].innerHTML = '提示:开始后你有三秒的准备时间。';

        timer3 = setTimeout(function() {
            flage = true;
            h3[0].innerHTML = '提示:你可以通过方向键或W/A/S/D进行控制。';
        }, 2990);
        if (!flage) {
            began(circles, ballNum, r, speed, minX, maxX, minY, maxY, timestamp1);
        }
    }
    return timestamp1;
};

canvas.onclick = function() {
    if (!flage) {
        submit.onclick();
    }
};

function began(circles, ballNum, r, speed, minX, maxX, minY, maxY, timestamp1) {

    //获取鼠标在canvas上的坐标
    canvas.onmousemove = function(e) {
        var loc = windowToCanvas(canvas, e.clientX || e.x, e.clientY || e.y);
        circles[ballNum].x = loc.x;
        circles[ballNum].y = loc.y;
    };

    function windowToCanvas(canvas, x, y) {
        var bbox = canvas.getBoundingClientRect();
        return {
            x: x - bbox.left * (w / bbox.width),
            y: y - bbox.top * (h / bbox.height)
        };
    }


    for (var i = 0; i < ballNum + 1; i++) {

        // 红球
        circles[i] = {
                x: w * Math.random(), //圆心的x轴坐标值
                y: h * Math.random(), //圆心的y轴坐标值
                velocityX: speed * Math.random(),
                velocityY: speed * Math.random(),
                color: 'red'
            },

            circles[i].x < minX || circles[i].x > maxX ? circles[i].x = minX : circles[i].x,
            circles[i].y < minY || circles[i].y > maxY ? circles[i].y = minY : circles[i].y;
    }

    // 蓝球
    circles[ballNum] = {
        x: 1,
        y: 1,
        velocityX: 0,
        velocityY: 0,
        color: 'blue'
    };

    timer = setInterval(function() {

        //清除画布内容
        ctx.clearRect(0, 0, w, h);

        // 填充渐变
        ctx.fillStyle = bgcChange;
        ctx.fillRect(0, 0, w, h);
        ctx.shadowColor = 'rgb(0,0,0)';
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;
        ctx.shadowBlur = 8;

        //填充球
        circles.forEach(function(b) {

            //开始一个新的绘制路径
            ctx.beginPath();
            ctx.arc(b.x, b.y, r, 0, Math.PI * 2, false);
            ctx.fillStyle = b.color;
            ctx.closePath();
            ctx.fill();
            collision(circles, r);
            boundary(b);
            timer2 = setTimeout(function() {
                move(b);
            }, 3000);
        });
    }, 1);


    document.onkeydown = function(event) {

        // console.log((event || window.event).keyCode + " is down");
        var keyCode = (event || window.event).keyCode;
        switch (keyCode) {
            case 37: //left
                lKey = true;
                break;
            case 38: //top
                tKey = true;
                break;
            case 39: //right
                rKey = true;
                break;
            case 40: //bottom
                bKey = true;
                break;
            case 65: //left
                lKey = true;
                break;
            case 87: //top
                tKey = true;
                break;
            case 68: //right
                rKey = true;
                break;
            case 83: //bottom
                bKey = true;
                break;
        }
    };

    document.onkeyup = function(event) {

        // console.log((event || window.event).keyCode + " is up");
        var keyCode = (event || window.event).keyCode;
        switch (keyCode) {
            case 13:
                if (!flage) {
                    submit.onclick();
                }
                break;
            case 37: //left
                lKey = false;
                break;
            case 38: //top
                tKey = false;
                break;
            case 39: //right
                rKey = false;
                break;
            case 40: //bottom
                bKey = false;
                break;
            case 65: //left
                lKey = false;
                break;
            case 87: //top
                tKey = false;
                break;
            case 68: //right
                rKey = false;
                break;
            case 83: //bottom
                bKey = false;
                break;
        }
    };

    timer4 = setInterval(function() {
        if (lKey) {
            circles[ballNum].x = circles[ballNum].x - 2;
        }
        if (rKey) {
            circles[ballNum].x = circles[ballNum].x + 2;
        }
        if (tKey) {
            circles[ballNum].y = circles[ballNum].y - 2;
        }
        if (bKey) {
            circles[ballNum].y = circles[ballNum].y + 2;
        }
    }, 1);

    //边界判定
    function boundary(b) {
        if (b.x + b.velocityX > maxX) b.x = maxX;
        if (b.x + b.velocityX < minX) b.x = minX;
        if (b.y + b.velocityY > maxY) b.y = maxY;
        if (b.y + b.velocityY < minY) b.y = minY;
        if (b.x + b.velocityX > maxX || b.x + b.velocityX < minX) b.velocityX = -b.velocityX;
        if (b.y + b.velocityY > maxY || b.y + b.velocityY < minY) b.velocityY = -b.velocityY;
    }

    //运动
    function move(b) {
        if (b != circles[ballNum]) {
            b.x += b.velocityX;
            b.y += b.velocityY;
        }
    }

    //碰撞判定
    function collision(circles, r) {
        if (flage) {
            circles.forEach(
                function(b1) {
                    circles.forEach(
                        function(b2) {
                            var rc = Math.ceil(Math.sqrt(Math.pow(b1.x - b2.x, 2) + Math.pow(b1.y - b2.y, 2)));
                            if (b1 !== b2) {
                                if (rc < r * 2) {

                                    //获取碰撞后的速度增量
                                    var ax = ((b1.velocityX - b2.velocityX) * Math.pow((b1.x - b2.x), 2) +
                                            (b1.velocityY - b2.velocityY) * (b1.x - b2.x) * (b1.y - b2.y)) / Math.pow(rc, 2),
                                        ay = ((b1.velocityY - b2.velocityY) * Math.pow((b1.y - b2.y), 2) +
                                            (b1.velocityX - b2.velocityX) * (b1.x - b2.x) * (b1.y - b2.y)) / Math.pow(rc, 2);

                                    //将速度增量赋给碰撞小球
                                    b1.velocityX -= ax;
                                    b1.velocityY -= ay;
                                    b2.velocityX += ax;
                                    b2.velocityY += ay;

                                    //修正小球碰撞距离
                                    var clength = r - rc / 2;
                                    var cx = clength * (b1.x - b2.x) / rc,
                                        cy = clength * (b1.y - b2.y) / rc;
                                    b1.x += cx;
                                    b1.y += cy;
                                    b2.x -= cx;
                                    b2.y -= cy;

                                    //碰到蓝球
                                    if (b1 == circles[ballNum] && b2 != circles[ballNum] && Math.ceil(rc) < r * 2 ||
                                        b1 != circles[ballNum] && b2 == circles[ballNum] && Math.ceil(rc) < r * 2) {
                                        timestamp2 = new Date().getHours() * 3600 + new Date().getMinutes() * 60 +
                                            new Date().getSeconds() + new Date().getMilliseconds() / 1000 - 3;
                                        flage = false;
                                        clearInterval(timer);
                                        clearTimeout(timer2);
                                        //clearTimeout(timer3);
                                        clearInterval(timer4);
                                        canvas.style.cursor = "pointer";
                                        var duration = Math.floor((timestamp2 - timestamp1) * 1000) / 1000;
                                        h3[0].innerHTML = '提示:你可以通过点击左边的游戏区再次进行游戏。';
                                        p[0].innerHTML = '半径(像素): ' + r +
                                            '<br/>挑战球数(个): ' + ballNum +
                                            '<br/>最大初速度(像素/微秒): ' + speed +
                                            '<br/>挑战计时(秒): ' + duration;
                                        console.log({
                                            '时间': duration,
                                            '半径': r,
                                            '球数': ballNum,
                                            '速度': speed
                                        });
                                        infor.style.display = "block";
                                    }
                                }
                            }
                        }
                    );
                }
            );
        }
    }
}
 <div id="box1">
        <canvas id='canvas' width='550' height='690'>
            <h1>提示:你的浏览器不支持canvas标签!</h1>
        </canvas>
    </div>
    </canvas>
    <div id="box2">
        <form>
            <h1>躲避红球</h1>
            <h2>参数设置</h2>
            <p>
                半径(像素):
            </p>
            <p>
                <input id="radius1" type="text" placeholder="请输入半径" value="15">
            </p>
            <p>
                红球数(个):
            </p>
            <p>
                <input id="ballNum1" type="text" placeholder="请输入球数" value="6">
            </p>
            <p>
                最大初速度(像素/微秒):
            </p>
            <p>
                <input id="speed1" type="text" placeholder="" value="1.5">
            </p>
            <p>
                <input id="submit" type="button" value="提交参数">
                <input type="reset" value="重置参数">
                <!-- <input type="reset" value="重置参数" onclick="history.go(0)"> -->
            </p>
            <h3>提示:你可以通过点击左边的游戏区进行游戏。</h3>
            <hr>
            <div id="box3">
                <h1>游戏结束!</h1>
                <p></p>
            </div>
        </form>
    </div>
html,
body {
    overflow: hidden;
    width: 100%;
    height: 100%;
    background-color: #123;
    color: #eee;
}

div {
    display: inline-block;
}

#box1 {
    width: 550px;
    height: 690px;
}

#box2 {
    margin-left: 68px;
    position: absolute;
}

#box3 {
    display: none;
}

#canvas {
    cursor: pointer;
    margin: 0;
    padding: 0;
    border: thin solid #eee;
}

#box3 p {
    line-height: 2;
}