JavaScript实现飞机大战_js飞机大战代码

在这里插入图片描述

绘制我方飞机

//创建我机
Plane.prototype.createMyPlane=function() {
    var image,myPlane,sx=0,sy=0,sWidth=132,sHeight=86,dx=200,dy=530,dWidth=132,dHeight=86;
    image = this.imgObj['common']['myplane1'];
    myPlane = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
    this.renderArr2.push(myPlane);
    this.myPlane=myPlane;
    
    //清除自己
    var obj=this;
    myPlane.destory=function(){
        clearInterval(this.timmer);
        clearInterval(this.boomTimmer);
        obj.myPlane=null;
        //游戏结束
        obj.flag='end';
    }
    //爆炸函数
    myPlane.boomIndex=1;
    myPlane.boom=function(){
        obj.boomMusic.play();
        //切换图片,切换完成,清除定时器
        myPlane.boomTimmer = setInterval(doboom,100);
    }

    function doboom(){
        if(myPlane.boomIndex>9){//爆炸完成
            //清除当前飞机
            myPlane.destory();
        }
        myPlane.image = obj.imgObj['myplane'][myPlane.boomIndex++];
    }
}

修改绘制方法

//绘制入口
Plane.prototype.draw=function(){
   this.drawBG();
   this.render();//渲染到页面上
   this.createMyPlane();
   this.render2();
}

运行效果
在这里插入图片描述

鼠标事件(飞机跟随)

  1. 右键事件屏蔽
  2. 加入鼠标移动事件监听
  3. 鼠标移入飞机后,飞机跟随鼠标移动
  4. 边界判断,不允许超出上、下、左、右、边界。
//右键事件
	Plane.prototype.contextMenu=function(e){
		var e = e||window.event;
			//取消右键默认事件
		e.preventDefault && e.preventDefault();
	}

	//鼠标移动事件
	Plane.prototype.mouseMove=function(e){
		var w=132,h=86
		var pos = _.getOffset(e);//获取鼠标位置
		var plane=this.myPlane;
		if(!plane) return ;
		//鼠标在飞机范围内,才会跟随
		if(plane.isPoint(pos)){
			if(isOut.call(this,pos,w,h)){
				return ;
			}
			plane.dx=pos.x-w/2;
			plane.dy=pos.y-h/2;
		}
		//判断超出边界
		function isOut(pos,w,h){
			if(pos.x+w/2>=this.w){//超出右边
				return true;
			}
			if(pos.x-w/2<=0){//超出左边
				return true;
			}
			if(pos.y+h/2>=this.h){//超出下边
				return true;
			}
			if(pos.y-h/2<=0){//超出上边
				return true;
			}

			return false;
		}

	}

  1. 在init方法中加入鼠标监听
//给canvas2画布添加鼠标移动事件(因为画布2在上面)
canvas2.addEventListener('mousemove',this.mouseMove.bind(this));
//给canvas2画布添加鼠标右键事件
canvas2.addEventListener('contextmenu',this.contextMenu.bind(this));

  1. 加入重绘方法
//重新绘制
Plane.prototype.reDraw=function(){
    if(this.flag=='start'){
        this.render2();
    }
}

  1. 加入主线程,用来刷新重绘
//绘制入口
Plane.prototype.draw=function(){
    this.drawBG();
    this.render();//渲染到页面上
    this.createMyPlane();
    this.render2();

    //开启主线程
    this.timmer = setInterval(this.reDraw.bind(this),100);
}

运行效果

在这里插入图片描述

绘制子弹

思路:

  1. 飞机定时创建子单
  2. 每个子单有单独的线程,往上移动
  3. 每次移动后要判断与飞机的碰撞
//创建子弹
Plane.prototype.createBullet=function(plane){
    this.shootMusic.play();
    var image,bullet,sx=0,sy=0,sWidth=20,sHeight=30,dx=0,dy=0,dWidth=20,dHeight=30;
    //计算子弹的位置
    dx=plane.dx+plane.dWidth/2-10;
    dy=plane.dy;
    image = this.imgObj['common']['bullet'];
    bullet = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
    this.renderArr2.push(bullet);
    this.bullets.push(bullet);

    bullet.timmer = setInterval(move.bind(this),80);

    var obj=this;
    bullet.destory=function(){
        clearInterval(bullet.timmer);
        obj.clear(obj.renderArr2,bullet);
        obj.clear(obj.bullets,bullet);
    }

    //子弹的移动
    function move(){
        if(obj.flag!='start'){
            clearInterval(bullet.timmer);
        }
        bullet.dy-=20;
        if(bullet.dy<0){
            //删除当前子弹
            bullet.destory();
            return;
        }

        isHitEnemy(bullet);
    }
    //子弹击中敌机
    function isHitEnemy(bullet){
        var enemys = obj.enemyPlanes;
        var enemy;
        for(var i=0;i<enemys.length;i++){
            enemy=enemys[i];
            if(hitEnemy(bullet,enemy)){//如果某个敌机被击中
                obj.curCount+=10;
                obj.countObj.text=obj.curCount;
                //删除当前子弹
                bullet.destory();
                //飞机爆炸
                enemy.boom();
                if(obj.curCount>obj.count){//胜利
                    clearInterval(obj.myPlane.timmer);
                    obj.endShow('suc');
                    obj.flag='end';
                }
                break;
            }
        }
    }

    function hitEnemy(bullet,enemy){
        //因为子弹比飞机小,所以只需要判断子弹的4个点是否在飞机范围内,如果有则表示碰撞了
        //左上角
        var x1 = bullet.dx;
        var y1 = bullet.dy;
        //右上角
        var x2 = x1+bullet.dWidth;
        var y2 = y1;
        //右下角
        var x3 = x1+bullet.dWidth;
        var y3 = y1+bullet.dHeight;
        //左下角
        var x4 = x1;
        var y4 = y1+bullet.dHeight;
        //只要有一个点在范围内,则判断为碰撞
        if(comparePoint(x1,y1,enemy)|| comparePoint(x2,y2,enemy)||comparePoint(x3,y3,enemy)||comparePoint(x4,y4,enemy) ){
            return true;
        }
        return false;
    }
    //根据坐标判断是否在指定的范围内
    function comparePoint(x,y,plane){
        //大于左上角,小于右下角的坐标则肯定在范围内
        if(x>plane.dx && y >plane.dy
            && x<plane.dx+plane.dWidth && y <plane.dy+plane.dHeight	){
            return  true;
        }
        return false;
    }
}

在这里插入图片描述

定时绘制敌机

  1. 500毫秒创建一个敌机
  2. 有4种敌机,采用随机的方式来获取,创建不同的敌机。
  3. 敌机的x坐标是随机的、y坐标固定为负的图片的宽度。
  4. 飞机创建后开启定时任务向下移动。
  5. 当移动到最下方后,重新回到上方。
  6. 每次移动后会判断是否撞击了我放飞机。
//初始化敌机
Plane.prototype.initEnemyPlane=function(){
    //定时创建敌机
    this.eTimmer = setInterval(this.createEnemyPlane.bind(this),500);
}
//创建敌机
Plane.prototype.createEnemyPlane=function(){
    if(this.flag!='start'){
        clearInterval(this.eTimmer);
    }

    if(this.enemyPlanes.length>10) return ;

    var image,enemyPlane,sx=0,sy=0,sWidth=0,sHeight=0,dx=200,dy=0,dWidth=0,dHeight=0;
    var index = _.getRandom(1,5);

    image = this.imgObj['common']['enemy'+index];
    sWidth=dWidth=image.width;
    sHeight=dHeight=image.height;
    dx = _.getRandom(0,this.w-dWidth);
    dy = -dHeight;

    enemyPlane = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
    //this.renderArr2.push(enemyPlane);
    this.renderArr2.unshift(enemyPlane);
    this.enemyPlanes.push(enemyPlane);
    //清除自己
    var obj=this;
    enemyPlane.destory=function(){
        clearInterval(enemyPlane.boomTimmer);
        clearInterval(enemyPlane.timmer);
        obj.clear(obj.renderArr2,enemyPlane);
        obj.clear(obj.enemyPlanes,enemyPlane);
    }
    //爆炸函数
    enemyPlane.boomIndex=1;
    enemyPlane.boom=function(){
        obj.boomMusic.play();
        //切换图片,切换完成,清除定时器
        enemyPlane.boomTimmer = setInterval(doboom,100);
    }

    function doboom(){
        if(enemyPlane.boomIndex>6){//爆炸完成
            //清除当前飞机
            enemyPlane.destory();
        }
        enemyPlane.image = obj.imgObj['boom'+index][enemyPlane.boomIndex++];
    }
    
    enemyPlane.timmer = setInterval(move.bind(this),50);

    var obj = this;
    //移动
    function move(){
        if(obj.flag!='start'){
            clearInterval(enemyPlane.timmer);
            clearInterval(enemyPlane.boomTimmer);
        }
        enemyPlane.dy+=2;
        if(enemyPlane.dy>obj.h){//出界后重新回到上方
            enemyPlane.dx = _.getRandom(0,obj.w-dWidth);
            enemyPlane.dy = -dHeight;
            return ;
        }
        //判断与我机碰撞
        if(obj.myPlane && !obj.myPlane.hitFlag && hitMyPlane(enemyPlane,obj.myPlane)){
            obj.myPlane.hitFlag=true;
            //清除子弹发射定时器
            clearInterval(obj.myPlane.timmer);
            enemyPlane.boom();
            obj.myPlane.boom();
            obj.endShow('end');
        }
    }

    function hitMyPlane(enemy,myPlane){
        if(!enemy||!myPlane){
            return ;
        }
        //因为子弹比飞机小,所以只需要判断子弹的4个点是否在飞机范围内,如果有则表示碰撞了
        //左上角
        var x1 = enemy.dx;
        var y1 = enemy.dy;
        //右上角
        var x2 = x1+enemy.dWidth;
        var y2 = y1;
        //右下角
        var x3 = x1+enemy.dWidth;
        var y3 = y1+enemy.dHeight;
        //左下角
        var x4 = x1;
        var y4 = y1+enemy.dHeight;
        //只要有一个点在范围内,则判断为碰撞
        if(comparePoint(x1,y1,myPlane)|| comparePoint(x2,y2,myPlane)||comparePoint(x3,y3,myPlane)||comparePoint(x4,y4,myPlane) ){
            return true;
        }
        return false;
    }
    //根据坐标判断是否在指定的范围内
    function comparePoint(x,y,plane){
        //大于左上角,小于右下角的坐标则肯定在范围内
        if(x>plane.dx && y >plane.dy
            && x<plane.dx+plane.dWidth && y <plane.dy+plane.dHeight	){
            return  true;
        }
        return false;
    }
}

运行效果
在这里插入图片描述

碰撞分析(补充)

在这里插入图片描述
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210525184144286.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLm

真题解析、进阶学习笔记、最新讲解视频、实战项目源码、学习路线大纲
详情关注公中号【编程进阶路】

NzZG4ubmV0L2RrbTEyMzQ1Ng==,size_16,color_FFFFFF,t_70#pic_center)
从上面几个图可看出什么?因为图片是方形的,他们的4个顶点一定至少有一个在对方的范围内。再看一下从左边撞击的图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后加上计分的、胜利、失败等提示就完成了!

看到这里的大佬,动动发财的小手 点赞 + 回复 + 收藏,能【 关注 】一波就更好了。

代码获取方式:
订阅我的专栏《javascript精彩实例》后,可以查看专栏内所有的文章,并且联系博主免费获取你心仪的源代码,专栏的文章都是上过csdn热榜的,值得信赖,了解一下我的专栏!

热门专栏推荐

【1】Java小游戏(俄罗斯方块、飞机大战、植物大战僵尸等)
【2】JavaWeb项目实战(图书管理、在线考试、宿舍管理等)

总结
  • 对于框架原理只能说个大概,真的深入某一部分具体的代码和实现方式就只能写出一个框架,许多细节注意不到。

  • 算法方面还是很薄弱,好在面试官都很和蔼可亲,擅长发现人的美哈哈哈…(最好多刷一刷,不然影响你的工资和成功率???)

  • 在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。

  • 要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!

第一次跳槽十分忐忑不安,和没毕业的时候开始找工作是一样的感受,真的要相信自己,有条不紊的进行。如果有我能帮忙的地方欢迎随时找我,比如简历修改、内推、最起码,可以把烦心事说一说,人嘛都会有苦恼的~

祝大家都有美好的未来,拿下满意的 offer。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值