给DOM开发者的游戏开发指南-06.面向对象

300 阅读2分钟

仓库地址:github.com/haiyoucuv/W…

面向对象

引入概念:面向对象 游戏对象 生命周期

经过上一节的操作,我们已经得到了一只有头有脸的Bird

按这样的方式写代码,写一个小游戏那要多麻烦

所以本节我们要将游戏中通用的东西抽离出来抽象为一个游戏对象,之后所有对象的创建都继承于这个基本的游戏对象

GameObject

  • 1.创建一个js并引入,在这个js中写入如下代码
    下面的代码抽象了一个简单的GameObject
/**
 * 抽象了一个简单的GameObject
 */
class GameObject {

	id;     // 绑定的dom元素的id
	dom;    // 绑定的dom元素

	// 位置
	top = 0;
	left = 0;

	// 缩放
	scaleX = 1;
	scaleY = 1;

	// 旋转
	rotate = 0;

	/**
	 * 获得宽高
	 * @returns {{width: number, height: number}}
	 */
	get size() {
		return {
			width: this.dom.clientWidth,
			height: this.dom.clientHeight,
		}
	}

	constructor(id) {
		this.id = id;
		this.dom = document.getElementById(id); // 在构造函数中绑定dom元素
		this.dom.style.position = "absolute";
	}

	/**
	 * 抽离数据更新部分
	 */
	update() {

	}

	/**
	 * 抽离渲染部分
	 */
	render() {
		const { top, left, scaleX, scaleY, rotate } = this;

		this.dom.style.top = top + "px";
		this.dom.style.left = left + "px";
		this.dom.style.transform = `scale(${scaleX}, ${scaleY}) rotate(${rotate}deg)`;
	}

	/**
	 * 抽离销毁部分
	 */
	destroy() {

	}

}
  • 2.用面向对象的方式创建鸟的class
    class Bird extends GameObject {

	speed;  // bird的速度 每次移动多少距离

	constructor(id, speed) {
		super(id);
		this.speed = speed; // 保存speed

		// 给个默认位置
		this.top = 150;
		this.left = 150;
	}

	update() {
		super.update();

		const { top, left } = this;
		const speed = this.speed;

		// 计算新的top
		if (top !== clickPos.top) {
			const dis = clickPos.top - top; // 计算差值
			const dir = dis > 0 ? 1 : -1;  // 计算在top上移动的方向 1 正向移动 或 -1 反向移动;

			// 如果速度过快,本次移动直接过头了(即差值<速度),就直接移动到指定top
			if (Math.abs(dis) < speed) {
				this.top = clickPos.top;
			} else {
				this.top = top + dir * speed;    // 计算新的top,新的位置 = 之前的位置 + 方向 * 速度
			}
		}

		// 用相同的方式计算left
		if (left !== clickPos.left) {
			const dis = clickPos.left - left;
			const dir = dis > 0 ? 1 : -1;

			if (Math.abs(dis) < speed) {
				this.left = clickPos.left;
			} else {
				this.left = left + dir * speed;
			}
		}
	}
}

  • 3.创建鸟的实例
const bird = new Bird("bird", 15);
  • 4.加入到循环中
/**
 * 计算Bird的位置(数据更新)
 */
function update() {
	bird.update();
}

/**
 * 更新显示对象位置(渲染)
 */
function render() {
	bird.render();
}

再次运行案例,效果一样,但是代码维护更方便,更容易懂,且每个对象有独立的生命周期,更易于组件化,可视化