入坑Screeps

/ 0评 / 0

寒假发现了一款编程版的星际争霸,叫《Screeps》

Screeps 是一款 MMORTS (大型多人在线即时战略游戏)。游戏里有很多世界,每一个玩家都可以在包含所有玩家的单个世界中创建自己的领地。在领地上可以采集资源,建造单位以及占领领土。随着你征服的领土越来越多,势力范围越来越大,你在游戏世界中的影响力也越来越大。不过荣耀与风险并存,你的领地也同时被虎视眈眈的其他玩家盯着。

Screeps 主要是为了有编程背景的人设计的。和其他 RTS 游戏不同的地方在于,只要你为你的 Creep 敲好了代码,就可以让它们自动运行,不用你亲自操作。同时和其他 MMO 游戏不同之处在于你不用花费成片成片的时间去玩,只用没事的时候抽空看一看一切是否进展顺利。

Screeps目前有四个大区,也叫shard,我选择的是最老的shard0。

先走了一遍教程,然后选了一个超狗的出生点。

因为没学过JavaScript,就先用教程里的代码跑了一个晚上。发现效率有点慢,而且每个creep只做一件事,经常出现harvester挡在矿位不挖矿的情况。所以我想把harvester,upgrader,builder几个角色合并成一个worker角色,让creep尽量有事可做。

当creep库存空时,停止work并去挖矿。挖满了进入work状态,work的优先级是先装满spawn和extension(防止creep挂掉后没有能量生产新的creep),然后是build,最后是upgradeController,因为upgrade几乎是无止尽的,所以优先级排最后。

早上起来发现成了这样,所有creep围在出生点不工作。

赶紧debug,看样子应该是找矿没有加过滤,应该把矿余量为零的过滤掉。

main.js(主模块)

var roleWorker = require('role.worker');

//将采矿、建筑、升级、维修等后勤功能整合到一个worker类型的creep上
//优先级 1放满spawn和extension 2build建筑 3升级controller
//寻矿,先找矿,没有矿再找箱子
module.exports.loop = function () {
    //清理内存
    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            //console.log('Clearing non-existing creep memory:', name);
        }
    }

    var workers = _.filter(Game.creeps, (creep) => creep.memory.role == 'worker');
    
    if(workers.length < 20){
        var newName = 'Worker' + Game.time;
        Game.spawns['Spawn1'].spawnCreep([WORK,WORK,CARRY,CARRY,MOVE,MOVE,MOVE,MOVE],
            newName,{memory: {role:'worker'}});
    }
    //spawn中显示提示
	if(Game.spawns['Spawn1'].spawning) { 
        var spawningCreep = Game.creeps[Game.spawns['Spawn1'].spawning.name];
        Game.spawns['Spawn1'].room.visual.text(
            '🛠️' + spawningCreep.memory.role,
            Game.spawns['Spawn1'].pos.x + 1, 
            Game.spawns['Spawn1'].pos.y, 
            {align: 'left', opacity: 0.8});
    }

	//遍历所有creep
    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'worker'){
            roleWorker.run(creep);
        }
    }
}

role.worker.js(worker模块)

var roleWorker = {
    //worker的memory中记录harvesting,transfering,building,upgrading
    run: function(creep){
        if(creep.memory.working && creep.store[RESOURCE_ENERGY] == 0) {
            creep.memory.working = false;
            creep.say('🔄 harvest');
	    }
	    if(!creep.memory.working && creep.store.getFreeCapacity() == 0) {
	        creep.memory.working = true;
	        creep.say('⚡ work');
        }

        if(creep.memory.working){
            var targets = creep.room.find(FIND_STRUCTURES, {//找建筑
                filter: (structure) => {//建筑类型extension或spawn
                    return (structure.structureType == STRUCTURE_EXTENSION || structure.structureType == STRUCTURE_SPAWN) &&
                        structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0;//库存未满
                }
            });
            if(targets.length > 0) {//优先充能spawn
                if(creep.transfer(targets[0], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(targets[0], {visualizePathStyle: {stroke: '#ffffff'}});
                }
            }
            else{
                var targets = creep.room.find(FIND_CONSTRUCTION_SITES);
                if(targets.length > 0) {
                    if(creep.build(targets[0]) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(targets[0], {visualizePathStyle: {stroke: '#ffffff'}});
                    }
                }
                else{
                    if(creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(creep.room.controller, {visualizePathStyle: {stroke: '#ffffff'}});
                    }
                }
            }
        }
        else{
            var targets = creep.room.find(FIND_SOURCES,{
                filter: (source) => {
                    return (source.energy != 0);
                }
            });
            if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
                creep.moveTo(sources[0], {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        }
        
    }
}

module.exports = roleWorker;

应该是没问题了,再观察一天吧~~~

发表评论

电子邮件地址不会被公开。 必填项已用*标注