likes
comments
collection
share

ts练习项目-贪吃蛇(时间类)

作者站长头像
站长
· 阅读数 46

项目介绍

学习了typescript语法。教程中的练习项目是贪吃蛇。项目中是利用元素的绝对定位来实现蛇与食物的动作。个人觉得不是很好,于是自己设计了一套实现方法。

项目代码已全部完成,并放到了github

效果演示

ts练习项目-贪吃蛇(时间类)

一、设计构思


在贪吃蛇游戏中,蛇需要每隔一段时间移动一格,而且随着等级的升高这个时间间隔需要越来越短(蛇的移动速度越来越快)。我们暂定这个间隔时间为tickTimetickTime越大则蛇的移动速度越慢,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
评论
请登录