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

	//加载图片,并回调绘制出图片(因为图片是异步加载的,所以要用回调)
	_.imageLoad(this.urlObj,this.imgObj,this.draw.bind(this));


}

//渲染图形
Plane.prototype.render=function(){
	var context=this.ctx;
	this.clearCanvas();	
	_.each(this.renderArr,function(item){
		item && item.render(context);
	});
}
//清洗画布
Plane.prototype.clearCanvas=function() {
	this.ctx.clearRect(0,0,parseInt(this.w),parseInt(this.h));
}

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

}

//绘制背景
Plane.prototype.drawBG=function(){
	var image,img,sx=0,sy=0,sWidth=520,sHeight=620,dx=0,dy=0,dWidth=520,dHeight=620;
	//背景
	image = this.imgObj['common']['bg'];
	img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight});
	this.renderArr.push(img);
}

global.plane=plane;

4. 页面再加上代码



var box = document.getElementById(‘box’);

var bgMusic = document.getElementById(‘bgMusic’);
var boomMusic = document.getElementById(‘boomMusic’);
var shootMusic = document.getElementById(‘shootMusic’);
plane.init(box,{
bgMusic:bgMusic,
boomMusic:boomMusic,
shootMusic:shootMusic
}
);


运行效果  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6d515ff7efff445f8b4fc342e8da727a.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RrbTEyMzQ1Ng==,size_16,color_FFFFFF,t_70)


## 绘制我方飞机



//创建我机
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();
}


运行效果  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/91c3ae70f42944e28385d99226ac0151.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RrbTEyMzQ1Ng==,size_16,color_FFFFFF,t_70)


## 鼠标事件(飞机跟随)


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;
	}

}

5. 在init方法中加入鼠标监听



//给canvas2画布添加鼠标移动事件(因为画布2在上面)
canvas2.addEventListener(‘mousemove’,this.mouseMove.bind(this));
//给canvas2画布添加鼠标右键事件
canvas2.addEventListener(‘contextmenu’,this.contextMenu.bind(this));


6. 加入重绘方法



//重新绘制
Plane.prototype.reDraw=function(){
if(this.flag==‘start’){
this.render2();
}
}


7. 加入主线程,用来刷新重绘



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

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

}


运行效果


![在这里插入图片描述](https://img-blog.csdnimg.cn/08471687c4be48d98e5144f35319c83f.gif#pic_center)


## 绘制子弹


思路:


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;
}

}


![在这里插入图片描述](https://img-blog.csdnimg.cn/e9e5993bf43949caae585b979eccc204.gif#pic_center)


## 定时绘制敌机


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;

下面是我在学习HTML和CSS的时候整理的一些笔记,有兴趣的可以看下:

HTML、CSS部分截图

进阶阶段

进阶阶段,开始攻 JS,对于刚接触 JS 的初学者,确实比学习 HTML 和 CSS 有难度,但是只要肯下功夫,这部分对于你来说,也不是什么大问题。

JS 内容涉及到的知识点较多,看到网上有很多人建议你从头到尾抱着那本《JavaScript高级程序设计》学,我是不建议的,毕竟刚接触 JS 谁能看得下去,当时我也不能,也没那样做。

我这部分的学习技巧是,增加次数,减少单次看的内容。就是说,第一遍学习 JS 走马观花的看,看个大概,去找视频以及网站学习,不建议直接看书。因为看书看不下去的时候很打击你学下去的信心。

然后通过一些网站的小例子,开始动手敲代码,一定要去实践、实践、实践,这一遍是为了更好的去熟悉 JS 的语法。别只顾着来回的看知识点,眼高手低可不是个好习惯,我在这吃过亏,你懂的。

1、JavaScript 和 ES6

在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。

JavaScript部分截图

2、前端框架

前端框架太多了,真的学不动了,别慌,其实对于前端的三大马车,Angular、React、Vue 只要把其中一种框架学明白,底层原理实现,其他两个学起来不会很吃力,这也取决于你以后就职的公司要求你会哪一个框架了,当然,会的越多越好,但是往往每个人的时间是有限的,对于自学的学生,或者即将面试找工作的人,当然要选择一门框架深挖原理。

以 Vue 为例,我整理了如下的面试题。

Vue部分截图

  • 21
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值