js+canvas实现飞机大战
更新时间:2022年5月8日 23:27 点击:734 作者:永恒天国
本文实例为大家分享了js canvas实现飞机大战的具体代码,供大家参考,具体内容如下
首先我们绘制一个canvas区域,确实其宽高为480px*852px;水平居中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> canvas { position: absolute; left: 0; right: 0; margin: auto; border: #000 solid 1px; } </style> </head> <body> <canvas width="480" height="852"></canvas> </body> </html>
然后我们再用js查询相应的canvas,再确定画笔cex;然后定一个全局变量state代表游戏状态。
其中state=0表示游戏初始化,state=1代表我方飞机入场,state=2代表战斗过程,state=3代表暂停过程,state=4代表游戏结束过程。
var canvas = document.getElementsByTagName("canvas")[0]; var cex = canvas.getContext('2d'); var state = 0; //状态
再确实背景图片,根据图片大小确实背景的的宽高等数据,再编写相应的函数,最终使用函数声明出一个背景图片对象出来。
//背景图片 var bg = new Image() bg.src = 'img/background.png' // 背景数据对象 var bakgobj = { img: bg, width: 480, height: 852, } // 背景函数 function By(params) { this.width = params.width; this.height = params.height; this.img = params.img; this.x = 0; this.y = 0; this.y1 = -this.height; // 背景绘制 this.paint = function () { cex.drawImage(this.img, this.x, this.y); cex.drawImage(this.img, this.x, this.y1) } // 背景运动 this.sprot = function () { this.y += 3; this.y1 += 3; if (this.y >= this.height) { this.y = -this.height; } if (this.y1 >= this.height) { this.y1 = -this.height; } } } // 背景对象 var bakg = new By(bakgobj);
声明出相应的logo图片与暂停图片
// logo图片 var logo = new Image(); logo.src = 'img/start.png' // 暂停图片 var pause = new Image(); pause.src = 'img/game_pause_nor.png';
使用相同的思路声明入场时的飞机对象
// 入场阶段 var gamearr = ['img/game_loading1.png', 'img/game_loading2.png', 'img/game_loading3.png', 'img/game_loading4.png' ]; // 入场图片对象 var gameArr = []; for (var i = 0; i < gamearr.length; i++) { gameArr[i] = new Image(); gameArr[i].src = gamearr[i]; } // 入场飞机数据 var gameobj = { img: gameArr, width: 186, height: 38, length: gameArr.length } // 入场飞机函数 function Game(params) { this.imgs = params.img; this.width = params.width; this.height = params.height; this.length = params.length; this.index = 0; //入场顺序图片下标 this.thim = 0; this.paint = function () { cex.drawImage(this.imgs[this.index], 0, bakg.height - this.height); } this.sprot = function () { this.thim++; if (this.thim % 3 == 0) { this.index++; } if (this.index == this.length) { state = 2; } } } // 入场飞机对象 var game = new Game(gameobj);
再声明飞机对象
// 飞机图片 var heroarr = ['img/hero1.png', 'img/hero2.png'] // 飞机图片对象 var heroArr = []; for (var i = 0; i < heroarr.length; i++) { heroArr[i] = new Image(); heroArr[i].src = heroarr[i]; } // 飞机数据 var heroobj = { img: heroArr, width: 99, height: 124, length: heroArr.length, full:4, //生命 invinc_:50, //无敌时间 maga:500, //子弹数量 } // 飞机函数 function Hero(params) { this.imgs = params.img; this.width = params.width; this.height = params.height; this.length = params.length; this.x = (bakgobj.width - this.width) / 2; this.y = bakgobj.height - this.height; this.index = 0; this.maga=params.maga; this.full=params.full; //飞机生命 this.invinc=0; //初始无敌时间 this.invinc_=params.invinc_; this.frac=0; //飞机分数; this.cou = 0; //控制子弹发射速度 this.ene = 0; //控制敌机出现频率 this.paint = function () { if((this.invinc>0 && this.invinc%2==0)||this.invinc<=0){ cex.drawImage(this.imgs[this.index], this.x, this.y) } } this.sprot = function () { this.index++; if (this.index == 2) { this.index = 0; } } // 增加射出子弹 this.bullk = function () { this.cou++; // 子弹发射速度 // if (this.cou % 5 == 0) { bullsec.push(new Bull(bullobj)) // } } // 增加敌机 this.enemysos = function () { if (this.ene % 20 == 0) { var rand = Math.random(); if (rand < 0.5) { enemy.push(new Enemy(enemy1obj)) } else if (rand < 0.8) { enemy.push(new Enemy(enemy2obj)) } else { enemy.push(new Enemy3(enemy3obj)) } } this.ene++; } } var hero = new Hero(heroobj);
子弹对象与数组
// 子弹图像 var bullimg = new Image(); bullimg.src = 'img/bullet1.png'; // 子弹数据 var bullobj = { img: bullimg, width: 9, height: 21, } // 子弹函数 function Bull(params) { this.img = params.img; this.width = params.width; this.height = params.height; this.x = hero.x + hero.width / 2 - this.width / 2; this.y = hero.y - this.height; this.paint = function () { cex.drawImage(this.img, this.x, this.y) } this.sprot = function () { this.y -= 20; //子弹飞行速度 } } var bull = new Bull(bullobj); // 界面上的子弹数组; var bullsec = []; function bull_paint() { for (var i = 0; i < bullsec.length; i++) { bullsec[i].paint(); } } function bull_sprot() { for (var i = 0; i < bullsec.length; i++) { bullsec[i].sprot(); } }
敌机小、中、大对象与数组、方法
// 敌机--小 var enemy1arr = ['img/enemy1.png', 'img/enemy1_down1.png', 'img/enemy1_down2.png', 'img/enemy1_down3.png', 'img/enemy1_down4.png' ] var enemy1Arr = []; for (var i = 0; i < enemy1arr.length; i++) { enemy1Arr[i] = new Image(); enemy1Arr[i].src = enemy1arr[i]; } //敌机—-小 数据 var enemy1obj = { img: enemy1Arr, width: 57, height: 51, length: enemy1Arr.length, frac:3, full:1, } // 敌机--中 var enemy2arr = ['img/enemy2.png', 'img/enemy2_down1.png', 'img/enemy2_down2.png', 'img/enemy2_down3.png', 'img/enemy2_down4.png' ] var enemy2Arr = []; for (var i = 0; i < enemy2arr.length; i++) { enemy2Arr[i] = new Image(); enemy2Arr[i].src = enemy2arr[i]; } //敌机--中 数据 var enemy2obj = { img: enemy2Arr, width: 69, height: 95, length: enemy2Arr.length, frac:5, full:2, } // 敌机--小、中 函数 function Enemy(params) { this.imgs = params.img; this.width = params.width; this.height = params.height; this.length = params.length; this.frac=params.frac; this.index = 0; this.buff=Math.random<0.05?true:false; //随机带buff this.ext=false;//敌机是否被击落 this.full = params.full; //敌机生命值 this.x = Math.random() * (bakg.width - this.width); this.y = -this.height; this.paint = function () { cex.drawImage(this.imgs[this.index], this.x, this.y); } this.sprot = function () { this.y += 5; if (this.full <= 0) { this.index++; } } } // 敌机--大 var enemy3arr = ['img/enemy3_n1.png', 'img/enemy3_n2.png', 'img/enemy3_hit.png', 'img/enemy3_down1.png', 'img/enemy3_down2.png', 'img/enemy3_down3.png', 'img/enemy3_down4.png', 'img/enemy3_down5.png', 'img/enemy3_down6.png' ] var enemy3Arr = []; for (var i = 0; i < enemy3arr.length; i++) { enemy3Arr[i] = new Image(); enemy3Arr[i].src = enemy3arr[i]; } //敌机--大 数据 var enemy3obj = { img: enemy3Arr, width: 169, height: 258, length: enemy3Arr.length, frac:10, full:4, } // 敌机--大 函数 function Enemy3(params) { this.imgs = params.img; this.width = params.width; this.height = params.height; this.length = params.length; this.frac=params.frac; this.index = 0; this.thim = 0; this.buff=Math.random<0.2?true:false; //随机带buff this.ext=false;//敌机是否被击落 this.full = params.full; this.full_=Math.floor(this.full/2);//战损 this.x = Math.random() * (bakg.width - this.width); this.y = -this.height; this.paint = function () { cex.drawImage(this.imgs[this.index], this.x, this.y); } this.sprot = function () { this.y += 5; if (this.full <= 0) { this.index++; }else if(this.full>0&&this.full<=this.full_){ this.index=2; }else if (this.thim % 5 == 0) { this.index++; if (this.index == 2) { this.index = 0; } } this.thim++; } } //敌机数组 var enemy = []; // 敌机绘制 function enemy_paint() { for (var i = 0; i < enemy.length; i++) { enemy[i].paint(); } } // 敌机移动 function enemy_sprot() { for (var i = 0; i < enemy.length; i++) { enemy[i].sprot(); } } // 敌机爆炸后删除 function enemy_del(){ for(var i=0;i<enemy.length;i++){ if(enemy[i].index==enemy[i].length){ hero.frac+=enemy[i].frac; enemy.splice(i,1); i--; } } }
再创建一个函数判断碰撞
// 检测敌机是否产生碰撞 function enemy_bull_hero() { hero.invinc--; for (var i = 0; i < enemy.length; i++) { if (hero.invinc<=0&&hero.y <= enemy[i].y + enemy[i].height&&hero.y>enemy[i].y-hero.height) { if (hero.x > enemy[i].x - hero.width && hero.x < enemy[i].x + enemy[i].width) { // 飞机与敌机碰撞; hero.full--; hero.invinc=hero.invinc_; if(hero.full==0){ state = 4; } } } for (var n = 0; n < bullsec.length; n++) { if (!enemy[i].ext&&bullsec[n].y <= enemy[i].y + enemy[i].height&&bullsec[n].y>enemy[i].y-bullsec[n].height) { if (bullsec[n].x > enemy[i].x - bullsec[n].width && bullsec[n].x < enemy[i].x + enemy[i] .width) { // 敌机与子弹碰撞; bullsec.splice(n, 1); n--; enemy[i].full--; if(enemy[i].full<=0){ enemy[i].ext=true; } } } } } }
再分别绑定相应的事件
//点击画布从状态0切换到状态1; canvas.onclick = function () { if (state == 0) { state = 1; } } // 飞机跟随鼠标移动 canvas.onmousemove = function (e) { if (state == 3) { state = 2; } if (state == 2) { var x = e.offsetX; var y = e.offsetY; hero.x = x - hero.width / 2; hero.y = y - hero.height / 2; } } // 鼠标移出暂停 canvas.onmouseout = function () { if (state == 2) { state = 3; } } // 弹夹子弹发射 document.onkeydown =function(event){ if(state==2){ if(event.keyCode==32&&hero.maga>0){ hero.bullk() //增加界面射出子弹 hero.maga--; } } };
最终在定时器中实时更新相应的画面
setInterval(function () { bakg.paint() bakg.sprot() cex.font='40px 微软雅黑'; cex.fillText('生命:'+hero.full,330,40); cex.fillText('分数:'+hero.frac,0,40); cex.fillText('子弹:'+hero.maga,0,80); if (state == 0) { //初始化 cex.drawImage(logo, 40, 0); } if (state == 1) { //出场动画 game.paint(); game.sprot(); } if (state == 2) { //战斗状态 hero.paint() hero.sprot() bull_paint() bull_sprot() hero.enemysos() //增加敌机数量 enemy_paint() enemy_sprot() enemy_bull_hero() //碰撞检测 enemy_del(); } if (state == 3) { //暂停状态 cex.drawImage(pause, 210, 375) hero.paint() bull_paint() enemy_paint() } if (state == 4) { //游戏结束状态 cex.fillText('菜',bakg.width/2-30,bakg.height/2-90); } }, 30)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
原文出处:https://blog.csdn.net/bian2845972116/article/details/1217350
相关文章
- 本篇文章主要分享了通过window.navigator来判断浏览器及其版本信息的实例代码。具有一定的参考价值,下面跟着小编一起来看下吧...2017-01-23
- 这篇文章主要介绍了js如何实现浏览器打印功能,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-15
- 这篇文章主要给大家介绍了关于Nest.js参数校验和自定义返回数据格式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-28
- 下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
- 作为前端,一直以来都知道HTTP劫持与XSS跨站脚本、CSRF跨站请求伪造。防御这些劫持最好的方法是从后端入手,前端能做的太少。而且由于源码的暴露,攻击者很容易绕过防御手段。但这不代表我们去了解这块的相关知识是没意义的,本文的许多方法,用在其他方面也是大有作用。...2021-05-24
- 这篇文章主要为大家详细介绍了js+css实现回到顶部按钮back to top回到顶部按钮,感兴趣的小伙伴们可以参考一下...2016-03-03
- 那么今天我就用JavaScript代码来实现这个效果吧,那么首先介绍一下整个的思路,首先我们先将确定输入密码的位数,我的需求是5位,那么就用一个div标签包住5个input标签...2016-01-02
- 这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
- 这篇文章主要介绍了js实现调用网络摄像头及常见错误处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-07
- 这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
- 这篇文章主要介绍了js组件SlotMachine实现图片切换效果制作抽奖系统的相关资料,需要的朋友可以参考下...2016-04-19
- Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.这篇文章主要介绍了vue.js 表格分页ajax 异步加载数据的相关资料,需要的朋友可以参考下...2016-10-20
- 为了网站的安全性,很多朋友都把密码设的比较复杂,但是如何密码不能明显示,不知道输的是对是错,为了安全起见可以把密码显示的,那么基于js代码如何实现的呢?下面通过本文给大家介绍JavaScript实现表单密码的隐藏和显示,需要的朋友参考下...2016-03-03
- 这篇文章主要为大家详细介绍了js实现列表按字母排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-11
- 这篇文章主要介绍了基于JavaScript实现文字超出部分隐藏 的相关资料,需要的朋友可以参考下...2016-03-01
- 这篇文章主要介绍了JS实现响应鼠标点击动画渐变弹出层效果代码,具有非常自然流畅的动画过度效果,涉及JavaScript针对鼠标事件的响应及页面元素样式的动态操作相关技巧,需要的朋友可以参考下...2016-03-28
- 这篇文章主要给大家介绍了一个关于JS正则匹配的踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-13
- 这次文章要给大家介绍的是node.JS md5加密中文与php结果不一致怎么办,不知道具体解决办法的下面跟小编一起来看看。 因项目需要,需要Node.js与PHP做接口调用,发现nod...2017-07-06
- 系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter。如果对smarty比较熟悉的话,学习angularjs会比较容易一点,这篇文章给大家介绍angularjs filter用法详解,感兴趣的朋友一起学习吧...2015-12-29
- 本文给大家介绍的是nodejs实现使用阿里大鱼短信API发送消息的方法和代码,有需要的小伙伴可以参考下。...2016-01-20