面向对象
引入概念:面向对象
游戏对象
生命周期
经过上一节的操作,我们已经得到了一只有头有脸的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();
}
再次运行案例,效果一样,但是代码维护更方便,更容易懂,且每个对象有独立的生命周期,更易于组件化,可视化