想要游戏变得有点难度的话 就得让敌机自己动起来(移动轨迹提前设置好)那么就得单独的来进行控制敌机上下左右发射

首先制作数据:

/*** health:生命值* width:宽度* height:高度* image:图片* enemyMoveFunc:function 返回自动移动的数据* timer:ms 执行时间间隔时间* moveDirection:移动方向、按下的键位 可以设置多个 , 作为分隔符 将会同时按下* distance:一次性移动多少距离* isHideHealth:是否不显示血量*/
planeLeftRight: {type: "enemy",health: 100,width: 80,height: 60,distance: 2,delayX: 100,image: "enemy-1",bulletNumber: 1,canvasImage: enemyImage_1,enemyMoveFunc() {return [{timer: 500,moveDirection: "button",distance: 3,},{timer: 500,moveDirection: "left,shoot",distance: 3,},{timer: 2000,moveDirection: "button,right",distance: 4,},{timer: 3000,moveDirection: "top,left,shoot",distance: 3,},{timer: 3000,moveDirection: "right",distance: 3,},{timer: 6000,moveDirection: "button",distance: 3,},];},},

可以看到 我添加一堆移动预设 有发射有上下左右 等等 接下来就是解析

// 移动映射函数 对应函数名字
this.moveDirectionMap = {top: "enemyForward",button: "enemyBackOff",left: "enemyLeftTranslation",right: "enemyRightTranslation",shoot: "enemyShoot",};
// 飞机移动enemyMove() {// 获取移动的数据const autoMoveList = this.autoMoveList;// 按键映射const moveDirectionMap = this.moveDirectionMap;if (Array.isArray(autoMoveList) && autoMoveList.length !== 0) {// 如果当前没有正在移动的数据则进行重新判断let operationIndex = 0;// 使用自定义移动方法const moveFunc = async () => {// 检测并运行const singleMove = autoMoveList[operationIndex];if (singleMove === undefined) return;// 配置当前操作const operationOptions = {operationIndex: operationIndex,operationTimer: null,moveNumber: 1,moveTimer: null,operationStop() {if (this.operationTimer) {clearTimeout(this.operationTimer);this.operationTimer = null;}if (this.moveTimer) {clearInterval(this.moveTimer);this.moveTimer = null;}},};// 将操作表进行分割 进行多个按键同时生效const directionList = singleMove.moveDirection.split(",");for (const index in directionList) {if (Object.hasOwnProperty.call(directionList, index)) {const element = directionList[index];// 调用移动方法this[moveDirectionMap[element]] &&this[moveDirectionMap[element]]();}}// 添加相对应的速度this.enemyFlySpeed = (singleMove.distance || this.enemyFlySpeed) * this.speedUp;// 进行移动时间记录 按照 60hz/1(具体取决于配置的飞机移动间隔) 的记录规则operationOptions.moveTimer = interval(() => {operationOptions.moveNumber += 1;}, allMoveSpeed);// 等待上一个执行完后执行下一个operationOptions.operationTimer = setTimeout(() => {// 停止移动this.enemyStop();operationIndex += 1;operationOptions.operationIndex += 1;operationOptions.moveNumber = 1;if (operationIndex < autoMoveList.length) {moveFunc();} else {if (typeStore[this.type].hasOwnProperty(this.id)) {this.enemyBackOff();}}}, singleMove.timer);// 保存typeStore[this.type].setId(this.id, { operationOptions });};// 如果 当前在移动 (暂停后继续执行const operationTarget = typeStore[this.type].getId(this.id);if (operationTarget &&operationTarget.hasOwnProperty("operationOptions")) {// 获取操作对象const operationOptions = operationTarget.operationOptions;// 获取上一次正在操作的数据operationIndex = operationOptions.operationIndex;const singleMove = autoMoveList[operationIndex];if (singleMove === undefined) return;// 将上一次执行的时间 进行合并if (singleMove) {singleMove.timer =singleMove.timer - allMoveSpeed * operationOptions.moveNumber;}moveFunc();} else {// 使用方法moveFunc();}} else {// 类型是往上移动if (this.moveType === "top") {this.enemyForward();// 如果类型是往下移动} else if (this.moveType === "buttom") {this.enemyBackOff();}}}// 前进(往上enemyForward() {// 清除重复定时器intervalStore.add(() => {// 判断范围if (this.positionY <= containerInfo.offsetTop) return;this.positionY -= this.enemyFlySpeed// 更新位置信息this.updatePosition();if (!rende2Canvas) {this.enemyDom.style.top =this.enemyDom.offsetTop - this.enemyFlySpeed + "px";}}, this.id + "enemyForwardTimer");}// 后退(往下enemyBackOff() {intervalStore.add(() => {// 限制范围if (this.positionY >= containerInfo.height) {this.enemyMoveStop("enemyBackOffTimer");this.clearEnemy();return;}this.positionY += this.enemyFlySpeed// 更新位置信息this.updatePosition();if (!rende2Canvas) {// 移动元素this.enemyDom.style.top =this.enemyDom.offsetTop + this.enemyFlySpeed + "px";}}, this.id + "enemyBackOffTimer");}// 左平移enemyLeftTranslation() {intervalStore.add(() => {// 限制范围if (this.positionX <= 0) return;this.positionX -= this.enemyFlySpeed// 更新位置信息this.updatePosition();if (!rende2Canvas) {// 移动元素this.enemyDom.style.left = this.positionX + "px";}}, this.id + "enemyLeftTranslationTimer");}// 右平移enemyRightTranslation() {intervalStore.add(() => {// 限制范围if (this.positionX >= containerInfo.height - this.width) return;this.positionX += this.enemyFlySpeed// 更新位置信息this.updatePosition();if (!rende2Canvas) {// 移动元素this.enemyDom.style.left = this.positionX + "px";}}, this.id + "enemyRightTranslationTimer");}// 发射子弹enemyShoot() {this.stopEnemyShoot();this.shootTimer = setInterval(() => {const positionX = this.positionX + containerInfo.offsetLeft;const positionY = this.positionY + (this.height / 2);// 循环发射子弹for (let i = 0; i < this.bulletNumber; i++) {// 宽度进行取平均分布子弹const average = this.width / (this.bulletNumber + 1);// 依次分布子弹位置let bulletPositionX = positionX + average * (i + 1);const bullet = new Bullet(shootDistance,bulletPositionX,positionY,"buttom",this.id,this.hurt,"enemy");bullet.createBullet();bullet.bulletMove();}}, this.shootInterval);}stopEnemyShoot() {if (this.shootTimer) {clearInterval(this.shootTimer);this.shootTimer = null;}}// 更新位置updatePosition() {const saveObject = {positionX: this.positionX,positionY: this.positionY,};typeStore[this.type].setId(this.id, saveObject);}// 清除相对应的移动定时器enemyMoveStop(key) {if (this[key]) {intervalStore.remove(this.id + this[key]);this[key] = null;}}// 停止所有移动定时器enemyStop() {const timerList = ["enemyForwardTimer","enemyBackOffTimer","enemyLeftTranslationTimer","enemyRightTranslationTimer",];for (const index in timerList) {const key = timerList[index];intervalStore.remove(this.id + key);}// 暂停发射this.stopEnemyShoot();}

那么这样子敌机就可以自己移动起来了 设定好移动位置 然后进行移动

当中添加了一堆代码 是为了之前所得暂停功能 所记录的
添加暂停功能后 当前移动的位置需要记录 继续游戏就需要还原已经移动过的路径 避免当前动作没有走完直接进行下一个移动动作

完整项目地址:https://github.com/SDSGK/plane-ES6

ES6飞机大战篇-敌机自动移动发射子弹相关推荐

  1. ES6飞机大战篇-添加子弹追踪功能

    既然是飞机大战 那必定少不了子弹追踪 那么添加子弹追踪功能的实现如下: // 原文链接:https://blog.csdn.net/erweimac/article/details/82256087 ...

  2. Python“飞机大战”上下左右移动空格发射子弹

    下载点此去 最后面有运行视频 一.项目背景 作为一名学习计算机的学生,在以往,我认为学习计算机要么就是无所不能的黑客,要么就是能制作出各种软件程序的大神.我选择pygame板块,制作一款能随意更改游戏 ...

  3. ES6飞机大战篇-封装全局定时器

    最近在编写飞机大战,开发到一半想到 是否可以选择暂停游戏 常见的清理就是用 clearTimerout 或者 clearInterval 那么 如果数量多了 就会出现有些定时器没有清理的问题 为了避免 ...

  4. ES6飞机大战篇-github托管游戏

    研究了一下github 发现居然可以托管网页, 我这个页面也没啥东西 所以就设置了一下 代理了一下 这样就可以直接在线玩了. 如果出现报错 可以等待所有资源加载完毕 毕竟是免费的托管 避免不了的请求慢 ...

  5. Unity游戏开发官方入门教程:飞机大战(六)——创建子弹

    Unity版本:Unity 2018.2.14f1 原视频链接:https://unity3d.com/cn/learn/tutorials/s/space-shooter-tutorial 教程目录 ...

  6. (七)通过pygame来设置飞机大战中 敌机 的速度、位置等

    python飞机大战系列文章(按顺序) (一)通过pygame 将自己的图像添加到游戏中 (二)通过pygame让游戏人物 动起来 (三)通过pygame处理用户的鼠标键盘操作(事件和监听 (四)详解 ...

  7. 从零开始 飞机大战(五)实现子弹定位和动画

    实现目标 首先判断什么时候需要发射炮弹,我们设置在摁下空格的时候发射炮弹,我们下载键盘监控事件中 所以在键盘检测到我们摁下空格的时候,一个炮弹就自动加载到舞台中, //键盘的监控事件 document ...

  8. Python学习日记-第二十四天-飞机大战(敌机出场设计)

    系列文章目录 ·使用定时器添加敌机 ·设计Enemy 类 前言 昨天因为有事,所以没有及时更新 一.使用定时器添加敌机 游戏启动后,每隔一秒会出现一架敌机 每架敌机向屏幕下方飞行,飞行速度各不相同 每 ...

  9. QT飞机大战六(敌机血条的添加以及特殊子弹道具)

    可能有点丑但其实是没有好的资源图片 比如这个血条太生硬了,这个子弹道具怎么真的就和子弹一样?? 不过没事,功能对了就行 首先考虑这个血条怎么搞. 那么首先我们的敌机需要有个属性sum_hp(总血量), ...

最新文章

  1. 神经网络支持大脑是「预测机器」,预测是节能的
  2. Python3.4 django使用mysql
  3. 12.JAVA基本数据类型
  4. 第25课 成绩等级 《小学生C++趣味编程》
  5. 程序员的算法课(19)-常用的图算法:最短路径(Shortest Path)
  6. TokenInsight:反映区块链行业整体表现的TI指数较昨日同期上涨0.41%
  7. C++基础——有关FILE的那些函数
  8. [转载]《博客园精华集》WebService筛选结果(共79篇)
  9. JDK8 到 JDK17版本新增特性
  10. 国内网通、电信代理服务器地址
  11. 计算机开机更新失败怎么办,windows update更新失败怎么办,详细教您windows update更新失败怎么办...
  12. java poi word bookmarks_poi根据word/excel模板(书签)创建导出word/excel文档
  13. Kubernetes1.3:QoS服务质量管理
  14. 小米手机全球已舍弃“MI”品牌,全面改用“xiaomi”全称品牌
  15. s60 微信 服务器繁忙,微信Mars — 移动互联网下的高质量网络连接探索
  16. 中企海外周报 | 中国众多品牌亮相IFA;喜茶新加坡第三家店开业
  17. Smack核心机制浅析
  18. wxappUnpacker 微信小程序反编译 2019 9月使用问题总结
  19. 单选/复选框中点击文字能选择该选项
  20. App inventor 写的垃圾分类小助手(一)

热门文章

  1. 16 - python 仿写飞翔的小鸟,附带源码
  2. 解决win10卡顿情况
  3. 跟涛哥一起学嵌入式 20:后ARM时代,嵌入式工程师的自我修养
  4. 新浪云存储SCS的使用
  5. Mapper系列一:基本使用
  6. 计算机网络 | 谈谈TCP的流量控制与拥塞控制
  7. iOS 中DLog 用法
  8. 先来先服务(FCFS)调度算法(Java实现)
  9. linux系统鼠标变沙漏,一纸沙漏
  10. Android 二维图形处理引擎 Skia