因为突然想尝试一下以HTML的Canvas为基础做一下游戏开发!所以就开始做了并且写下这篇文章记录一下
一开始为了能在Canvas上画出图形,直接在HTML里面写了JavaScript,后面为了模块化开发转成单文件。不过最开始还是写JavaScript的,因为要在画布上画东西需要Get到Canvas,所以需要document.getElementByID
,但是由于JavaScript是弱类型,document.getElementByID
不但不会隐式返回一个类型,而且没法标注类型,导致接下来写getContext("2d")
的时候IDE/代码编辑器不会提示。因为以上原因所以毅然换了TypeScript。
TypeScript遇到的第一个问题是直接写let canvas:HTMLCanvasElement = document.getElementByID
会报错,因为getElementByID
依赖不会返回一个HTMLCanvasElement
类型,所以需要手动as HTMLCanvasElement
然后就是tsc编译完js整个ts文件会红,这个写个tsc init
生成一个tsconfig文件就能解决了。
之后的大部分时间在研究分文件写之后为什么会一直在js文件里会出现exports和require的代码,这是js所不支持的写法。解决方法就是把tsconfig中的module改成es6,target也改成es6。有可能会因为tsc的缓存没有清除所以一时不会发生改动。可以清除以下tsc的缓存文件或者使用tsc --module es6
注意import的时候路径后面要加一个.js,就算这是ts文件,如
import { Render } from "./render.js";
不然会在编译到js后找不到文件:
已拦截加载自“http://127.0.0.1:5500/public/ui”的模块,它使用了不允许的 MIME 类型(“text/html”)。
上面说使用了不允许的MIME类型,实际上是因为找不到文件而返回了404ERROR,而404ERROR是HTML不是JavaScript文件所以导致返回了使用了不允许的MINE类型。
<!-- index.html -->
<body>
<script type="module">
import * as main from './public/main.js';
</script>
</script>
<canvas width="800" height="600" id="canvas"></canvas>
</body>
以上是HTML部分的
部分代码,用这种方式去加载main.js文件,因为加入了export和import的代码已经模块化了,再在里面写function并不在全局作用域内。// main.ts
import {UI} from "./ui.js";
import { Render } from "./render.js";
export class Game {
private x: number;
private render: Render;
private ui:UI;
constructor() {
this.x = 10;
this.render = new Render();
this.ui = new UI();
setInterval(() => this.Update(), 1000 / 60);
}
Draw():void {
if (this.render.ctx) {
this.render.ctx.clearRect(0, 0, 800, 600);
this.render.ctx.font = "20px serif";
this.render.ctx.fillText("random text", 10 + this.x, 10)
this.ui.Draw();
}
}
private Update():void {
this.x += 1;
this.Draw();
}
}
new Game()
很显而易见的为了模块化我们给每个文件起了一个class,与此同时在顶上和构造函数里面进行初始化。
构造函数中的最后一行
setInterval(() => this.Update(), 1000 / 60);
是为了设定主循环,60每帧,中间用箭头函数是因为箭头函数不会创建自己的this,而是从外部作用域捕获this的值。因此,可以使用箭头函数来解决这个问题。
// render.ts
export class Render {
public canvas: HTMLCanvasElement;
public ctx: CanvasRenderingContext2D;
constructor() {
this.canvas = document.getElementById("canvas") as HTMLCanvasElement
this.ctx = this.canvas.getContext("2d") as CanvasRenderingContext2D;
}
}
render.ts中单独设置了画布的渲染,要用到draw的部分调用render.ts。
我想这样一个基础的游戏框架就搭建好了。