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

html,飞机,大战,十八,模块化,项目,开源 · 浏览次数 : 60

小编点评

**游戏核心代码** ```javascript // 全局变量 let hero, enemies, awards, score, life; // 创建游戏组件 function createComponent() { // 生成随机敌机或奖励 if (Math.random() < 55) { enemies.push(new Enemy(E1)); } else if (Math.random() < 85 && Math.random() > 55) { enemies.push(new Enemy(E2)); } else if (Math.random() < 95 && Math.random() > 85) { enemies.push(new Enemy(E3)); } else { awards.push(new award(C1)); } // 更新EMY_LASTTIME ENEMY_LASTTIME = new Date().getTime(); } // 判断游戏组件是否应该移动 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(); } } // 绘制游戏组件 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); } // 销毁游戏组件 function deleteComponent() { // 销毁英雄 if (hero.destory) { life--; hero.destory = false; if (life === 0) { state = END; } } // 销毁敌人 for (let i = 0; i < enemies.length; i++) { enemies[i].destroy(); } // 销毁奖励 for (let i = 0; i < awards.length; i++) { awards[i].destroy(); } } // 检查碰撞 function checkHit() { // 检查子弹与敌人碰撞 for (let i = 0; i < hero.bulletList.length; i++) { for (let j = 0; j < enemies.length; j++) { if (hero.bulletList[i].collidesWith(enemies[j])) { // 播放碰撞音效和特效 // 更新游戏状态 // 消失敌人和奖励 } } } // 检查敌人与奖励碰撞 for (let i = 0; i < enemies.length; i++) { if (enemies[i].collidesWith(awards[0])) { // 播放碰撞音效和特效 // 更新游戏状态 // 消失敌人和奖励 } } } // 游戏循环 function main_1() { // 创建画布对象 const canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); // 定义游戏状态 let state = START; // 开始游戏循环 while (state !== END) { switch (state) { case START: // 初始化游戏 createComponent(); judgeComponent(); break; case RUNNING: // 运行游戏逻辑 judgeComponent(); paintComponent(); checkHit(); break; case PAUSE: // 暂停游戏 break; case END: // 显示游戏结束界面 break; } // 刷新画布 requestAnimationFrame(main_1); } } // 启动游戏 main_1(); ``` **配置项** ``` let canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); // 定义游戏状态 let state = START; // 初始化画布对象 const canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); // 定义游戏逻辑 // ... ```

正文

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

 

 

 

 

 

 

 

 

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

项目已开源:

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;

 

与Html飞机大战(十八): 模块化+项目开源相似的内容:

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

好家伙,好久好久没有更新这个系列了 为了使文档更方便阅读,使代码更容易维护,来把这个飞机大战模块化 项目已开源: https://gitee.com/tang-and-han-dynasties/airplane-battle h.git 项目结构如下: 最大的改动是主启动类进行了修改: 我们将曾经

我的第一个项目(十) :处理全局变量(解决模块化后变量无法获取的问题)

好家伙, 飞机大战分包分的差不多了, 但是又出现了问题: 文件目录如下: 然而关于变量 helloworld.vue完整代码

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

好家伙, 代码已开源 Git: https://gitee.com/tang-and-han-dynasties/panghu-planebattle-esm.git NPM: panghu-planebattle-esm - npm (npmjs.com) 现在,比如说,我用Vue写好了个人博客主

我的第一个项目(九) :飞机大战Vue版本塞到主页

好家伙, 这是未进行分包的vue版本的飞机大战 效果如下: 这里说明一下,大概使用逻辑是提供一个 然后在这中渲染游戏 游戏主界面代码如下: 1 2 3 欢迎来到主页面 4 5

我的第一个NPM包:panghu-planebattle-esm(胖虎飞机大战)使用说明

好家伙,我的包终于开发完啦 欢迎使用胖虎的飞机大战包!! 为你的主页添加色彩 这是一个有趣的网页小游戏包,使用canvas和js开发 使用ES6模块化开发 效果图如下: (觉得图片太sb的可以自己改) 代码已开源!! Git: https://gitee.com/tang-and-han-dynas

我的第一个项目(七):(解决问题)Vue中canvas无法绘制图片

好家伙, 现在,我想要把我的飞机大战塞到我的主页里去,想办法把文件导入 然后,直接死在第一步,图片渲染都成问题 先用vue写一个测试文件 来测试canvas的绘制

第134篇:解决浏览器的CORS跨域问题(CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.)

好家伙, 我继续尝试着将我的飞机大战使用ES6模块化分离开来,出了点问题 1.出现问题: edge,chrome等一系列浏览器,会为了安全,禁止你跨域访问 目录如下: 主程序 index.html main_1.js main.js 完整代码如下: 1 /* //plane封装成类 2 //实例化后

CCPC 2023 湘潭邀请赛游记

序 04:36,长沙返程的硬卧列车上。 禁不起隔壁大叔富有特色的鼾声,对着窗外发愣。 写写游记吧。 Day (-inf, 0) 由于 UCUP Taiwan 场神奇的发挥,意外获得湘潭邀请赛名额 x1。公费旅游万岁! 然而,飞机不给报,高铁不给报,软卧不给报,打车也不给报,路途时间高达 30h,还被

2022年终总结

这是工作的第三年了,IT人的三年之痒,亦或许是觉得自己翅膀硬了,我辞去了毕业后第一份国企工作,投奔了某IT大厂 一、变化 这一年,我从泉城济南,来到了成都;离家的距离从1500公里+缩减到了,700公里,以后回家可以考虑飞机以外的交通工具了。 职业上,从纯开发,逐渐向自动化、测试工具开发靠拢,感觉上

讯飞星火大模型 与New Bing实测对比

昨天科大讯飞发布了讯飞星火认知大模型,在发布会现场实测大模型的7种核心能力,并发布了它在教育、办公、汽车、数字员工领域的应用成果。科大讯飞董事长刘庆峰表示:认知大模型展示了通用人工智能的曙光,讯飞星火认知大模型已在文本生成、知识问答、数学能力3种能力上超越ChatGPT。NewBing 也全面开放给