创建一个游戏地图类

这个类属于整个游戏的一部分, 所以需要继承GameObject类(自己写的基类), 并在构造函数中使用super()函数。

这个Map类有一些属性,rows(地图的行数), cols(地图的列数), L(每个单元格的单位长度),parent(父元素),ctx(canvas的context)。

export default class Map extends GameObject {
  constructor(parent, ctx) {
    super();
    this.rows = 15;
    this.cols = 15;
    this.parent = parent;
    this.ctx = ctx;

    this.L = 0;
  }
}

L取宽度和高度中的最小值,update_size()函数就可以使地图随着浏览器的宽高动态变化

update_size() {
    this.L = Math.min(
      this.parent.clientWidth / this.cols,
      this.parent.clientHeight / this.rows
    );
    this.ctx.canvas.width = this.L * this.cols;
    this.ctx.canvas.height = this.L * this.rows;
  }

render函数中,一般用于渲染图像,这里希望奇数和偶数格的颜色不同。

render() {
    let odd_color = "#a5de4e",
      even_color = "#b5e85d";
    for (let i = 0; i < this.rows; i++) {
      for (let j = 0; j < this.cols; j++) {
        if ((i + j) % 2 === 0) {
          this.ctx.fillStyle = even_color;
        } else {
          this.ctx.fillStyle = odd_color;
        }
        this.ctx.fillRect(j * this.L, i * this.L, this.L, this.L);
      }
    }
  }

Map完整代码

import GameObject from "./GameObject.js";

export default class Map extends GameObject {
  constructor(parent, ctx) {
    super();
    this.rows = 15;
    this.cols = 15;
    this.parent = parent;
    this.ctx = ctx;

    this.L = 0;
  }

  start() {}

  update_size() {
    this.L = Math.min(
      this.parent.clientWidth / this.cols,
      this.parent.clientHeight / this.rows
    );
    this.ctx.canvas.width = this.L * this.cols;
    this.ctx.canvas.height = this.L * this.rows;
  }

  update() {
    this.update_size();
    this.render();
  }

  render() {
    let odd_color = "#a5de4e",
      even_color = "#b5e85d";
    for (let i = 0; i < this.rows; i++) {
      for (let j = 0; j < this.cols; j++) {
        if ((i + j) % 2 === 0) {
          this.ctx.fillStyle = even_color;
        } else {
          this.ctx.fillStyle = odd_color;
        }
        this.ctx.fillRect(j * this.L, i * this.L, this.L, this.L);
      }
    }
  }

  on_destory() {}
}

App.vue中的代码

<template>
  <div class="App">
    <div class="playground" ref="playground">
      <canvas ref="game_canvas"></canvas>
    </div>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import Map from "./script/Map";
const playground = ref(null);
const game_canvas = ref(null);

onMounted(() => {
  let context = game_canvas.value.getContext("2d");
  let map = new Map(playground.value, context);
});
</script>
<style scoped lang="scss">
.App {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;

  .playground {
    width: 50vw;
    height: 70vh;
    background-color: #888;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style>