问题标题: 飞机大战砖头版

2
2

0
1
1
阿巴
阿巴
资深守护
资深守护

js编的

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>飞机大战</title>
    </head>

    <body>
        <div id="stage" style="margin: 0 auto; width: 480px; height: 650px; text-align: center; vertical-align: middle" >
            <canvas id="canvas" style="border:0px solid red;" width="480" height="650">
                不支持画板对象
            </canvas>
        </div>
        <script>
            var canvas = document.getElementById('canvas');
            var ctx = canvas.getContext('2d');

            var background = new Image();
            background.src = "images/background.png";

            var sky = new Sky();
            
            var e1 = [];
            e1[0] = new Image();
            e1[0].src = "images/enemy1.png";
            e1[1] = new Image();
            e1[1].src = "images/enemy1_down1.png";
            e1[2] = new Image();
            e1[2].src = "images/enemy1_down2.png";
            e1[3] = new Image();
            e1[3].src = "images/enemy1_down3.png";
            e1[4] = new Image();
            e1[4].src = "images/enemy1_down4.png";
            
            var e2 = [];
            e2[0] = new Image();
            e2[0].src = "images/enemy2.png";
            e2[1] = new Image();
            e2[1].src = "images/enemy2_down1.png";
            e2[2] = new Image();
            e2[2].src = "images/enemy2_down2.png";
            e2[3] = new Image();
            e2[3].src = "images/enemy2_down3.png";
            e2[4] = new Image();
            e2[4].src = "images/enemy2_down4.png";
            
            var e3 = [];
            e3[0] = new Image();
            e3[0].src = "images/enemy3_n1.png";
            e3[1] = new Image();
            e3[1].src = "images/enemy3_n2.png";
            e3[2] = new Image();
            e3[2].src = "images/enemy3_down1.png";
            e3[3] = new Image();
            e3[3].src = "images/enemy3_down2.png";
            e3[4] = new Image();
            e3[4].src = "images/enemy3_down3.png";
            e3[5] = new Image();
            e3[5].src = "images/enemy3_down4.png";
            e3[6] = new Image();
            e3[6].src = "images/enemy3_down5.png";
            e3[7] = new Image();
            e3[7].src = "images/enemy3_down6.png";
            
            var h = [];
            h[0] = new Image();
            h[0].src = "images/hero1.png";
            h[1] = new Image();
            h[1].src = "images/hero2.png";
            h[2] = new Image();
            h[2].src = "images/hero_blowup_n1.png";
            h[3] = new Image();
            h[3].src = "images/hero_blowup_n2.png";
            h[4] = new Image();
            h[4].src = "images/hero_blowup_n3.png";
            h[5] = new Image();
            h[5].src = "images/hero_blowup_n4.png";
            
            var copyright = new Image();
            copyright.src = "images/shoot_copyright.png";
            
            var pause = new Image();
            pause.src = "images/game_pause_nor.png";
            
            //创建数组b,存储子弹图片
            var b = [];
            b[0] = new Image();
            b[0].src = "images/bullet1.png";
            b[1] = new Image();
            b[1].src = "images/bullet2.png";
            
            var enemies = [];    
            var hero = new Hero(0,0,99,124,1,h,2);
            var bullets = [];
            var score = 0;
            var heroes = 3;
            //声明变量START,表示游戏开始
            var START = 1;
            //声明变量RUNNING,表示游戏运行状态
            var RUNNING = 2;
            //声明变量PAUSE,表示游戏暂停状态
            var PAUSE = 3;
            //声明变量GAME_OVER,表示游戏结束状态
            var GAME_OVER = 4;
            //声明state,表示游戏状态,默认是开始状态
            var state = START;
            setInterval(function() {
                /*
                componentEnter();
                hero.shoot();
                checkHit();
                componentStep();
                paintComponent(ctx);
                deleteComponent();
                */
                /*//判断飞机大战游戏中的各个状态
                switch(state){
                    case START:
                        //开始游戏
                        sky.paint(ctx);
                        sky.step();
                        var x = 20;
                        var y = 130;
                        ctx.drawImage(copyright,x,y);
                        break;
                    case RUNNING:
                        //运行游戏
                        paintComponent(ctx);
                        sky.step();
                        componentStep();
                        componentEnter();
                        hero.shoot();
                        checkHit();
                        deleteComponent();
                        break;
                    case PAUSE:
                        //暂停游戏
                        paintComponent(ctx);
                        sky.step();
                        ctx.drawImage(pause,0,0);
                        break;
                    case GAME_OVER:
                        //游戏结束
                        paintComponent(ctx);
                        sky.step();
                        var x = 480/2 - 245/2;
                        var y = 852*(1-0.6);
                        ctx.font = "40px 微软雅黑";
                        ctx.fillText("GAME OVER",x,y);
                        break;
                }*/
                controlState(ctx);
            }, 10);
            
            //定义controlState方法
            function controlState(ctx){
                //判断飞机大战游戏中的各个状态
                switch(state){
                    case START:
                        //开始游戏
                        sky.paint(ctx);
                        sky.step();
                        var x = 20;
                        var y = 130;
                        ctx.drawImage(copyright,x,y);
                        break;
                    case RUNNING:
                        //运行游戏
                        paintComponent(ctx);
                        sky.step();
                        componentStep();
                        componentEnter();
                        hero.shoot();
                        checkHit();
                        deleteComponent();
                        break;
                    case PAUSE:
                        //暂停游戏
                        paintComponent(ctx);
                        sky.step();
                        ctx.drawImage(pause,0,0);
                        break;
                    case GAME_OVER:
                        //游戏结束
                        paintComponent(ctx);
                        sky.step();
                        var x = 480/2 - 245/2;
                        var y = 852*(1-0.6);
                        ctx.font = "40px 微软雅黑";
                        ctx.fillText("GAME OVER",x,y);
                        break;
                }
            }
            
            //鼠标点击画布,游戏开始
            canvas.onclick = function(){
                if(state ==  START){
                    state = RUNNING;
                }
            }
            
            //鼠标离开游戏界面,游戏暂停
            canvas.onmouseout = function(){
                if(state == RUNNING){
                    state = PAUSE;
                }
            }
            
            //鼠标进入游戏界面,游戏继续
            canvas.onmouseover = function(){
                if(state == PAUSE){
                    state = RUNNING;
                }
            }

            function isActionTime(lastTime, interval) {
                if (lastTime == 0) {
                    return true;
                }
                var currentTime = new Date().getTime();
                return currentTime - lastTime >= interval;
            }

            var lastTime = 0;
            var interval = 400;
            function componentEnter() {
                if (! isActionTime(lastTime, interval)) {
                    return;
                }
                lastTime = new Date().getTime();
                var n = parseInt(Math.random() * 10);
                switch(n) {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        enemies[enemies.length] = new Enemy(0, -51, 57, 51, 1, 1, 1, e1, 1);
                        break;
                    case 8:
                        enemies[enemies.length] = new Enemy(0, -95, 69, 95, 2, 3, 5, e2, 1);
                        break;
                    case 9:
                        if (enemies[0] == undefined || enemies[0].type != 3) {
                            enemies.splice(0, 0, new Enemy(0, -258, 169, 258, 3, 20, 20, e3, 2));
                        }
                }
            }

            function componentStep() {
                sky.step();
                for (var i = 0; i < enemies.length; i++) {
                    enemies[i].step();
                }
                for(var i = 0; i < bullets.length; i++){
                    bullets[i].step();
                }
                hero.step();
            }

            function paintComponent(ctx) {
                /*
                if (! isActionTime(paintLastTime, paintInterval)) {
                    return;
                }
                paintLastTime = new Date().getTime();
                */
                sky.paint(ctx);
                for (var i = 0; i < enemies.length; i++) {
                    enemies[i].paint(ctx);
                }
                for(var i = 0; i < bullets.length; i++){
                    bullets[i].paint(ctx);
                }
                hero.paint(ctx);
                ctx.font = "20px 微软雅黑";
                ctx.fillText("SCORE:"+score,10,20);
                ctx.fillText("LIFE:"+heroes,400,20);
            }

            function Sky() {
                this.img = background;
                this.width = 480;
                this.height = 852;
                this.x1 = 0;
                this.y1 = 0;
                this.x2 = 0;
                this.y2 = -this.height;
                this.interval = 400;
                this.lastTime = 0;
                this.paint = function(ctx) {
                    ctx.drawImage(this.img, this.x1, this.y1);
                    ctx.drawImage(this.img, this.x2, this.y2);
                }
                this.step = function() {
                    if (! isActionTime(this.lastTime, this.interval)) {
                        return;
                    }
                    this.lastTime = new Date().getTime();
                    this.y1 = this.y1 + 1;
                    this.y2 = this.y2 + 1;
                    if (this.y1 > this.height) {
                        this.y1 = -this.height;
                    }
                    if (this.y2 > this.height) {
                        this.y2 = -this.height;
                    }
                }
            }
            
            function getPointOnCanvas(x,y){
                var bbox = canvas.getBoundingClientRect();
                return {
                    x:x-bbox.left,
                    y:y-bbox.top
                };
            }
            
            canvas.onmousemove = function(e){
                //运行状态下,英雄机跟随鼠标移动
                if(state ==  RUNNING){
                    var mpoint = getPointOnCanvas(e.x,e.y);
                    hero.x = mpoint.x - hero.width/2;
                    hero.y = mpoint.y - hero.height/2;    
                }
                
            }
            
            function FlyingObject(x,y,width,height,life,frames,baseFrameCount){
                this.x = x;
                this.y = y;
                this.width = width;
                this.height = height;
                this.life = life; 
                this.interval = 10;
                this.lastTime = 0;
                this.down = false;
                this.canDelete = false;
                /*
                 * 定义frames属性,存储所有的动画帧,是一个数组
                 * 正常运算期间循环显示基本动画帧,当this.down为true的时候,
                 * 开始显示销毁动画帧,销毁动画显示完毕之后就可以从界面上消除了。
                 */
                this.frames = frames;
                //定义img属性,表示当前显示的动画帧,默认显示第一帧
                this.img = this.frames[0];
                //定义frameIndex属性,表示动画帧序号,运算期间不断增加
                this.frameIndex = 0;
                //定义frameCount属性,表示基本动画帧数量
                this.frameCount = baseFrameCount;
                this.paint = function(ctx){
                    ctx.drawImage(this.img,this.x,this.y);
                }
                this.step = function() {
                    if (! isActionTime(this.lastTime, this.interval)) {
                        return;
                    }
                    this.lastTime = new Date().getTime();
                    if(this.down){
                        /*
                         * 判断动画帧序号是否与frames数组的长度相等,若相等,
                         * 说明销毁动画已播放完毕,标记该对象为可删除状态.
                         */
                        if(this.frameIndex == frames.length){
                            this.canDelete = true;
                        }else{
                            this.img = this.frames[this.frameIndex];
                            this.frameIndex++;
                        }
                    }else{
                        this.move();
                        //控制基本动画的播放
                        this.img = this.frames[this.frameIndex%this.frameCount];
                        this.frameIndex++;
                    }
                }
                this.move = function(){
                    this.y++;
                }
                this.hit = function(component){
                    var c = component;
                    return c.x>this.x-c.width&&c.x<this.x+this.width&&
                           c.y>this.y-c.height&&c.y<this.y+this.height;
                }
                this.bang = function(){
                    this.life--;
                    if(this.life == 0){
                        this.down = true;
                        if(this.score){
                            score = score + this.score;
                        }
                        //开始播放销毁动画
                        this.frameIndex = this.frameCount;
                    }
                }
                this.outOfBounds = function(){
                    return this.y >= 852;
                }
            }
            
            function Enemy(x,y,width,height,type,life,score,frames,baseFrameCount){
                FlyingObject.call(this,x,y,width,height,life,frames,baseFrameCount);
                this.x = Math.random() * (480 - this.width);
                this.y = -this.height;
                this.score = score;
                this.type = type;
            }
            
            function Hero(x,y,width,height,life,frames,baseFrameCount){
                FlyingObject.call(this,x,y,width,height,life,frames,baseFrameCount);
                this.x = 480/2 - this.width/2;
                this.y = 650 - this.height - 30;
                this.shootInterval = 300;
                this.shootLastTime = 0;
                this.shoot = function(){
                    if(!isActionTime(this.shootLastTime,this.shootInterval)){
                        return;
                    }
                    this.shootLastTime = new Date().getTime();
                    //bullets[bullets.length] = new Bullet(this.x+45,this.y,9,21,1,b,2);
                    bullets[bullets.length] = new Bullet(this.x+45,this.y,9,21,1,b,1);
                }
                this.move = function(){
                    
                }
            }
            
            function Bullet(x,y,width,height,life,frames,baseFrameCount){
                FlyingObject.call(this,x,y,width,height,life,frames,baseFrameCount);
                this.move = function(){
                    this.y -= 2;
                }
                this.outOfBounds = function() {                  
                    return this.y < -height;
                }
            }
            
            function checkHit(){
                for(var i = 0; i < enemies.length; i++){
                    var enemy = enemies[i];
                    if(enemy.canDelete||enemy.down){
                        continue;
                    }
                    for(var j = 0; j < bullets.length; j++){
                        var bullet = bullets[j];
                        /*
                         * 判断子弹是否为可删除或者下落状态,若满足其中之一
                         * 则跳过当次循环进入下一次循环.
                         */
                        //if(bullet.canDelete){
                            //continue;
                        //}
                        if(bullet.canDelete || bullet.down){
                            continue;
                        }
                        if(enemy.hit(bullet)){
                            enemy.bang();
                            bullet.bang();
                        }
                    }
                    if(enemy.hit(hero)){
                        enemy.bang();
                        hero.bang();
                    }
                }
            }
            
            function deleteComponent(){
                var ary = [];
                var idx = 0;
                for(var i = 0; i < enemies.length; i++){
                    if(!(enemies[i].canDelete||enemies[i].outOfBounds())){
                        ary[idx] = enemies[i];
                        idx++;
                    }
                }
                enemies = ary;
                ary = [];
                idx = 0;
                for (var i = 0; i < bullets.length; i++) {
                    if (!(bullets[i].canDelete || bullets[i].outOfBounds())) {
                        ary[idx++] = bullets[i];
                    }
                }
                bullets = ary;
                if (hero.canDelete ) {
                    heroes--;
                    if (heroes == 0) {
                        //alert("游戏结束");
                        //当最后一架英雄机牺牲后,将状态state设置为:GAME_OVER
                        state = GAME_OVER;
                    } else {
                        hero = new Hero(0, 0, 99, 124, 1, h, 2);
                    }
                }
            }
        </script>
    </body>
</html>

阿巴在2021-06-06 10:48:49追加了内容

拷到记事本里保存改成html形式即可

0
武建豪
武建豪
中级天翼
中级天翼

有时候好卡,是操作的问题吗

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
黄硕梁
黄硕梁
初级天翼
初级天翼

要不是这个名字

我还以为不是老师

0
李子杰
李子杰
资深光能
资深光能

有结束吗???

李子杰在2021-06-05 15:52:39追加了内容

常常会卡!!!

时间太长了!!!

0
我要回答