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

好家伙,

 

飞机大战分包分的差不多了,

但是又出现了问题:

文件目录如下:

 

然而关于变量

 

 

helloworld.vue完整代码

<template>
  <div>
    <div ref="stage"></div>
  </div>
</template>

<script>
//     Award,
//     Bullet,
//     Enemy,
//     Hero,
//     Loading,
//     Main,
//     Sky
//七个大类引进来
import Award from "./js/award"
import Bullet from "./js/bullet"
import Enemy from "./js/enemy"
import Hero from "./js/hero"
import Loading from "./js/loading"
// import Main from "./js/main"
import Sky from "./js/sky"

// import SKYY from "./js/config"

import { START, STARTING, RUNNING, PAUSE, END, LOADINGING } from "./js/config"
import { SKY, LOADING, HERO, BULLET, E1, E2, E3, C1 } from "./js/config"
import { bg, copyright, pause } from "./js/config"
export default {
  mounted() {
    //console测试
    console.log("模块化测试")
    //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");
    //state表示游戏的状态 取值必须是以上的五种状态
    let state = START;

    //score 分数变量 life 变量
    let score = 0;
    let life = 3;

    //初始化奖励类
    // class Loading {
    //   constructor(config) {
    //     this.frame = config.frame;
    //     this.img = this.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) {
    //     if (this.frameIndex < 3)
    //       context.drawImage(this.img[this.frameIndex], this.x, this.y);
    //   }
    // }
    class Main {
      //一下全为全局变量或方法 (全局的!!)
      //初始化一个天空实例
      //主启动方法
      maingame() {
        const sky = new Sky(SKY);
        //初始化一个飞机界面加载实例
        const loading = new Loading(LOADING);
        loading.prototype =this;
        
        //初始化一个英雄实例 英雄是会变的
        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(context);
                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);
        });
      }
    }

    let main_1 = new Main()
    main_1.maingame();
  }
}


</script>

<style>
#stage {
  width: 480px;
  height: 650px;
  margin: 0 auto;
}
</style>
helloworld.vue

 

来看helloworld.vue中的部分代码

import Loading from "./js/loading"
/**
*
*
**/
let state = START;

const loading = new Loading(LOADING);
/**
*
*
**/
loading.judge();

 

loading.js

// import { state } from "./config"
// 初始化一个飞机界面加载类

import { RUNNING } from "./config";
class Loading {
  constructor(config) {

    this.frame = config.frame;
    this.img = this.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) {
    if (this.frameIndex < 3) {
      context.drawImage(this.img[this.frameIndex], this.x, this.y);
    }
  }
}

export default Loading

 

若我把Loading这个类写在Helloworld.vue中,是不会有报错的,

但我把Loading这个类写在外部的.js文件,然后再使用模块化导入,

可见,es6模块化把原先的作用域分隔开了

 

那么这个问题怎么解决呢?

同时我还有另外两个全局变量life(生命值)和score(分数)要处理

//state表示游戏的状态 取值必须是以上的五种状态
    let state = START;

    //score 分数变量 life 变量
    let score = 0;
  let life = 3;

只能委屈一下window了,把他们都变成全局变量

 //state表示游戏的状态 取值必须是以上的五种状态
    window.state = START;

    //score 分数变量 life 变量
    window.score = 0;
  window.life = 3;

 

搞定,不报错了

 

posted @ 2023-04-15 23:21  养肥胖虎  阅读(57)  评论(0编辑  收藏  举报