首页 > 其他分享 >Html飞机大战(十八): 模块化+项目开源

Html飞机大战(十八): 模块化+项目开源

时间:2023-01-05 20:55:21浏览次数:70  
标签:canvas hero 模块化 length 开源 Html let context enemies

好家伙,好久好久没有更新这个系列了

 

 

 

 

 

 

 

 

为了使文档更方便阅读,使代码更容易维护,来把这个飞机大战模块化

项目已开源:

https://gitee.com/tang-and-han-dynasties/airplane-battle---h.git

 

项目结构如下:

 

 

最大的改动是主启动类进行了修改:

我们将曾经部分的全局方法,和循环计时器封装到类的方法中

main.js文件如下:

class Main {
    //一下全为全局变量或方法 (全局的!!)
   
    //主启动方法
    maingame() {
const sky = new Sky(SKY); //初始化一个飞机界面加载实例 const loading = new Loading(LOADING); //初始化一个英雄实例 英雄是会变的 let hero = new Hero(HERO); //该变量中有所有的敌机实例 let enemies = []; //该变量中存放所有的奖励实例 let awards = []; //敌机产生的速率 let ENEMY_CREATE_INTERVAL = 800; let ENEMY_LASTTIME = new Date().getTime(); function stateControl() { //为canvas绑定一个点击事件 且他如果是START状态的时候需要修改成STARTING状态 canvas.addEventListener("click", () => { if (state === START) { state = STARTING; } }); // 为canvas绑定一个鼠标移动事件 鼠标正好在飞机图片的正中心 canvas.addEventListener("mousemove", (e) => { let x = e.offsetX; let y = e.offsetY; hero.x = x - hero.width / 2; hero.y = y - hero.height / 2; }); // 为canvas绑定一个鼠标离开事件 鼠标离开时 RUNNING -> PAUSE canvas.addEventListener("mouseleave", () => { if (state === RUNNING) { state = PAUSE; } }); // 为canvas绑定一个鼠标进入事件 鼠标进入时 PAUSE => RUNNING canvas.addEventListener("mouseenter", () => { if (state === PAUSE) { state = RUNNING; } }); //为canvas绑定一个屏幕移动触摸点事件 触碰点正好在飞机图片的正中心 canvas.addEventListener("touchmove", (e) => { // let x = e.pageX; // let y = e.pageY; console.log(e); // let x = e.touches[0].clientX; // let y = e.touches[0].clinetY; let x = e.touches[0].pageX; let y = e.touches[0].pageY; // let x = e.touches[0].screenX; // let y = e.touches[0].screenY; let write1 = (document.body.clientWidth - 480) / 2; let write2 = (document.body.clientHeight - 650) / 2; hero.x = x - write1 - hero.width / 2; hero.y = y - write2 - hero.height / 2; // hero.x = x - hero.width / 2; // hero.y = y - hero.height / 2; console.log(x, y); console.log(document.body.clientWidth, document.body.clientHeight); e.preventDefault(); // 阻止屏幕滚动的默认行为 }) } stateControl(); // 碰撞检测函数 //此处的碰撞检测包括 //1.子弹与敌机的碰撞 //2.英雄与敌机的碰撞 //3.英雄与随机奖励的碰撞 function checkHit() { // 遍历所有的敌机 for (let i = 0; i < awards.length; i++) { //检测英雄是否碰到奖励类 if (awards[i].hit(hero)) { //当然了,这个随机奖励的样式也要删了 awards.splice(i, 1); //清除所有的敌机 // for (let i = 0; i < enemies.length; i++) { // enemies.splice(i, 1); // } enemies.length = 0; } } for (let i = 0; i < enemies.length; i++) { //检测英雄是否撞到敌机 if (enemies[i].hit(hero)) { //将敌机和英雄的destory属性改为true enemies[i].collide(); hero.collide(); } for (let j = 0; j < hero.bulletList.length; j++) { enemies[i].hit(hero.bulletList[j]); //检测子弹是否撞到敌机 if (enemies[i].hit(hero.bulletList[j])) { //将敌机和子弹的destory属性改为true enemies[i].collide(); hero.bulletList[j].collide(); } } } } // 全局函数 隔一段时间就来初始化一架敌机/奖励 function createComponent() { const currentTime = new Date().getTime(); if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL) { let ran = Math.floor(Math.random() * 100); if (ran < 55) { enemies.push(new Enemy(E1)); } else if (ran < 85 && ran > 55) { enemies.push(new Enemy(E2)); } else if (ran < 95 && ran > 85) { enemies.push(new Enemy(E3)); } else if (ran > 95) { awards.push(new award(C1)); } ENEMY_LASTTIME = currentTime; } } // 全局函数 来判断所有的子弹/敌人组件 "负责移动" function judgeComponent() { for (let i = 0; i < hero.bulletList.length; i++) { hero.bulletList[i].move(); } for (let i = 0; i < enemies.length; i++) { enemies[i].move(); } for (let i = 0; i < awards.length; i++) { awards[i].move(); } } // 全局函数 来绘制所有的子弹/敌人组件 绘制score&life面板 function paintComponent() { for (let i = 0; i < hero.bulletList.length; i++) { hero.bulletList[i].paint(context); } for (let i = 0; i < enemies.length; i++) { enemies[i].paint(context); } for (let i = 0; i < awards.length; i++) { awards[i].paint(context); } context.font = "20px 微软雅黑"; context.fillStyle = "green"; context.textAlign = "left"; context.fillText("score: " + score, 10, 20); context.textAlign = "right"; context.fillText("life: " + life, 480 - 10, 20); //重置样式 context.fillStyle = "black"; context.textAlign = "left"; } // 全局函数 来销毁所有的子弹/敌人组件 销毁掉英雄 function deleteComponent() { if (hero.destory) { life--; hero.destory = false; if (life === 0) { state = END; } else { hero = new Hero(HERO); } } for (let i = 0; i < hero.bulletList.length; i++) { if (hero.bulletList[i].outOfBounds() || hero.bulletList[i].destory) { hero.bulletList.splice(i, 1); } } for (let i = 0; i < enemies.length; i++) { if (enemies[i].outOfBounds() || enemies[i].destory) { enemies.splice(i, 1); } } } //当图片加载完毕时,需要做某些事情 bg.addEventListener("load", () => { setInterval(() => { switch (state) { case START: sky.judge(); sky.paint(context); let logo_x = (480 - copyright.naturalWidth) / 2; let logo_y = (650 - copyright.naturalHeight) / 2; context.drawImage(copyright, logo_x, logo_y); break; case STARTING: sky.judge(); sky.paint(context); loading.judge(); loading.paint(context); break; case RUNNING: sky.judge(); sky.paint(context); hero.judge(); hero.paint(context); hero.shoot(); createComponent(); judgeComponent(); deleteComponent(); paintComponent(); checkHit(); break; case PAUSE: let pause_x = (480 - pause.naturalWidth) / 2; let pause_y = (650 - pause.naturalHeight) / 2; context.drawImage(pause, pause_x, pause_y); break; case END: //给我的画笔设置一个字的样式 //后面写出来的字都是这个样式的 context.font = "bold 24px 微软雅黑"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText("GAME_OVER", 480 / 2, 650 / 2); break; } }, 10); }); //背景切换方法 // function changebg() { // console.log("changebg方法被触发") // bg.src = "img/background.png" // } } } let main_1 = new Main() // main_1.stateControl(); main_1.maingame();

 

并将配置项分开来:

以下配置归到config.js文件中

// 初始化画布对象
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");

// 定义游戏的状态
// 开始
const START = 0;
// 开始时
const STARTING = 1;
// 运行时
const RUNNING = 2;
// 暂停时
const PAUSE = 3;
// 结束时
const END = 4;

//state表示游戏的状态 取值必须是以上的五种状态
let state = START;
//score 分数变量 life 变量
let score = 0;
let life = 3;

 

标签:canvas,hero,模块化,length,开源,Html,let,context,enemies
From: https://www.cnblogs.com/FatTiger4399/p/17028675.html

相关文章

  • html5 新标签
    main(块级元素)注意在一个文档中,<main>元素是唯一的,所以不能出现一个以上的<main>元素。<main>元素不能是以下元素的后代:<article>、<aside>、<footer>、<header>或......
  • Pomelo:网易开源基于 Node.js 的游戏服务端框架
    ​​Pomelo​​是基于Node.js的高性能、分布式游戏服务器框架。它包括基础的开发框架和相关的扩展组件(库和工具包),可以帮助你省去游戏开发枯燥中的重复劳动和底层逻辑......
  • 开源的工作流都有哪些特征?
    开源的工作流是什么?都有什么样的特征和优势特点?众所周知,随着现代化办公管理的兴起,工作效率高的低代码开发平台涌上前线,成为很多企业实现数字化转型和做好数据管理的重要系......
  • Apache RocketMQ 斩获 InfoQ 2022 年度十大开源新锐项目
    以“深入数字经济·洞见技术价值”为主题的【InfoQ2022中国技术力量年终榜单】正式公布获奖名单。其中,ApacheRocketMQ以其卓越的易用性、社区活跃性、成熟度、产品优越性......
  • Github应用最广泛的开源项目
    ​ Github自从2008年上线以来,发展迅速,目前已经成为最流行的代码托管站点。在Github中,开发者除了可以托管自己的项目源码外,还可以Watch(关注)、Star(加星)、Fork(复制一份)、Pull......
  • HTML5实现浏览器端大文件分片上传
    ​ 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数下面直接贴代码吧,一些难懂的我大部分都加上......
  • Apache RocketMQ 斩获 InfoQ 2022 年度十大开源新锐项目
    以“深入数字经济·洞见技术价值”为主题的【InfoQ2022中国技术力量年终榜单】正式公布获奖名单。其中,ApacheRocketMQ以其卓越的易用性、社区活跃性、成熟度、产品优越......
  • 基于开源体系的云原生微服务治理实践与探索
    作者:董艺荃|携程服务框架负责人携程微服务产品的发展历程携程微服务产品起步于2013年。最初,公司基于开源项目ServiceStack进行二次开发,推出.Net平台下的微服务框架CSe......
  • 【Qt】开源一键代码开光工具,一行代码给你的项目施加祝福,减少Bug
    年底啦,没什么项目,想摸鱼划水没见到什么好玩的东西,看到有人分享这个,直接做个库来玩下,之后说不定会嵌到公司的项目里面去....效果如下,佛光普照!输入也只需要一行命令magic......
  • 基于开源体系的云原生微服务治理实践与探索
    作者:董艺荃|携程服务框架负责人携程微服务产品的发展历程携程微服务产品起步于2013年。最初,公司基于开源项目ServiceStack进行二次开发,推出.Net平台下的微服务框架......