最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

环球热头条丨我的第一个项目(九) :飞机大战Vue版本塞到主页

来源:博客园


(相关资料图)

好家伙,

这是未进行分包的vue版本的飞机大战

效果如下:

这里说明一下,大概使用逻辑是提供一个

然后在这

中渲染游戏

游戏主界面代码如下:

1   7     8   <script>  9   export default { 10     mounted() { 11         //canvas初始化 12         console.log("我被执行啦") 13         let canvas = document.createElement("canvas"); 14         this.$refs.stage.appendChild(canvas); 15         canvas.width = 480; 16         canvas.height = 650; 17         canvas.ref = canvas; 18         canvas.style = "border: 1px solid red;" 19         const context = canvas.getContext("2d"); 20    21         //图片初始化方法 22         function createImage(src) { 23           let img; 24           if (typeof src === "string") { 25             img = new Image(); 26             img.src = require("./img/" + src); 27           } else { 28             img = []; 29             for (let i = 0; i < src.length; i++) { 30               img[i] = new Image(); 31               img[i].src = require("./img/" + src[i]); 32             } 33           } 34           return img; 35         } 36         //createImage()方法测试样例 37         // let bg = createImage("4.jpg") 38         // bg.onload = function () { 39         //   console.log("img加载完毕") 40         //   context.drawImage(bg, 0, 0, 480, 650) 41         // } 42         const IMAGES = { 43           b: "bullet1.png", 44           bg: "4.png", 45           copyright: "shoot_copyright.png", 46           pause: "game_pause.png", 47           loading_frame: ["game_loading1.png", "game_loading2.png", "game_loading3.png", 48             "game_loading4.png" 49           ], 50           hero_frame_live: ["hero1.png", "hero2.png"], 51           hero_frame_death: ["hero_blowup_n1.png", "hero_blowup_n2.png", "hero_blowup_n3.png", 52             "hero_blowup_n4.png" 53           ], 54           e1_live: ["enemy1.png"], 55           e1_death: ["enemy1_down1.png", "enemy1_down2.png", "enemy1_down3.png", "enemy1_down4.png"], 56           e2_live: ["enemy2.png"], 57           e2_death: ["enemy2_down1.png", "enemy2_down2.png", "enemy2_down3.png", "enemy2_down4.png"], 58           e3_live: ["enemy3_n1.png", "enemy3_n2.png"], 59           e3_death: ["enemy3_down1.png", "enemy3_down2.png", "enemy3_down3.png", "enemy3_down4.png", 60             "enemy3_down5.png", "enemy3_down6.png" 61           ], 62           c1: "lanqiu.png" 63         }; 64         //初始化各个图片 65         const b = createImage(IMAGES.b); 66         const bg = createImage(IMAGES.bg); 67         const copyright = createImage(IMAGES.copyright); 68         const pause = createImage(IMAGES.pause); 69         const loading_frame = createImage(IMAGES.loading_frame); 70         const hero_frame = { 71           live: createImage(IMAGES.hero_frame_live), 72           death: createImage(IMAGES.hero_frame_death), 73         }; 74         const e1 = { 75           live: createImage(IMAGES.e1_live), 76           death: createImage(IMAGES.e1_death), 77         }; 78         const e2 = { 79           live: createImage(IMAGES.e2_live), 80           death: createImage(IMAGES.e2_death), 81         }; 82         const e3 = { 83           live: createImage(IMAGES.e3_live), 84           death: createImage(IMAGES.e3_death), 85         }; 86         const c1 = createImage(IMAGES.c1); 87    88         //配置项: 89         // 定义游戏的状态 90         // 开始 91         const START = 0; 92         // 开始时 93         const STARTING = 1; 94         // 运行时 95         const RUNNING = 2; 96         // 暂停时 97         const PAUSE = 3; 98         // 结束时 99         const END = 4;100         // 加载中101         const LOADINGING = 5;102   103         //state表示游戏的状态 取值必须是以上的五种状态104         let state = LOADINGING;105         // hero_frame.addEventListener("load", () => {106         //   state = START;107         // })108   109         pause.onload = function () {110           state = START;111           console.log(state)112         }113   114         //score 分数变量 life 变量115         let score = 0;116         let life = 3;117   118         //天空类的配置项119         const SKY = {120           bg: bg,121           width: 480,122           height: 650,123           speed: 10,124         };125   126         // 飞机加载界面的配置项127         const LOADING = {128           frame: loading_frame,129           width: 186,130           height: 38,131           x: 0,132           y: 650 - 38,133           speed: 400,134         };135   136         // 英雄配置项137         const HERO = {138           frame: hero_frame,139           width: 99,140           height: 124,141           speed: 100,142         };143   144         // 子弹配置项145         const BULLET = {146           img: b,147           width: 9,148           height: 21,149         };150   151         //小敌机配置项152         const E1 = {153           type: 1,154           width: 57,155           height: 51,156           life: 10,157           score: 1,158           frame: e1,159           minSpeed: 20,160           maxSpeed: 10161         };162         //中敌机配置项163         const E2 = {164           type: 2,165           width: 69,166           height: 95,167           life: 50,168           score: 5,169           frame: e2,170           minSpeed: 50,171           maxSpeed: 20172         };173         //打敌机配置项174         const E3 = {175           type: 3,176           width: 169,177           height: 258,178           life: 100,179           score: 20,180           frame: e3,181           minSpeed: 100,182           maxSpeed: 100183         };184         //奖励类配置项185         const C1 = {186           type: 4,187           width: 75,188           height: 75,189           life: 1,190           score: 1,191           img: c1,192           minSpeed: 5,193           maxSpeed: 10194         };195         //正式代码196   197         //初始化奖励类198         class Award {199           constructor(config) {200             this.type = config.type;201             this.width = config.width;202             this.height = config.height;203             this.x = Math.floor(Math.random() * (480 - config.width));204             this.y = -config.height;205             this.life = config.life;206             this.score = config.score;207             this.img = config.img;208             this.live = true;209             this.speed = Math.floor(Math.random() * (config.minSpeed - config.maxSpeed + 1)) + config.maxSpeed;210             this.lastTime = new Date().getTime();211             this.deathIndex = 0;212             this.destory = false;213           }214           move() {215             const currentTime = new Date().getTime();216             if (currentTime - this.lastTime >= this.speed) {217               if (this.live) {218                 this.y = this.y + 6;219                 this.lastTime = currentTime;220               } else {221                 this.destory = true;222   223               }224             }225           }226           paint(context) {227             context.drawImage(this.img, this.x, this.y, this.width, this.height);228           }229           outOfBounds() {230             if (this.y > 650) {231               return true;232             }233           }234           hit(o) {235             let ol = o.x;236             let or = o.x + o.width;237             let ot = o.y;238             let ob = o.y + o.height;239             let el = this.x;240             let er = this.x + this.width;241             let et = this.y;242             let eb = this.y + this.height;243             if (ol > er || or < el || ot > eb || ob < et) {244               return false;245             } else {246               return true;247             }248           }249           // collide() {250           //   this.life--;251           //   if (this.life === 0) {252           //     this.live = false;253           //     score += this.score;254           //   }255           // }256         }257   258         //259         //初始化一个子弹类260         class Bullet {261           constructor(config, x, y) {262             this.img = config.img;263             this.width = config.width;264             this.height = config.height;265             this.x = x;266             this.y = y;267             this.destory = false;268           }269           //子弹绘制方法270           paint(context) {271             context.drawImage(this.img, this.x, this.y);272           }273           //移动子弹 this.y--274           move() {275             this.y -= 8;276           }277           outOfBounds() {278             //如果返回的是真的话 那么我们应该销毁掉这个子弹279             return this.y < -this.height;280           }281           collide() {282             //让这颗子弹变成可销毁状态283             this.destory = true;284           }285         }286         //287   288         // 初始化一个敌机类289         class Enemy {290   291   292   293   294   295           296           constructor(config) {297             this.type = config.type;298             this.width = config.width;299             this.height = config.height;300             this.x = Math.floor(Math.random() * (480 - config.width));301             this.y = -config.height;302             this.life = config.life;303             this.score = config.score;304             this.frame = config.frame;305             this.img = this.frame.live[0];306             this.live = true;307             this.speed = Math.floor(Math.random() * (config.minSpeed - config.maxSpeed + 1)) + config.maxSpeed;308             this.lastTime = new Date().getTime();309             this.deathIndex = 0;310             this.destory = false;311           }312           move() {313             const currentTime = new Date().getTime();314             if (currentTime - this.lastTime >= this.speed) {315               if (this.live) {316                 this.img = this.frame.live[0];317                 this.y++;318                 this.lastTime = currentTime;319               } else {320                 this.img = this.frame.death[this.deathIndex++];321                 if (this.deathIndex === this.frame.death.length) {322                   this.destory = true;323                 }324               }325             }326           }327           paint(context) {328             context.drawImage(this.img, this.x, this.y);329           }330           outOfBounds() {331             if (this.y > 650) {332               return true;333             }334           }335           hit(o) {336             let ol = o.x;337             let or = o.x + o.width;338             let ot = o.y;339             let ob = o.y + o.height;340             let el = this.x;341             let er = this.x + this.width;342             let et = this.y;343             let eb = this.y + this.height;344             if (ol > er || or < el || ot > eb || ob < et) {345               return false;346             } else {347               return true;348             }349           }350           collide() {351             this.life--;352             if (this.life === 0) {353               this.live = false;354               score += this.score;355             }356           }357         }358   359         //360         // 初始化一个英雄类361         class Hero {362           constructor(config) {363             this.width = config.width;364             this.height = config.height;365             this.x = (480 - config.width) / 2;366             this.y = 650 - config.height;367             this.frame = config.frame;368             this.frameLiveIndex = 0;369             this.frameDeathIndex = 0;370             this.lastTime = new Date().getTime();371             this.speed = config.speed;372             //当前展示的图片373             this.img = null;374             this.live = true;375             //子弹上次射击的时间376             this.lastShootTime = new Date().getTime();377             //子弹射击的间隔378             this.shootInterval = 50;379             //子弹夹数组380             this.bulletList = [];381             this.destory = false;382           }383           judge() {384             const currentTime = new Date().getTime();385             if (currentTime - this.lastTime > this.speed) {386               if (this.live) {387                 this.img = this.frame.live[this.frameLiveIndex++ % this.frame.live.length];388               } else {389                 //0 1 2 3 4390                 this.img = this.frame.death[this.frameDeathIndex++];391                 //到4的时候英雄死了392                 if (this.frameDeathIndex === this.frame.death.length) {393                   this.destory = true;394                 }395               }396               this.lastTime = currentTime;397             }398           }399           paint(context) {400             context.drawImage(this.img, this.x, this.y, this.width, this.height);401           }402           //英雄可以射击子弹403           shoot() {404             //获取当前时间405             const currentTime = new Date().getTime();406             //飞机的位置407             if (currentTime - this.lastShootTime > this.shootInterval) {408               //在飞机的头部初始化一个子弹对象409               let bullet = new Bullet(BULLET, this.x + this.width / 2 - BULLET.width / 2, this.y - BULLET.height);410               //英雄飞机要认领这个子弹411               this.bulletList.push(bullet);412               //在网页上绘制一个子弹对象413               bullet.paint(context);414               //更新英雄射击时间415               this.lastShootTime = currentTime;416             }417           }418           collide() {419             //将活着标识符切换为false420             //活着 -> 爆炸中 -> 死亡(销毁)421             this.live = false;422           }423         }424         //425         // 初始化一个飞机界面加载类426         class Loading {427           constructor(config) {428             this.frame = config.frame;429             this.frameIndex = 0;430             this.width = config.width;431             this.height = config.height;432             this.x = config.x;433             this.y = config.y;434             this.speed = config.speed;435             this.lastTime = new Date().getTime();436           }437           judge() {438             const currentTime = new Date().getTime();439             if (currentTime - this.lastTime > this.speed) {440               this.frameIndex++;441               if (this.frameIndex === 4) {442                 state = RUNNING;443               }444               this.lastTime = currentTime;445             }446           }447           paint(context) {448             context.drawImage(this.frame[this.frameIndex], this.x, this.y);449           }450         }451   452   453         class Main {454           //一下全为全局变量或方法 (全局的!!)455           //初始化一个天空实例456           //主启动方法457           maingame() {458             const sky = new Sky(SKY);459             //初始化一个飞机界面加载实例460             const loading = new Loading(LOADING);461             //初始化一个英雄实例 英雄是会变的462             let hero = new Hero(HERO);463             //该变量中有所有的敌机实例464             let enemies = [];465             //该变量中存放所有的奖励实例466   467             let awards = [];468             //敌机产生的速率469             let ENEMY_CREATE_INTERVAL = 800;470             let ENEMY_LASTTIME = new Date().getTime();471   472             function stateControl() {473               //为canvas绑定一个点击事件 且他如果是START状态的时候需要修改成STARTING状态474               canvas.addEventListener("click", () => {475                 if (state === START) {476                   state = STARTING;477                 }478               });479               // 为canvas绑定一个鼠标移动事件 鼠标正好在飞机图片的正中心480               canvas.addEventListener("mousemove", (e) => {481                 let x = e.offsetX;482                 let y = e.offsetY;483                 hero.x = x - hero.width / 2;484                 hero.y = y - hero.height / 2;485               });486               // 为canvas绑定一个鼠标离开事件 鼠标离开时 RUNNING -> PAUSE487               canvas.addEventListener("mouseleave", () => {488                 if (state === RUNNING) {489                   state = PAUSE;490                 }491               });492               // 为canvas绑定一个鼠标进入事件 鼠标进入时 PAUSE => RUNNING493               canvas.addEventListener("mouseenter", () => {494                 if (state === PAUSE) {495                   state = RUNNING;496                 }497               });498               //为canvas绑定一个屏幕移动触摸点事件 触碰点正好在飞机图片的正中心499               canvas.addEventListener("touchmove", (e) => {500                 // let x = e.pageX;501                 // let y = e.pageY;502                 console.log(e);503                 // let x = e.touches[0].clientX;504                 // let y = e.touches[0].clinetY;505                 let x = e.touches[0].pageX;506                 let y = e.touches[0].pageY;507                 // let x = e.touches[0].screenX;508                 // let y = e.touches[0].screenY;509                 let write1 = (document.body.clientWidth - 480) / 2;510                 let write2 = (document.body.clientHeight - 650) / 2;511                 hero.x = x - write1 - hero.width / 2;512                 hero.y = y - write2 - hero.height / 2;513   514                 // hero.x = x - hero.width / 2;515                 // hero.y = y - hero.height / 2;516                 console.log(x, y);517                 console.log(document.body.clientWidth, document.body.clientHeight);518                 e.preventDefault(); // 阻止屏幕滚动的默认行为519   520               })521             }522             stateControl();523             // 碰撞检测函数524             //此处的碰撞检测包括 525             //1.子弹与敌机的碰撞526             //2.英雄与敌机的碰撞527             //3.英雄与随机奖励的碰撞528             function checkHit() {529               // 遍历所有的敌机530               for (let i = 0; i < awards.length; i++) {531                 //检测英雄是否碰到奖励类532                 if (awards[i].hit(hero)) {533                   //当然了,这个随机奖励的样式也要删了534                   awards.splice(i, 1);535                   //清除所有的敌机536                   // for (let i = 0; i < enemies.length; i++) {537                   //   enemies.splice(i, 1);538                   // }539                   enemies.length = 0;540   541                 }542               }543               for (let i = 0; i < enemies.length; i++) {544                 //检测英雄是否撞到敌机545                 if (enemies[i].hit(hero)) {546                   //将敌机和英雄的destory属性改为true547                   enemies[i].collide();548                   hero.collide();549                 }550                 for (let j = 0; j < hero.bulletList.length; j++) {551                   enemies[i].hit(hero.bulletList[j]);552                   //检测子弹是否撞到敌机553                   if (enemies[i].hit(hero.bulletList[j])) {554                     //将敌机和子弹的destory属性改为true555                     enemies[i].collide();556                     hero.bulletList[j].collide();557                   }558                 }559               }560             }561             // 全局函数 隔一段时间就来初始化一架敌机/奖励562             function createComponent() {563               const currentTime = new Date().getTime();564               if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL) {565                 let ran = Math.floor(Math.random() * 100);566                 if (ran < 55) {567                   enemies.push(new Enemy(E1));568                 } else if (ran < 85 && ran > 55) {569                   enemies.push(new Enemy(E2));570                 } else if (ran < 95 && ran > 85) {571                   enemies.push(new Enemy(E3));572                 } else if (ran > 95) {573                   awards.push(new award(C1));574   575                 }576   577                 ENEMY_LASTTIME = currentTime;578               }579             }580             // 全局函数 来判断所有的子弹/敌人组件 "负责移动"581             function judgeComponent() {582               for (let i = 0; i < hero.bulletList.length; i++) {583                 hero.bulletList[i].move();584               }585               for (let i = 0; i < enemies.length; i++) {586                 enemies[i].move();587               }588               for (let i = 0; i < awards.length; i++) {589                 awards[i].move();590               }591             }592             // 全局函数 来绘制所有的子弹/敌人组件 绘制score&life面板593             function paintComponent() {594               for (let i = 0; i < hero.bulletList.length; i++) {595                 hero.bulletList[i].paint(context);596               }597               for (let i = 0; i < enemies.length; i++) {598                 enemies[i].paint(context);599               }600               for (let i = 0; i < awards.length; i++) {601                 awards[i].paint(context);602               }603               context.font = "20px 微软雅黑";604               context.fillStyle = "green";605               context.textAlign = "left";606               context.fillText("score: " + score, 10, 20);607               context.textAlign = "right";608               context.fillText("life: " + life, 480 - 10, 20);609               //重置样式610               context.fillStyle = "black";611               context.textAlign = "left";612             }613             // 全局函数 来销毁所有的子弹/敌人组件 销毁掉英雄614             function deleteComponent() {615               if (hero.destory) {616                 life--;617                 hero.destory = false;618                 if (life === 0) {619                   state = END;620                 } else {621                   hero = new Hero(HERO);622                 }623               }624               for (let i = 0; i < hero.bulletList.length; i++) {625                 if (hero.bulletList[i].outOfBounds() || hero.bulletList[i].destory) {626                   hero.bulletList.splice(i, 1);627                 }628               }629               for (let i = 0; i < enemies.length; i++) {630                 if (enemies[i].outOfBounds() || enemies[i].destory) {631                   enemies.splice(i, 1);632                 }633               }634             }635   636             //当图片加载完毕时,需要做某些事情637             bg.addEventListener("load", () => {638               setInterval(() => {639                 switch (state) {640                   case START:641                     sky.judge();642                     sky.paint(context);643                     let logo_x = (480 - copyright.naturalWidth) / 2;644                     let logo_y = (650 - copyright.naturalHeight) / 2;645                     context.drawImage(copyright, logo_x, logo_y);646                     break;647                   case STARTING:648                     sky.judge();649                     sky.paint(context);650                     loading.judge();651                     loading.paint(context);652                     break;653                   case RUNNING:654                     sky.judge();655                     sky.paint(context);656                     hero.judge();657                     hero.paint(context);658                     hero.shoot();659                     createComponent();660                     judgeComponent();661                     deleteComponent();662                     paintComponent();663                     checkHit();664                     break;665                   case PAUSE:666                     let pause_x = (480 - pause.naturalWidth) / 2;667                     let pause_y = (650 - pause.naturalHeight) / 2;668                     context.drawImage(pause, pause_x, pause_y);669                     break;670                   case END:671                     //给我的画笔设置一个字的样式672                     //后面写出来的字都是这个样式的673                     context.font = "bold 24px 微软雅黑";674                     context.textAlign = "center";675                     context.textBaseline = "middle";676                     context.fillText("GAME_OVER", 480 / 2, 650 / 2);677                     break;678                 }679               }, 10);680             });681   682   683             //背景切换方法684             // function changebg() {685             //     console.log("changebg方法被触发")686             //     bg.src = "img/background.png"687             // }688           }689         }690         //691   692         //初始化一个天空类693         class Sky {694           constructor(config) {695             this.bg = config.bg;696             this.width = config.width;697             this.height = config.height;698             this.x1 = 0;699             this.y1 = 0;700             this.x2 = 0;701             this.y2 = -this.height;702             this.speed = config.speed;703             this.lastTime = new Date().getTime();704           }705           //判断方法706           judge() {707             let currentTime = new Date().getTime();708             if (currentTime - this.lastTime > this.speed) {709               this.y1++;710               this.y2++;711               this.lastTime = currentTime;712             }713             if (this.y2 === 0) {714               this.y1 = 0;715               this.y2 = -this.height;716             }717           }718           //绘图方法719           paint(context) {720             context.drawImage(this.bg, this.x1, this.y1, this.width, this.height);721             context.drawImage(this.bg, this.x2, this.y2, this.width, this.height);722           }723         }724         let main_1 = new Main()725         main_1.maingame();726       }727     }728   729   730   </script>731   732   739   740   

关键词: