閑聊js14: 實(shí)現(xiàn)一個關(guān)鍵的,最小化的属愤,非場景圖類型的精靈系統(tǒng)(下)

閑聊js: 實(shí)現(xiàn)一個關(guān)鍵的女器,最小化的,非場景圖類型的精靈系統(tǒng)(上)一文中完成了精靈系統(tǒng)住诸,但是還缺乏空間變換和動畫runLoop的支持驾胆,本篇完成上述需求!

本篇目的:

  • 為BLFSprite添加空間變換相關(guān)的成員變量
  • 為BLFSprite添加beginRender/endRender方法贱呐,有利于變換狀態(tài)的操作
  • 增加兩個精靈類:BLFGridSprite和BLFDemoSprite
  • 在引擎中封裝requestAnimationFrame操作丧诺,讓引擎動起來(遇到了一點(diǎn)問題,花了點(diǎn)時間奄薇,還是this指針導(dǎo)致的問題驳阎!)
  • 動起來,轉(zhuǎn)起來

精靈系統(tǒng)最大的作用是封裝動畫和渲染操作馁蒂,讓我們添加空間變換方面的內(nèi)容吧!

  1. BLFSprite中暫時先添加平移,旋轉(zhuǎn)操作:
class BLFSprite {
    constructor(name = '') {
        this.typeName = "BASE";
        this.name = name;
        this.color = "rgba(255,0,0,1)";

        //當(dāng)前精靈的位置坐標(biāo)
        this.x = 0;
        this.y = 0;

        //當(dāng)前精靈的旋轉(zhuǎn)角度
        this.rotation = 0;

        //用于移動原點(diǎn)偏移量
        //例如rectSprite的原點(diǎn)在左上角劫瞳,而我們想旋轉(zhuǎn)的時候以rect中心點(diǎn)進(jìn)行废睦,此時需要通過使用centerX,centerY進(jìn)行操作
        this.centerX = 0;
        this.centerY = 0;
    }
}
  1. BLFSprite中添加beginRender/endRender用于控制空間變換操作和狀態(tài):
 beginRender(render) {
        //將渲染器的變換矩陣歸一化
        render.resetTransform();
        
        //設(shè)置精靈的原點(diǎn)
        if (this.x != 0 || this.y != 0)
            render.translate(this.x, this.y);

        //旋轉(zhuǎn)中心點(diǎn)的設(shè)置
        if (this.rotation != 0)
            if (this.centerX != 0 || this.centerY != 0) {
                render.rotateAt(this.centerX, this.centerY, this.rotation);
            } else
                render.rotate(this.rotation);
    }

    endRender(render) {
         //將渲染器的變換矩陣恢復(fù)原始狀態(tài)
        render.resetTransform();
    }
  1. 原來代碼BLFSprite default情況下渲染網(wǎng)格背景,現(xiàn)在使用BLFGridSprite精靈做背景,因此基類render成純虛方法,子類如要顯示,必須override!
 //虛函數(shù),如有需要揣非,子類需override
    //default實(shí)現(xiàn):原本繪制背景搞监,現(xiàn)改成純虛方法
    render(render) {

    }

實(shí)現(xiàn)BLFGridSprite和BLFDemoSprite:

  1. BLFGridSprite:
class BLFGridSprite extends BLFSprite {
    constructor(name = '') {
        //super([基類構(gòu)造函數(shù)參數(shù)列表])
        super(name);

        //this調(diào)用父類的成員屬性必須在super()調(diào)用后才okV媪酢!5媸汀茫船!
        this.typeName = "GridBackgroud";
    }

    render(render) {
        render.drawGrid('black', 'white', 20, 20);
    }
}
  1. BLFDemoSprite:
class BLFDemoSprite extends BLFSprite {
    constructor(center = false, name = '') {
        //super([基類構(gòu)造函數(shù)參數(shù)列表])
        super(name);

        //this調(diào)用父類的成員屬性必須在super()調(diào)用后才okH谎邸>洹G巧贰空骚!
        this.typeName = "DemoSprite";

        this.x = 250;
        this.y = 250;

        this.rotateSpeed = 1;

        this.rect = new Rect(0, 0, 100, 50);
        this.lines = [new Point(100, 25), new Point(150, 25)];
        
        //如果center = true
        //旋轉(zhuǎn)中心為rect的中心點(diǎn),否則為rect的左上角
        if (center) {
            this.centerX = this.rect.width * 0.5;
            this.centerY = this.rect.height * 0.5;
        }
    }

    //渲染rect
    //粗線渲染朝向標(biāo)記線
   //細(xì)線渲染坐標(biāo)軸
    render(render) {
        render.drawRect(this.rect, 'blue');
        render.pushStates();
        render.setLineState(3.0);
        render.drawLine(this.lines[0].x, this.lines[0].y, this.lines[1].x, this.lines[1].y, 'green');
        render.popStates();
        render.drawCoords(this.rect);
    }

    //運(yùn)動都在update中進(jìn)行數(shù)值更新
    update(msec) {
        this.rotation += this.rotateSpeed;
    }
}

在引擎中封裝requestAnimationFrame档礁,動起來了!

//修改上一節(jié)中BLFRender中定義的run函數(shù)辫愉,讓它真正的runLoop起來:
class BLFEngine2D {

     run(msec) {
        this.updateAll(msec);
        this.renderAll();

        //調(diào)用requestAnimationFrame
        requestAnimationFrame((msec) => { this.run(msec) });

        /*非箭頭函數(shù)解決方案
        let self = this;
        requestAnimationFrame(function(msec) {
            self.run(msec);
        });
        */
    }
}

這個函數(shù)花了我一點(diǎn)時間,歸根結(jié)底還是經(jīng)典的this指向問題屏镊!

  • DOM中而芥,使用requestAnimationFrame進(jìn)行動畫操作
  • requestAnimationFrame的參數(shù)是類型為:
    function animate(time)為原型的回調(diào)函數(shù)
  • 但是我這里為了封裝到BLFRender2D中稀余,剛開始死活不行,原因是this指向出了問題荐捻。
  • 解決this指向:箭頭函數(shù)/let self = this;這兩種方式脱篙!

測試代碼:

<script>
        let canvas = document.getElementById("myCanvas");
        let context = canvas.getContext('2d');
        let engine = new BLFEngine2D(context);
        let spr = new BLFRectSprite(new Rect(0, 0, 50, 25), "spRect");

        let spr2 = new BLFDemoSprite();
        spr2.x = 400; //調(diào)整位置
        spr2.rotateSpeed = -1; //逆時針

        engine.sprMgr.addSprite(new BLFGridSprite("background"));
        engine.sprMgr.addSprite(spr);
        engine.sprMgr.addSprite(spr2); //逆時針左上角旋轉(zhuǎn)
        engine.sprMgr.addSprite(new BLFDemoSprite(true)); //順時針中心旋轉(zhuǎn)

        //引擎進(jìn)入loop
        engine.run();
    </script>
demoSprite.png

htmlpreview.github.io/?https://github.com/jackyblf/BLF_JS_Demos/blob/master/spritesystemtest.html

到目前為止沼溜,一個可演示用的渲染系統(tǒng)和簡單的非場景圖類型的動畫精靈系統(tǒng)已經(jīng)完成平挑,下一篇進(jìn)入:動畫、數(shù)學(xué)與碰檢篇章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末系草,一起剝皮案震驚了整個濱河市通熄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌找都,老刑警劉巖唇辨,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異能耻,居然都是意外死亡赏枚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門晓猛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饿幅,“玉大人,你說我怎么就攤上這事戒职±醵鳎” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵洪燥,是天一觀的道長磕秤。 經(jīng)常有香客問我乳乌,道長,這世上最難降的妖魔是什么市咆? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任汉操,我火速辦了婚禮,結(jié)果婚禮上蒙兰,老公的妹妹穿的比我還像新娘磷瘤。我一直安慰自己,他們只是感情好癞己,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布膀斋。 她就那樣靜靜地躺著,像睡著了一般痹雅。 火紅的嫁衣襯著肌膚如雪仰担。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天绩社,我揣著相機(jī)與錄音摔蓝,去河邊找鬼。 笑死愉耙,一個胖子當(dāng)著我的面吹牛贮尉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播朴沿,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼猜谚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赌渣?” 一聲冷哼從身側(cè)響起魏铅,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坚芜,沒想到半個月后览芳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸿竖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年沧竟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缚忧。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡悟泵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闪水,到底是詐尸還是另有隱情魁袜,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布敦第,位于F島的核電站峰弹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芜果。R本人自食惡果不足惜鞠呈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望右钾。 院中可真熱鬧蚁吝,春花似錦、人聲如沸舀射。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脆烟。三九已至山林,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邢羔,已是汗流浹背驼抹。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拜鹤,地道東北人框冀。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像敏簿,于是被迫代替她去往敵國和親明也。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容