ts练习项目-贪吃蛇(时间类)
项目介绍
学习了typescript语法。教程中的练习项目是贪吃蛇。项目中是利用元素的绝对定位来实现蛇与食物的动作。个人觉得不是很好,于是自己设计了一套实现方法。
项目代码已全部完成,并放到了github。
效果演示
一、设计构思
在贪吃蛇游戏中,蛇需要每隔一段时间移动一格,而且随着等级的升高这个时间间隔需要越来越短(蛇的移动速度越来越快)。我们暂定这个间隔时间为tickTime。tickTime越大则蛇的移动速度越慢,tickTime越小则蛇的移动速度越快。
为了精准的控制这个tickTime,需要抽象出一个时间类。
二、基本功能
这个类中需要有哪些属性和方法呢?
日常生活中的时钟的秒针每走一次会发出“滴答”的声音。我们把这个声音表述为tick。 然后我们让蛇一直“听着”这个tick的声音,听到了就移动一格,听不到就不动。
两次tick之间的时间间隔就是我们需要的tickTime。这个tickTime就等于当前tick的时间减去上次tick的时间。所以这个类中应该有上次tick的时间lastTime。
当然我们需要提供一个开始方法,用来初始化第一个lastTime。
另外每次tick都需要发出“滴答”的声音,让蛇听到(给它提供一个方法),即isTick方法,tick了就返回true,否则就返回false。这样蛇就可以一直“听着”我们的tick声移动了。
class Time {
private _lastTime: number;
constructor() {
this._lastTime = 0;
}
start() {
this._lastTime = Date.now();
}
isTick(tickTime: number): boolean {
const deltaTime = Date.now() - this._lastTime;
if(deltaTime >= tickTime) {
this._lastTime = Date.now();
return true;
}
return false;
}
}
三、功能优化
isTick方法的参数就是我们想控制的每次tick的时间间隔。但是这里有个问题。
因为requestAnimationFrame的时间间隔不固定,所以我们无法让每次tick的时间都精确的等于tickTime。
例如:假设每次requestAnimationFrame的时间间隔是20毫秒。我们想每500毫秒tick一次,当前的时间间隔是490毫秒,那下一次的时间间隔将是490 + 20 = 510毫秒。比预期多了10毫秒。如果不做处理,那累计起来就会差很多。所以每次tick都需要修正此次的lastTime。
isTick(tickTime: number): boolean {
const deltaTime = Date.now() - this._lastTime;
if(deltaTime >= tickTime) {
this._correctLastTime(deltaTime - tickTime);
return true;
}
return false;
}
private _correctLastTime(correctionValue: number) {
this._lastTime = Date.now() - correctionValue;
}
四、暂停功能
暂停功能需要暂停(pause)和继续(play)两个方法。暂停方法只需记住暂停时的时间,而继续方法只需将lastTime向后推迟暂定的时长。即在lastTime加上暂停的时长即可。
pause() {
this._pauseTime = Date.now()
}
play() {
this._lastTime += (Date.now() - this._pauseTime);
}
五、完整代码
class Time {
private _lastTime: number;//上次时间
private _pauseTime: number;//暂停时间
constructor() {
this._lastTime = 0;
this._pauseTime = 0;
}
start() {
this._lastTime = Date.now();
}
pause() {
this._pauseTime = Date.now()
}
play() {
this._lastTime += (Date.now() - this._pauseTime);
}
isTick(tickTime: number): boolean {
const deltaTime = Date.now() - this._lastTime;
if(deltaTime >= tickTime) {
this._correctLastTime(deltaTime - tickTime);
return true;
}
return false;
}
private _correctLastTime(correctionValue: number) {
this._lastTime = Date.now() - correctionValue;
}
}
export default Time;
转载自:https://juejin.cn/post/7368660526396620809