寫這篇文章的目的是為了在之后會講到的關(guān)于Screeps中如何跨Tick執(zhí)行代碼這篇文章做鋪墊呀闻。
本章內(nèi)容也許對目前的你沒有任何啟發(fā)或者是作用,但他的的確確成為了跨Tick執(zhí)行技術(shù)的基礎(chǔ)周偎。
狀態(tài)模擬技術(shù)
概念:修改Screeps中的對象屬性,讓其擁有未來某個(gè)或任意Tick的狀態(tài)或?qū)傩浴?/p>
作用:這使得你可以在本tick中撑帖,計(jì)算下一個(gè)tick或任意一個(gè)可能的情況下蓉坎,某個(gè)對象的操作。
這么說可能比較模糊胡嘿,下面我們來到Screeps來實(shí)際運(yùn)用一下狀態(tài)模擬技術(shù)蛉艾。
準(zhǔn)備工作
- 1只Creep
- 1個(gè)SOURCE對象
請看下面的代碼
(抽象代碼,請勿直接使用)
RoomSources = Game.rooms[roomName].find(FIND_SOURCES)[0];
console.log(RoomSources.pos)
這段代碼我們獲得了一個(gè)Sources對象衷敌,并輸出了它的pos位置對象勿侯。結(jié)果如下
{
roomName:"E10N10",
x:16
y:25
}
這表明這個(gè)Sources對象位于房間E10N10中16,25坐標(biāo)上。
接下來我們來看看Creep
console.log(mycreep.pos)
得到輸出
{
roomName:"E10N10",
x:22
y:16
}
同理也可見這個(gè)creep所在的房間和位置逢享,很明顯這個(gè)Creep和目標(biāo)的Sources還有一段距離罐监。
那么現(xiàn)在我們讓這個(gè)Creep在當(dāng)前位置嘗試Harvest,下面是我們得到的結(jié)果
//某個(gè)tick內(nèi)
RoomSources = Game.rooms[roomName].find(FIND_SOURCES)[0];
console.log(mycreep.harvest(RoomSources));
//返回
"ERR_NOT_IN_RANGE"
可見此時(shí)我們的creep嘗試采集操作是提示距離不夠的瞒爬。
重點(diǎn)來了弓柱,如果我們嘗試修改這個(gè)Creep的pos對象讓他就在目標(biāo)sources旁邊呢?
//某個(gè)tick內(nèi)
RoomSources = Game.rooms[roomName].find(FIND_SOURCES)[0];
mycreep.pos.x = 16;
mycreep.pos.y = 26;
console.log(mycreep.harvest(RoomSources));
//返回
"OK"
可見侧但,即使我們的creep在當(dāng)前tick并不在16,26這個(gè)坐標(biāo)上矢空,但通過我們強(qiáng)行修改,這個(gè)坐標(biāo)不僅生效了禀横,還成功讓harvest方法返回了OK屁药。
這就是狀態(tài)模擬技術(shù)。
我們可以模擬這個(gè)creep的任意屬性柏锄,再配合api酿箭,我們可以在第一個(gè)tick內(nèi)計(jì)算第二個(gè)复亏,第三個(gè)tick甚至第N個(gè)tick時(shí),這個(gè)creep的預(yù)期行為缭嫡。
了解了狀態(tài)模擬概念缔御,也許你應(yīng)該零星明白了跨tick技術(shù)的基本原理。我們可以通過原型拓展(詳見hoho大佬的文章妇蛀,這里不詳訴)以及鏈表技術(shù)耕突,緩存creep未來幾個(gè)tick的操作和行為。即使某個(gè)tick不對creep進(jìn)行任何api操作评架,這個(gè)creep也能執(zhí)行預(yù)期的任務(wù)眷茁。并且跨tick技術(shù)同時(shí)實(shí)現(xiàn)了運(yùn)算和調(diào)用的完全分離,同時(shí)也讓cpu的運(yùn)行更加高效纵诞。
同理上祈,狀態(tài)模擬技術(shù)可以用于任何Screeps對象,下一篇文章我會細(xì)談如何給這些對象進(jìn)行高效的原型拓展以便于跨tick技術(shù)的應(yīng)用挣磨。
不久將會更新關(guān)于跨tick技術(shù)的詳解文章雇逞,敬請關(guān)注荤懂。