我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

好家伙,

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 

代码已开源

Git:

https://gitee.com/tang-and-han-dynasties/panghu-planebattle-esm.git

NPM:

panghu-planebattle-esm - npm (npmjs.com)

 

现在,比如说,我用Vue写好了个人博客主页的前端

我想在这个主页里面加点东西,让我的博客更缤纷多彩一点

我想在他的主页里面塞个小游戏,他会怎么做

 

1.思考步骤

如下:

第一步:去网上找个小游戏的资源,将这个包下载到本地,

诶,正好发现有个飞机大战 panghu-planebattle-modular 小游戏开发好了

我可以直接下载,或者通过npm安装

npm install panghu-planebattle-modular

 

第二步:导入到某个.vue文件或html文件

通过import导入

 

第三步:划一个区域<div>给这个包去渲染游戏

 剩下的他就不用管了

大概是这么个过程,然后我们按着这个思路,反向去分我们这个包

 

先来看看原先的完整代码:

完整代码

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

<template>     <div>     <h1>欢迎来到主页面</h1>       <div ref="stage"></div>     </div>   </template>      <script>   export default {     mounted() {         //canvas初始化         console.log("我被执行啦")         let canvas = document.createElement('canvas');         this.$refs.stage.appendChild(canvas);         canvas.width = 480;         canvas.height = 650;         canvas.ref = canvas;         canvas.style = "border: 1px solid red;"         const context = canvas.getContext("2d");            //图片初始化方法         function createImage(src) {           let img;           if (typeof src === "string") {             img = new Image();             img.src = require('./img/' + src);           } else {             img = [];             for (let i = 0; i < src.length; i++) {               img[i] = new Image();               img[i].src = require('./img/' + src[i]);             }           }           return img;         }         //createImage()方法测试样例         // let bg = createImage("4.jpg")         // bg.onload = function () {         //   console.log("img加载完毕")         //   context.drawImage(bg, 0, 0, 480, 650)         // }         const IMAGES = {           b: "bullet1.png",           bg: "4.png",           copyright: "shoot_copyright.png",           pause: "game_pause.png",           loading_frame: ["game_loading1.png", "game_loading2.png", "game_loading3.png",             "game_loading4.png"           ],           hero_frame_live: ["hero1.png", "hero2.png"],           hero_frame_death: ["hero_blowup_n1.png", "hero_blowup_n2.png", "hero_blowup_n3.png",             "hero_blowup_n4.png"           ],           e1_live: ["enemy1.png"],           e1_death: ["enemy1_down1.png", "enemy1_down2.png", "enemy1_down3.png", "enemy1_down4.png"],           e2_live: ["enemy2.png"],           e2_death: ["enemy2_down1.png", "enemy2_down2.png", "enemy2_down3.png", "enemy2_down4.png"],           e3_live: ["enemy3_n1.png", "enemy3_n2.png"],           e3_death: ["enemy3_down1.png", "enemy3_down2.png", "enemy3_down3.png", "enemy3_down4.png",             "enemy3_down5.png", "enemy3_down6.png"           ],           c1: "lanqiu.png"         };         //初始化各个图片         const b = createImage(IMAGES.b);         const bg = createImage(IMAGES.bg);         const copyright = createImage(IMAGES.copyright);         const pause = createImage(IMAGES.pause);         const loading_frame = createImage(IMAGES.loading_frame);         const hero_frame = {           live: createImage(IMAGES.hero_frame_live),           death: createImage(IMAGES.hero_frame_death),         };         const e1 = {           live: createImage(IMAGES.e1_live),           death: createImage(IMAGES.e1_death),         };         const e2 = {           live: createImage(IMAGES.e2_live),           death: createImage(IMAGES.e2_death),         };         const e3 = {           live: createImage(IMAGES.e3_live),           death: createImage(IMAGES.e3_death),         };         const c1 = createImage(IMAGES.c1);            //配置项:         // 定义游戏的状态         // 开始         const START = 0;         // 开始时         const STARTING = 1;         // 运行时         const RUNNING = 2;         // 暂停时         const PAUSE = 3;         // 结束时         const END = 4;         // 加载中         const LOADINGING = 5;            //state表示游戏的状态 取值必须是以上的五种状态         let state = LOADINGING;         // hero_frame.addEventListener("load", () => {         //   state = START;         // })            pause.onload = function () {           state = START;           console.log(state)         }            //score 分数变量 life 变量         let score = 0;         let life = 3;            //天空类的配置项         const SKY = {           bg: bg,           width: 480,           height: 650,           speed: 10,         };            // 飞机加载界面的配置项         const LOADING = {           frame: loading_frame,           width: 186,           height: 38,           x: 0,           y: 650 - 38,           speed: 400,         };            // 英雄配置项         const HERO = {           frame: hero_frame,           width: 99,           height: 124,           speed: 100,         };            // 子弹配置项         const BULLET = {           img: b,           width: 9,           height: 21,         };            //小敌机配置项         const E1 = {           type: 1,           width: 57,           height: 51,           life: 10,           score: 1,           frame: e1,           minSpeed: 20,           maxSpeed: 10         };         //中敌机配置项         const E2 = {           type: 2,           width: 69,           height: 95,           life: 50,           score: 5,           frame: e2,           minSpeed: 50,           maxSpeed: 20         };         //打敌机配置项         const E3 = {           type: 3,           width: 169,           height: 258,           life: 100,           score: 20,           frame: e3,           minSpeed: 100,           maxSpeed: 100         };         //奖励类配置项         const C1 = {           type: 4,           width: 75,           height: 75,           life: 1,           score: 1,           img: c1,           minSpeed: 5,           maxSpeed: 10         };         //正式代码            //初始化奖励类         class Award {           constructor(config) {             this.type = config.type;             this.width = config.width;             this.height = config.height;             this.x = Math.floor(Math.random() * (480 - config.width));             this.y = -config.height;             this.life = config.life;             this.score = config.score;             this.img = config.img;             this.live = true;             this.speed = Math.floor(Math.random() * (config.minSpeed - config.maxSpeed + 1)) + config.maxSpeed;             this.lastTime = new Date().getTime();             this.deathIndex = 0;             this.destory = false;           }           move() {             const currentTime = new Date().getTime();             if (currentTime - this.lastTime >= this.speed) {               if (this.live) {                 this.y = this.y + 6;                 this.lastTime = currentTime;               } else {                 this.destory = true;                  }             }           }           paint(context) {             context.drawImage(this.img, this.x, this.y, this.width, this.height);           }           outOfBounds() {             if (this.y > 650) {               return true;             }           }           hit(o) {             let ol = o.x;             let or = o.x + o.width;             let ot = o.y;             let ob = o.y + o.height;             let el = this.x;             let er = this.x + this.width;             let et = this.y;             let eb = this.y + this.height;             if (ol > er || or < el || ot > eb || ob < et) {               return false;             } else {               return true;             }           }           // collide() {           //   this.life--;           //   if (this.life === 0) {           //     this.live = false;           //     score += this.score;           //   }           // }         }            //         //初始化一个子弹类         class Bullet {           constructor(config, x, y) {             this.img = config.img;             this.width = config.width;             this.height = config.height;             this.x = x;             this.y = y;             this.destory = false;           }           //子弹绘制方法           paint(context) {             context.drawImage(this.img, this.x, this.y);           }           //移动子弹 this.y--           move() {             this.y -= 8;           }           outOfBounds() {             //如果返回的是真的话 那么我们应该销毁掉这个子弹             return this.y < -this.height;           }           collide() {             //让这颗子弹变成可销毁状态             this.destory = true;           }         }         //            // 初始化一个敌机类         class Enemy {                                     constructor(config) {             this.type = config.type;             this.width = config.width;             this.height = config.height;             this.x = Math.floor(Math.random() * (480 - config.width));             this.y = -config.height;             this.life = config.life;             this.score = config.score;             this.frame = config.frame;             this.img = this.frame.live[0];             this.live = true;             this.speed = Math.floor(Math.random() * (config.minSpeed - config.maxSpeed + 1)) + config.maxSpeed;             this.lastTime = new Date().getTime();             this.deathIndex = 0;             this.destory = false;           }           move() {             const currentTime = new Date().getTime();             if (currentTime - this.lastTime >= this.speed) {               if (this.live) {                 this.img = this.frame.live[0];                 this.y++;                 this.lastTime = currentTime;               } else {                 this.img = this.frame.death[this.deathIndex++];                 if (this.deathIndex === this.frame.death.length) {                   this.destory = true;                 }               }             }           }           paint(context) {             context.drawImage(this.img, this.x, this.y);           }           outOfBounds() {             if (this.y > 650) {               return true;             }           }           hit(o) {             let ol = o.x;             let or = o.x + o.width;             let ot = o.y;             let ob = o.y + o.height;             let el = this.x;             let er = this.x + this.width;             let et = this.y;             let eb = this.y + this.height;             if (ol > er || or < el || ot > eb || ob < et) {               return false;             } else {               return true;             }           }           collide() {             this.life--;             if (this.life === 0) {               this.live = false;               score += this.score;             }           }         }            //         // 初始化一个英雄类         class Hero {           constructor(config) {             this.width = config.width;             this.height = config.height;             this.x = (480 - config.width) / 2;             this.y = 650 - config.height;             this.frame = config.frame;             this.frameLiveIndex = 0;             this.frameDeathIndex = 0;             this.lastTime = new Date().getTime();             this.speed = config.speed;             //当前展示的图片             this.img = null;             this.live = true;             //子弹上次射击的时间             this.lastShootTime = new Date().getTime();             //子弹射击的间隔             this.shootInterval = 50;             //子弹夹数组             this.bulletList = [];             this.destory = false;           }           judge() {             const currentTime = new Date().getTime();             if (currentTime - this.lastTime > this.speed) {               if (this.live) {                 this.img = this.frame.live[this.frameLiveIndex++ % this.frame.live.length];               } else {                 //0 1 2 3 4                 this.img = this.frame.death[this.frameDeathIndex++];                 //到4的时候英雄死了                 if (this.frameDeathIndex === this.frame.death.length) {                   this.destory = true;                 }               }               this.lastTime = currentTime;             }           }           paint(context) {             context.drawImage(this.img, this.x, this.y, this.width, this.height);           }           //英雄可以射击子弹           shoot() {             //获取当前时间             const currentTime = new Date().getTime();             //飞机的位置             if (currentTime - this.lastShootTime > this.shootInterval) {               //在飞机的头部初始化一个子弹对象               let bullet = new Bullet(BULLET, this.x + this.width / 2 - BULLET.width / 2, this.y - BULLET.height);               //英雄飞机要认领这个子弹               this.bulletList.push(bullet);               //在网页上绘制一个子弹对象               bullet.paint(context);               //更新英雄射击时间               this.lastShootTime = currentTime;             }           }           collide() {             //将活着标识符切换为false             //活着 -> 爆炸中 -> 死亡(销毁)             this.live = false;           }         }         //         // 初始化一个飞机界面加载类         class Loading {           constructor(config) {             this.frame = config.frame;             this.frameIndex = 0;             this.width = config.width;             this.height = config.height;             this.x = config.x;             this.y = config.y;             this.speed = config.speed;             this.lastTime = new Date().getTime();           }           judge() {             const currentTime = new Date().getTime();             if (currentTime - this.lastTime > this.speed) {               this.frameIndex++;               if (this.frameIndex === 4) {                 state = RUNNING;               }               this.lastTime = currentTime;             }           }           paint(context) {             context.drawImage(this.frame[this.frameIndex], this.x, this.y);           }         }               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"             // }           }         }         //            //初始化一个天空类         class Sky {           constructor(config) {             this.bg = config.bg;             this.width = config.width;             this.height = config.height;             this.x1 = 0;             this.y1 = 0;             this.x2 = 0;             this.y2 = -this.height;             this.speed = config.speed;             this.lastTime = new Date().getTime();           }           //判断方法           judge() {             let currentTime = new Date().getTime();             if (currentTime - this.lastTime > this.speed) {               this.y1++;               this.y2++;               this.lastTime = currentTime;             }             if (this.y2 === 0) {               this.y1 = 0;               this.y2 = -this.height;             }           }           //绘图方法           paint(context) {             context.drawImage(this.bg, this.x1, this.y1, this.width, this.height);             context.drawImage(this.bg, this.x2, this.y2, this.width, this.height);           }         }         let main_1 = new Main()         main_1.maingame();       }     }         </script>      <style>   #stage {     width: 480px;     height: 650px;     margin: 0 auto;   }   </style>      

Helloworld.vue

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 

一看,738行,这,没人想维护的,复制粘贴都嫌累

(再看一眼就要爆炸)

 

我们要实现一个这样的效果(事实上也实现了)

<template>   <div>     <div ref="stage"></div>   </div> </template>  <script> import { canvas, main_1 } from "panghu-planebattle-modular"  export default {   mounted() {     this.$refs.stage.appendChild(canvas);     main_1.maingame();   } } </script>  <style> #stage {   width: 480px;   height: 650px;   margin: 0 auto; } </style>

 

而事实上,就是三行代码:

//从包中导入canvas,main_1 import { canvas, main_1 } from "panghu-planebattle-modular"  //dom操作添加canvas this.$refs.stage.appendChild(canvas);   //调用main_1的maingame方法 main_1.maingame();

 

让使用者操作的部分由738行代码变成3行代码

 

2.开始分包

将程序主要分成下面几个需要处理的部分

1、静态的:图片,图片地址,配置项

2、六个小类:Enemy、Hero、Loading、Sky、Award、Bullet

3、主启动类:Main

4、全局方法,全局变量

5、入口(对外导出的对象)

 

项目目录结构如下:

 

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 

 

1.图片

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 

2.配置项

首先是配置项config.js

我们将所有的配置项文件都放在这里,全局变量也放在这里

 如果将来我们要调参数,比如说,改改图片,改改子弹的速度之类,就直接在这个文件里改就行了

 

3.其中六个小类,我把他们"独立"分开

比如Bullet(子弹类)

//初始化一个子弹类 class Bullet {   constructor(config, x, y) {     this.img = config.img;     this.width = config.width;     this.height = config.height;     this.x = x;     this.y = y;     this.destory = false;   }   //子弹绘制方法   paint(context) {     context.drawImage(this.img, this.x, this.y);   }   //移动子弹 this.y--   move() {     this.y -= 8;   }   outOfBounds() {     //如果返回的是真的话 那么我们应该销毁掉这个子弹     return this.y < -this.height;   }   collide() {     //让这颗子弹变成可销毁状态     this.destory = true;   } }  export default Bullet 

 

这里需要提一嘴的是,类的导出必须带 default,否则会报错

export default Bullet 

 

 

4.主启动类main

我们将所有曾经的全局方法,还有定时器都封装到这个类中

最后新建一个实例,并导出

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

  1 import Enemy from "./enemy"   2 import Hero from "./hero"   3 import Loading from "./loading"   4 import Sky from "./sky"   5 import Award from "./award"   6    7 import { START, STARTING, RUNNING, PAUSE, END } from "./config"   8 import { SKY, LOADING, HERO, E1, E2, E3, C1 } from "./config"   9 import { bg, copyright, pause } from "./config"  10 import { canvas, context } from "./config"  11   12 class Main {  13     //以下全为全局变量或方法 (全局的!!)  14     //初始化一个天空实例  15     //主启动方法  16     maingame() {  17         const sky = new Sky(SKY);  18         //初始化一个飞机界面加载实例  19         const loading = new Loading(LOADING);  20         //初始化一个英雄实例 英雄是会变的  21         let hero = new Hero(HERO);  22         //该变量中有所有的敌机实例  23         let enemies = [];  24         //该变量中存放所有的奖励实例  25         let awards = [];  26         //敌机产生的速率  27         let ENEMY_CREATE_INTERVAL = 800;  28         let ENEMY_LASTTIME = new Date().getTime();  29   30         function stateControl() {  31             //为canvas绑定一个点击事件 且他如果是START状态的时候需要修改成STARTING状态  32             canvas.addEventListener("click", () => {  33                 if (state === START) {  34                     state = STARTING;  35                 }  36             });  37             // 为canvas绑定一个鼠标移动事件 鼠标正好在飞机图片的正中心  38             canvas.addEventListener("mousemove", (e) => {  39                 let x = e.offsetX;  40                 let y = e.offsetY;  41                 hero.x = x - hero.width / 2;  42                 hero.y = y - hero.height / 2;  43             });  44             // 为canvas绑定一个鼠标离开事件 鼠标离开时 RUNNING -> PAUSE  45             canvas.addEventListener("mouseleave", () => {  46                 if (state === RUNNING) {  47                     state = PAUSE;  48                 }  49             });  50             // 为canvas绑定一个鼠标进入事件 鼠标进入时 PAUSE => RUNNING  51             canvas.addEventListener("mouseenter", () => {  52                 if (state === PAUSE) {  53                     state = RUNNING;  54                 }  55             });  56             //为canvas绑定一个屏幕移动触摸点事件 触碰点正好在飞机图片的正中心  57             canvas.addEventListener("touchmove", (e) => {  58                 // let x = e.pageX;  59                 // let y = e.pageY;  60                 console.log(e);  61                 // let x = e.touches[0].clientX;  62                 // let y = e.touches[0].clinetY;  63                 let x = e.touches[0].pageX;  64                 let y = e.touches[0].pageY;  65                 // let x = e.touches[0].screenX;  66                 // let y = e.touches[0].screenY;  67                 let write1 = (document.body.clientWidth - 480) / 2;  68                 let write2 = (document.body.clientHeight - 650) / 2;  69                 hero.x = x - write1 - hero.width / 2;  70                 hero.y = y - write2 - hero.height / 2;  71   72                 // hero.x = x - hero.width / 2;  73                 // hero.y = y - hero.height / 2;  74                 console.log(x, y);  75                 console.log(document.body.clientWidth, document.body.clientHeight);  76                 e.preventDefault(); // 阻止屏幕滚动的默认行为  77   78             })  79         }  80         stateControl();  81         // 碰撞检测函数  82         //此处的碰撞检测包括   83         //1.子弹与敌机的碰撞  84         //2.英雄与敌机的碰撞  85         //3.英雄与随机奖励的碰撞  86         function checkHit() {  87             // 遍历所有的敌机  88             for (let i = 0; i < awards.length; i++) {  89                 //检测英雄是否碰到奖励类  90                 if (awards[i].hit(hero)) {  91                     //当然了,这个随机奖励的样式也要删了  92                     awards.splice(i, 1);  93                     //清除所有的敌机  94                     // for (let i = 0; i < enemies.length; i++) {  95                     //   enemies.splice(i, 1);  96                     // }  97                     enemies.length = 0;  98   99                 } 100             } 101             for (let i = 0; i < enemies.length; i++) { 102                 //检测英雄是否撞到敌机 103                 if (enemies[i].hit(hero)) { 104                     //将敌机和英雄的destory属性改为true 105                     enemies[i].collide(); 106                     hero.collide(); 107                 } 108                 for (let j = 0; j < hero.bulletList.length; j++) { 109                     enemies[i].hit(hero.bulletList[j]); 110                     //检测子弹是否撞到敌机 111                     if (enemies[i].hit(hero.bulletList[j])) { 112                         //将敌机和子弹的destory属性改为true 113                         enemies[i].collide(); 114                         hero.bulletList[j].collide(); 115                     } 116                 } 117             } 118         } 119         // 全局函数 隔一段时间就来初始化一架敌机/奖励 120         function createComponent() { 121             const currentTime = new Date().getTime(); 122             if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL) { 123                 let ran = Math.floor(Math.random() * 100); 124                 if (ran < 55) { 125                     enemies.push(new Enemy(E1)); 126                 } else if (ran < 85 && ran > 55) { 127                     enemies.push(new Enemy(E2)); 128                 } else if (ran < 95 && ran > 85) { 129                     enemies.push(new Enemy(E3)); 130                 } else if (ran > 95) { 131                     awards.push(new Award(C1)); 132  133                 } 134  135                 ENEMY_LASTTIME = currentTime; 136             } 137         } 138         // 全局函数 来判断所有的子弹/敌人组件 "负责移动" 139         function judgeComponent() { 140             for (let i = 0; i < hero.bulletList.length; i++) { 141                 hero.bulletList[i].move(); 142             } 143             for (let i = 0; i < enemies.length; i++) { 144                 enemies[i].move(); 145             } 146             for (let i = 0; i < awards.length; i++) { 147                 awards[i].move(); 148             } 149         } 150         // 全局函数 来绘制所有的子弹/敌人组件 绘制score&life面板 151         function paintComponent() { 152             for (let i = 0; i < hero.bulletList.length; i++) { 153                 hero.bulletList[i].paint(context); 154             } 155             for (let i = 0; i < enemies.length; i++) { 156                 enemies[i].paint(context); 157             } 158             for (let i = 0; i < awards.length; i++) { 159                 awards[i].paint(context); 160             } 161             context.font = "20px 微软雅黑"; 162             context.fillStyle = "green"; 163             context.textAlign = "left"; 164             context.fillText("score: " + score, 10, 20); 165             context.textAlign = "right"; 166             context.fillText("life: " + life, 480 - 10, 20); 167             //重置样式 168             context.fillStyle = "black"; 169             context.textAlign = "left"; 170         } 171         // 全局函数 来销毁所有的子弹/敌人组件 销毁掉英雄 172         function deleteComponent() { 173             if (hero.destory) { 174                 life--; 175                 hero.destory = false; 176                 if (life === 0) { 177                     state = END; 178                 } else { 179                     hero = new Hero(HERO); 180                 } 181             } 182             for (let i = 0; i < hero.bulletList.length; i++) { 183                 if (hero.bulletList[i].outOfBounds() || hero.bulletList[i].destory) { 184                     hero.bulletList.splice(i, 1); 185                 } 186             } 187             for (let i = 0; i < enemies.length; i++) { 188                 if (enemies[i].outOfBounds() || enemies[i].destory) { 189                     enemies.splice(i, 1); 190                 } 191             } 192         } 193  194         //当图片加载完毕时,需要做某些事情 195         bg.addEventListener("load", () => { 196             setInterval(() => { 197                 switch (state) { 198                     case START: 199                         sky.judge(); 200                         sky.paint(context); 201                         let logo_x = (480 - copyright.naturalWidth) / 2; 202                         let logo_y = (650 - copyright.naturalHeight) / 2; 203                         context.drawImage(copyright, logo_x, logo_y); 204                         break; 205                     case STARTING: 206                         sky.judge(); 207                         sky.paint(context); 208                         loading.judge(); 209                         loading.paint(context); 210                         break; 211                     case RUNNING: 212                         sky.judge(); 213                         sky.paint(context); 214                         hero.judge(); 215                         hero.paint(context); 216                         hero.shoot(context); 217                         createComponent(); 218                         judgeComponent(); 219                         deleteComponent(); 220                         paintComponent(); 221                         checkHit(); 222                         break; 223                     case PAUSE: 224                         let pause_x = (480 - pause.naturalWidth) / 2; 225                         let pause_y = (650 - pause.naturalHeight) / 2; 226                         context.drawImage(pause, pause_x, pause_y); 227                         break; 228                     case END: 229                         //给我的画笔设置一个字的样式 230                         //后面写出来的字都是这个样式的 231                         context.font = "bold 24px 微软雅黑"; 232                         context.textAlign = "center"; 233                         context.textBaseline = "middle"; 234                         context.fillText("GAME_OVER", 480 / 2, 650 / 2); 235                         break; 236                 } 237             }, 10); 238         }); 239  240  241         //背景切换方法 242         // function changebg() { 243         //     console.log("changebg方法被触发") 244         //     bg.src = "img/background.png" 245         // } 246     } 247 } 248 export let main_1 = new Main() 249 // export default Main 

main.js

 

 

5.包的入口

首先看一眼package.json

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 看main,(这个可以自己调的)

由上图可知,这个包的入口就是index.js了

 

//index.js export { canvas } from "./config" export { main_1 } from "./main"

config.js中的canvas

export let canvas = document.createElement('canvas'); canvas.width = 480; canvas.height = 650; canvas.ref = canvas; canvas.style = "border: 1px solid red;"

main.js中的main

export let main_1 = new Main()

 

在这里,用上我们前几天学的语法(嘿嘿)

我的第一个项目(十一) :飞机大战分包完成(简单阐述分包思路以及过程)

 

分包完成

 

 

发表评论

评论已关闭。

相关文章