SOURCE

console 命令行工具 X clear

                    
>
console
/*
 build time: Sep 08,2013 21:59
 author: jiejie.zhuo
 email: zhuo-jiejie@foxmail.com
 */
;(function ($) {
    $(function () {
        var imageUrl = "http://sandbox.runjs.cn/uploads/rs/30/7mnuxrh7/";
        var isMobile = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|mobile)/);

        //获取画布对象
        var c = $("#game-box").get(0);
        var c_width = $(c).width();
        var c_height = $(c).height();
        //创建画布
        var cxt = c.getContext("2d");
        //手机屏幕自适应
        (function () {
            $(window).on("resize.plain", resize);
            resize();
            function resize() {
                $(c).attr("height", $(window).height() < 800 ? $(window).height() : 800);
                $(c).attr("width", $(window).width() < 480 ? $(window).width() : 480);
                c_width = $(c).width();
                c_height = $(c).height();
                cxt.font = "30px Microsoft YaHei";
                cxt.fillStyle = "#333";
            }
        })();
        //图片资源, 存放图片对象
        var sources = [];

        //新建图片方法
        function creatImg(src) {
            if (typeof sources[src] != "undefined") {
                return sources[src];
            }

            sources[src] = new Image();
            sources[src].src = src;
            return sources[src];
        }

        //图片预加载方法
        function loadImages(images, callback) {
            var loadedImages = 0;
            var numImages = images.length;
            for (var i in images) {
                sources[images[i]] = new Image();
                sources[images[i]].onload = function () {
                    loadedImages++;
                    if (loadedImages >= numImages) {
                        callback();
                    }
                };
                sources[images[i]].src = imageUrl + images[i];
            }
        }

        //页面开始执行方法
        (function () {
            var images = ['bg.jpg', 'loading1.png', 'loading2.png', 'loading3.png', 'logo.png'];
            loadImages(images, loading);
        })();

        //等待动画
        function loading() {
            var loadingTime = 0;

            var refresh = function () {
                drawBg();
                drawLogo();
                load();
                loadingTime++;
            }
            var loadingClock = setInterval(refresh, 1);

            function drawBg() {
                var bg_img = creatImg("bg.jpg");
                var bg_img_width = bg_img.width;
                var bg_img_height = bg_img.height;
                cxt.drawImage(bg_img, 0, 0, bg_img_width, bg_img_height);
            }

            function drawLogo() {
                var logo_img = creatImg("logo.png");
                var logo_width = logo_img.width;
                var logo_height = logo_img.height;

                var x = (c_width - logo_width) / 2;
                var y = 100;
                cxt.drawImage(logo_img, x, y, logo_width, logo_height);
            }

            function load() {
                if (loadingTime == 600) {
                    loadingTime = 0;
                }

                var pic = creatImg("loading" + (parseInt(loadingTime / 200) + 1) + ".png");
                var pic_width = pic.width;
                var pic_height = pic.height;

                var x = (c_width - pic_width) / 2;
                cxt.drawImage(pic, x, 220, pic_width, pic_height);
            }

            var images = ['cartridge.png', 'cartridge_power.png', 'die1.png', 'die2.png', 'me.png', 'plain1.png', 'plain2.png', 'plain3.png', 'plain2_hurt.png', 'plain3_hurt.png', 'plain1_die1.png', 'plain1_die2.png', 'plain1_die3.png', 'plain2_die1.png', 'plain2_die2.png', 'plain2_die3.png', 'plain2_die4.png', 'plain3_die1.png', 'plain3_die2.png', 'plain3_die3.png', 'plain3_die4.png', 'plain3_die5.png', 'plain3_die6.png', 'me_die1.png', 'me_die2.png', 'me_die3.png', 'me_die4.png', 'prop1.png', 'prop2.png', 'bomb.png', 'me_2.png', 'plain3_2.png'];
            
            //游戏开始方法
            loadImages(images, function () {
                main();
                clearInterval(loadingClock);
            });
        }

        //游戏方法
        function main() {
            var modal = {
                "show": function (s) {
                    $("#modal").find(".content").html(s);
                    $("#modal").removeClass("hide");
                },
                "hide": function () {
                    $("#modal").addClass("hide");
                }
            };
            var bg_img = creatImg("bg.jpg");
            var bg_img_width = bg_img.width;
            var bg_img_height = bg_img.height;
            cxt.drawImage(bg_img, 0, 0, bg_img_width, bg_img_height);

            var me = {};
            me.x;
            me.y;
            me.lastX;
            me.lastY;
            me.bomb = 0;
            me.status = true;
            me.model = creatImg("me.png");
            me.model2 = creatImg("me_2.png");
            me.width = c_width / 480 * me.model.width;
            me.height = me.width / me.model.width * me.model.height;
            me.move = function (x, y) {
                me.lastX = me.x;
                me.lastY = me.y;
                me.x = x - me.width / 2;
                me.y = y - me.height / 2;
                me.x = me.x > c_width - me.width ? c_width - me.width : me.x;
                me.x = me.x < 0 ? 0 : me.x;
                me.y = me.y > c_height - me.height ? c_height - me.height : me.y;
                me.y = me.y < 0 ? 0 : me.y;
            }
            me.moveing = function () {
                if (!me.status) {
                    return;
                }
                
                cxt.drawImage(game.time % 30 > 15 ? me.model : me.model2, me.x, me.y, me.width, me.height);
                me.attacking();
            }
            me.cartridges = [];
            me.cartridge = function (x, y) {
                var cartridgeModel = creatImg(me.attackPower ? "cartridge_power.png" : "cartridge.png");

                this.model = cartridgeModel;
                
                this.width = c_width / 480 * cartridgeModel.width;
                this.height = this.width / cartridgeModel.width * cartridgeModel.height;

                this.x = x + (me.width - this.width) / 2;
                this.y = y - this.height;
            }
            me.attackTime = 0;
            me.attackPower = false;
            me.attack = function () {
                if (!me.status) {
                    return;
                }

                me.attackTime++;
                if (me.attackTime % 14 != 0) {
                    return;
                }

                me.attackTime = 0;
                var cartridge;
                if(me.attackPower) {
                    cartridge = [(new me.cartridge(me.x - (me.width / 5), me.y)), (new me.cartridge(me.x + (me.width / 5), me.y))];
                } else {
                    cartridge = [(new me.cartridge(me.x, me.y))];
                }
                Array.prototype.push.apply(me.cartridges, cartridge);
            }
            me.attacking = function () {
                me.attack();
                var cartridgeSpeed = 10;
                for(var cartridgeIndex = me.cartridges.length; cartridgeIndex--;) {
                    var cartridge = me.cartridges[cartridgeIndex];
                    cxt.drawImage(cartridge.model, cartridge.x, cartridge.y, cartridge.width, cartridge.height);
                    if (cartridge.y <= 0) {
                        me.cartridges.splice(cartridgeIndex, 1);
                        continue;
                    }

                    for(var plainIndex = game.plains.length; plainIndex--;) {
                        var plain = game.plains[plainIndex];
                        var X = cartridge.x;
                        var nextY = cartridge.y - cartridgeSpeed;
                        if (
                            X > plain.x
                         && X < (plain.x + plain.width)
                         && nextY < (plain.y + plain.height + plain.speed)
                         && cartridge.y >= (plain.y + plain.height)
                        ) {
                            plain.byAttack();
                            me.cartridges.splice(cartridgeIndex, 1);
                        }
                    }

                    cartridge.y = cartridge.y - cartridgeSpeed;  //子弹向上移动
                }
            }
            me.die = function () {
                if (!me.status) {
                    return;
                }

                me.status = false;
                var dieSpeed = 20;
                var x = this.x;
                var y = this.y;
                var h = this.height;
                var w = this.width;

                game.plainsDies.push((new die()));

                function die() {
                    var dieTime = 4 * dieSpeed;
                    this.animationTime = 4 * dieSpeed;

                    this.call = function () {
                        if (this.animationTime == 1) {
                            game.over();
                        }
                        var dieModel = creatImg("me_die" + (parseInt((dieTime - this.animationTime) / dieSpeed) + 1) + ".png");
                        cxt.drawImage(dieModel, x, y, w, h);
                        this.animationTime--;
                    }
                }
            }

            var game = {};
            game.score = 0;
            game.me = me;
            game.time = 0;
            game.refreshInterval = 8;
            game.refresh = function () {
                game.time++;
                game.bgScroll();
                game.plainsScroll();
                game.plainsDying();
                game.me.moveing();
                game.propShow();
                game.refreshMessage();          
            }
            game.bgScrollTime = 0;
            game.bgScroll = function () {
                game.bgScrollTime += 0.5;
                if (game.bgScrollTime > bg_img_height) {
                    game.bgScrollTime = 0;
                }
                cxt.drawImage(bg_img, 0, game.bgScrollTime - bg_img_height, bg_img_width, bg_img_height);
                cxt.drawImage(bg_img, 0, game.bgScrollTime, bg_img_width, bg_img_height);
            }
            game.prop = function (type) {
                this.type = type;
                this.status = "show";
                this.isDeleted = false;
                this.modelImg;
                switch(type) {
                    case 1:
                        this.modelImg = "prop1.png";
                        break;
                    case 2:
                        this.modelImg = "prop2.png";
                        break;
                }
                this.model = creatImg(this.modelImg);
                this.width = c_width / 480 * this.model.width;
                this.height = this.model.height / this.model.width * this.width;
                this.x = Math.random() * (c_width - this.width);
                this.y = -this.height;

                var speed = this.speed = 6;
                var animateTime = this.animateTime = 70;
                this.showType = "down";
                this.show = function () {
                    if(this.animateTime <= animateTime / 2) {
                        this.showType = "up";
                    }
                    cxt.drawImage(this.model, this.x, this.y, this.width, this.height);
                    if(isGain(this)) {
                        this.isDeleted = true;
                        this.byGain();
                        return;
                    }
                    var move = ((c_height + this.height) / 3) / (animateTime / 2);
                    this.speed = move;
                    if(this.showType == "down") {
                        this.y += move; 
                    } else {
                        this.y -= move; 
                    }
                    this.animateTime--;
                    if(this.animateTime <= 0) {
                        this.speed = speed;
                        this.status = "move";
                    }
                }
                this.move = function () {
                    this.y += this.speed;
                    cxt.drawImage(this.model, this.x, this.y, this.width, this.height);
                    if(isGain(this)) {
                        this.isDeleted = true;
                        this.byGain();
                        return;
                    }
                }

                this.byGain = function () {
                    switch(this.type) {
                        case 1:
                            game.me.bomb++;
                            break;
                        case 2:
                            game.me.attackPower = true;
                            game.me.attackPowerClock = setTimeout(function () {
                                game.me.attackPower = false;
                            }, 15000);
                            break;
                    }
                }

                //判断有没有吃到道具
                var isGain = function(prop) {
                    var leftX = prop.x;
                    var rightX = prop.x + prop.width;
                    if(rightX < game.me.x || leftX > (game.me.x + game.me.width)) {
                        return false;
                    }
                    var removing = prop.status == "move" ? prop.speed : (prop.showType == "down" ? prop.speed : -prop.speed);
                    var nextY = prop.y + removing;
                    if(((prop.y + prop.height) > game.me.y || (nextY + prop.height) < game.me.y) && game.me.lastY > (prop.y + prop.height)) {
                        return false;
                    }
                    return true;
                }
            }
            game.addProp = function () {
                var interval = 25;
                if((game.time * game.refreshInterval) % (interval * 1000) == 0) {
                    game.props.push((new game.prop(parseInt(Math.random() * 1.8 + 1.1))));
                }
            }
            game.props = [];
            game.propShow = function () {
                game.addProp();
                for(var propIndex = game.props.length; propIndex--;) {
                    var prop = game.props[propIndex];
                    if(prop.isDeleted == true) {
                        game.props.splice(propIndex, 1);
                        continue;
                    }

                    prop[prop.status]();

                    if(prop.y > c_height) {
                        game.props.splice(propIndex, 1);
                    }
                }
            }
            game.useBomb = function () {
                if(game.me.bomb <= 0) {
                    return;
                }
                game.me.bomb--;
                for(var plainIndex = game.plains.length; plainIndex--;) {
                    var plain = game.plains[plainIndex];
                    plain.die();
                }
            }
            game.plains = [];
            game.plainsNum = 0;
            game.addPlain = function () {
                if (game.bgScrollTime % 30 != 0) {
                    return;
                }

                if (game.plainsNum == 26) {
                    game.plainsNum = 0;
                }

                game.plainsNum++;
                switch (true) {
                    case game.plainsNum % 13 == 0:
                        game.plains.push(new plain(3));
                        break;
                    case game.plainsNum % 6 == 0:
                        game.plains.push(new plain(2));
                        break;
                    default:
                        game.plains.push(new plain(1));
                        break;
                }
            }
            game.plainsScroll = function () {
                game.addPlain();
                for(var plainIndex = game.plains.length; plainIndex--;) {
                    var plain = game.plains[plainIndex];
                    if (plain.y > c_height || plain.status == false) {
                        game.plains.splice(plainIndex, 1);
                        continue;
                    }

                    plain.show();
                    
                    if (isCollide(plain)) {
                        game.me.die();
                    }

                    plain.y = plain.y + plain.speed;
                }

                //判断是否和玩家的飞机碰撞
                function isCollide(plain) {
                    var plainTopLeft = [plain.x, plain.y];
                    var plainBottomRight = [plain.x + plain.width, plain.y + plain.height];
                    var meTopLeft = [game.me.x + game.me.width / 3, game.me.y];
                    var meBottomRight = [game.me.x + (game.me.width * 2 / 3), game.me.y + (game.me.height * 2 / 3)];

                    var collideTopLeft = [Math.max(plainTopLeft[0], meTopLeft[0]), Math.max(plainTopLeft[1], meTopLeft[1])];
                    var collideBottomRight = [Math.min(plainBottomRight[0], meBottomRight[0]), Math.min(plainBottomRight[1], meBottomRight[1])];

                    if (collideTopLeft[0] < collideBottomRight[0] && collideTopLeft[1] < collideBottomRight[1]) {
                        return true;
                    }

                    return false;
                }
            }
            game.plainsDies = [];
            game.plainsDying = function () {
                for(var plainDieIndex = game.plainsDies.length; plainDieIndex--;) {
                    var plainDie = game.plainsDies[plainDieIndex];
                    if (plainDie.animationTime == 0) {
                        game.plainsDies.splice(plainDieIndex, 1);
                        return;
                    }
                    plainDie.call();
                }
            }
            game.over = function () {
                $(c).removeClass("playing");
                if(isMobile) {
                    c.removeEventListener("touchmove");
                } else {
                    $(c).off("mousemove");
                }
                $(c).off("click");
                clearInterval(game.clock);
                modal.show(game.score);
            }
            game.clear = function () {
                game.me.x = (c_width - game.me.width) / 2;
                game.me.y = c_height - game.me.height;

                game.plains = [];
                game.plainsDies = [];
                game.plainsNum = 0;
                game.time = 0;
                game.bgScrollTime = 0;
                game.score = 0;
                game.me.status = true;
                game.me.bomb = 0;
                game.me.attackPower = false;
                clearTimeout(game.me.attackPowerClock);
            }
            game.start = function () {
                $(c).addClass("playing");
                $(c).on("click", function (e) {
                    game.useBomb();
                });
                if(isMobile) {
                    c.addEventListener("touchmove", function (e) {
                        e.preventDefault();
                        var touch = e.targetTouches[0];
                        var x = touch.pageX - $(this).offset().left;
                        var y = touch.pageY;
                        me.move(x, y);
                    });
                } else {
                    $(c).on("mousemove", function (e) {
                        var x = e.clientX - $(this).offset().left;
                        var y = e.clientY;
                        me.move(x, y);
                    })
                }

                modal.hide();
                game.clear();
                game.clock = setInterval(function () {
                    game.refresh();
                }, game.refreshInterval);
            }
            game.refreshMessage = function () {
                cxt.fillText(game.score, 20, 44);

                if(game.me.bomb > 0) {
                    var bombModel = creatImg("bomb.png");
                    cxt.drawImage(bombModel, 10, c_height - bombModel.height - 10, bombModel.width, bombModel.height);
                    cxt.fillText(game.me.bomb, 20 + bombModel.width, c_height - bombModel.height + 28);
                }
            }
            game.start();

            //飞机类
            function plain(type) {
                this.type = type;

                this.hp;  //飞机生命值
                this.height;
                this.width;
                this.maxSpeed;
                this.dieTime;
                this.status = true;  //飞机死了没
                var dieSpeed = 20;  //死亡动画播放速度

                switch (type) {
                    case 1:
                        this.hp = 1;
                        this.score = 1000;
                        this.maxSpeed = 5;
                        this.dieTime = dieSpeed * 3;
                        break;
                    case 2:
                        this.hp = 8;
                        this.score = 8000;
                        this.maxSpeed = 2;
                        this.dieTime = dieSpeed * 4;
                        break;
                    case 3:
                        this.hp = 18;
                        this.score = 30000;
                        this.maxSpeed = 1;
                        this.dieTime = dieSpeed * 6;
                        break;
                }

                this.modelimg = "plain" + this.type + ".png";
                this.model = creatImg(this.modelimg);

                if(this.type == 3) {
                    this.modelimg2 = "plain3_2.png";
                    this.model2 = creatImg(this.modelimg2);
                }

                this.width = c_width / 480 * this.model.width;
                this.height = this.width / this.model.width * this.model.height;

                this.x = Math.random() * (c_width - this.width);
                this.y = -(this.height);

                var maxSpeed = game.time / 1000 > 10 ? 10 : game.time / 1000;
                this.speed = Math.random() * (maxSpeed - 1) + 1;
                this.speed = this.speed < 0.5 ? Math.random() * 0.5 + 0.5 : this.speed;
                this.speed = this.speed > this.maxSpeed ? this.maxSpeed : this.speed;

                this.show = function () {
                    if(this.type == 3) {
                        cxt.drawImage(game.time % 30 > 15 ? this.model : this.model2, this.x, this.y, this.width, this.height);
                        return;
                    }
                    cxt.drawImage(this.model, this.x, this.y, this.width, this.height);
                }

                this.die = function () {
                    var plainType = this.type;
                    var plainX = this.x;
                    var plainY = this.y;
                    var plainW = this.width;
                    var plainH = this.height;

                    game.plainsDies.push((new die(this.dieTime)));
                    
                    game.score += this.score;
                    this.status = false;

                    function die(dieTime) {
                        var dieTime = dieTime;
                        this.animationTime = dieTime;

                        this.call = function () {
                            if (this.animationTime <= 0) {
                                return;
                            }
                            var dieModel = creatImg("plain" + plainType + "_die" + (parseInt((dieTime - this.animationTime) / dieSpeed) + 1) + ".png");
                            cxt.drawImage(dieModel, plainX, plainY, plainW, plainH);
                            this.animationTime--;
                        }
                    }
                }

                var hp = this.hp;
                this.byAttack = function () {
                    this.hp--;
                    if (this.hp <= 0) {
                        this.die();
                        return;
                    }

                    if (this.hp <= hp / 3) {
                        this.model = creatImg("plain" + this.type + "_hurt.png");
                    }
                }
            }

            $("#modal").on("click", "button", function () {
                game.start();
            });
        }
    });
})(jQuery);
<div id="main">
            <div id="modal" class="hide">
                <div class="header">飞机大战分数</div>
                <div class="content" id="content">0</div>
                <div class="footer">
                    <button>继 续</button>
                </div>
            </div>
            <canvas id="game-box"></canvas>
        </div>
/*
 build time: Sep 08,2013 21:59
 author: jiejie.zhuo
 email: zhuo-jiejie@foxmail.com
 */
* {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

body {
    margin: 0;
    padding: 0;
    font-size: 14px;
    color: #333;
    font-family: "Microsoft YaHei", sans-serif, 'Microsoft Sans Serif', 'Microsoft JhengHei UI';
    background-color: #555;
}

#main {
    width: 480px;
    margin: 0 auto;
}

#main canvas.playing {
    cursor: none;
}

#modal {
    width: 400px;
    height: 300px;
    top: 100px;
    left: 50%;
    margin-left: -200px;
    border: #666 solid 2px;
    border-radius: 8px;
    position: absolute;
    font-size: 20px;
    background-color: #dddddd;
    z-index: 1002;
}

@media screen and (max-width: 480px) {
    #main, #container {
        width: 100%;
    }

    #modal {
        width: 94%;
        top: 10px;
        left: 3%;
        margin: 0;
    }
}

#modal.hide {
    display: none;
}

#modal .header {
    height: 45px;
    line-height: 45px;
    font-weight: bold;
    text-align: center;
    border-bottom: #666 solid 2px; 
}

#modal .content {
    height: 210px;
    line-height: 210px;
    font-weight: bold;
    text-align: center;
}

#modal .footer {
    height: 45px;
    line-height: 45px;
    text-align: center;
    border-top: #666 solid 2px; 
}

#modal .footer button {
    width: 120px;
    height: 30px;
    border: #666 solid 2px;
    border-radius: 15px;
    font-size: 15px;
    font-weight: bold;
    position: absolute;
    bottom: 4px;
    left: 50%;
    margin-left: -60px;
    color: #333;
    cursor: pointer;
}

本项目引用的自定义外部资源