前端小废物系列(1) |
您所在的位置:网站首页 › 类似screeps › 前端小废物系列(1) |
新手教程(1)游戏 UI 和基本脚本
本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。 基本界面是这样的,第一步是认识教程关的提示按钮,有的时候提示是一大堆英文(如果和我一样不愿意打机翻中文补丁),看的人很烦。这个按钮用来开关提示,对我这样的新手很有用。 界面里我们这块地界称为一个「房间」,实际游戏时每个房间是挨在一起的(看这个地盘四周的出口),但是现在是教学关,暂时没必要放其他房间。(我记得教学关使用的是本地的 CPU,实际游戏使用的是游戏服务器的 CPU,这个游戏可以自己搞个服务器和同事朋友同学师长等等人自己玩,后面会讲到)关于实际游戏的房间排布参照这里:Game world 屏幕中间的是第一个「Spawn」,大概理解成虫族产卵的单位,这是种群的中心。 屏幕下面的位置是写代码用的,因为是在浏览器里玩(我截图是在客户端里玩,客户端实际上也是套壳浏览器,还有其他各式各样的客户端,后面会讲到),所以就借用了浏览器调试代码的这种形式。 脚本,控制台,内存这三个有快捷键,分别是「Alt + 1」「Alt + 2」「Alt + 3」 在浏览器里面玩的话,可以同时打开浏览器的调试窗口 Ctrl + Shift + J,然后觉得游戏内的这个太简陋还挡视线用 Alt + Enter 关掉。 「Spawn」 这个单位生产各种 「Creep」 使用的方法叫做 spawnCreep,每一个 「Creep」 都有一个具体的名字和一些特定的身体部件表达不同的行为(面向对象它来了)。 定位生产单位用 Game.spawns['Spawn1']。 这一步我们需要创建一个名为 Harvester1 的 「Creep」 对象,身体部件数组有 [WORK, CARRY, MOVE],命令敲到控制台上。 文档: Your colony Creeps Game object StructureSpawn.spawnCreep Game.spawns['Spawn1'].spawnCreep( [WORK, CARRY, MOVE], 'Harvester1' );生产中。。。 在右边查看这个 Harvester1 的详细信息(查看其他单位类似,需要鼠标先选中一个单位) 英文提示中的“View”动作,这里卖个关子,后面教程我记得是有专门区分的。 现在就可以让 Harvester1 动起来了(它有三个行为:工作,搬运,移动),地图里黄色一闪一闪的方块是能量资源,这些宝贵的资源可以被拥有一个或以上 WORK 部件的 「Creep」 收割,然后被拥有 CARRY 部件的 「Creep」 送回 「Spawn」。 为了让 「Creep」 一直工作,在控制台一遍一遍的催是不够的,脚本这时候就来了。(有些游戏里只要鼠标点点让采矿车锁定矿区就能自动工作下去,这里是用命令来驱动各种 「Creep」 的行为,没命令它们就原地待命) 在这里可以编写永久运行的脚本,游戏都是循环运行的(服务器不停你就可以继续榨取价值,这里的”tick“是双关语,前面界面也有,右边一个大大的暂停下面写出了 tick 和现实时间之间的转换比例,之后在真实游戏里详细说明),它允许玩家编写不断工作的程序来控制各种 「Creep」 的行为,即使玩家离线(仅在真实的游戏中,而不是教学关)程序也在服务器上不断运行。 要将脚本提交到游戏中运行,可以点这个对勾,也可以按 Ctrl+Enter。 每个教学关的代码都是在它自己的分支中创建的。玩家可以查看来自这些分支的代码,以便在自己的脚本中进一步使用。 文档: Scripting basics代码终于来了。。。把这段直接照搬过去就行,Harvester1 就能一直工作了 收割方法 harvest 需要 「Creep」挨着矿点(黄色资源点),寻址或者定位 「Creep」 用 Game.creeps['Harvester1']。然后在 Room.find 方法里加入常量参数 FIND_SOURCES,就是在房间里找资源点。 文档: Game.creeps RoomObject.room Room.find Creep.moveTo Creep.harvest采矿中。。。 把矿送回去又需要脚本了,对应前面所说的”没命令就原地待命“。「Creep」 把能量送回 「Spawn」 的方法是 Creep.transfer,方法同样在 「Creep」 和目标 「Spawn」紧挨时才能完成,所以采完矿的 「Creep」 还得走回去。 如果在代码里加入了 .store.getFreeCapacity() > 0 这句检查 「Creep」 的剩余容量,那自动采矿车就完成了。 文档: Creep.transfer Creep.store module.exports.loop = function () { var creep = Game.creeps['Harvester1']; if(creep.store.getFreeCapacity() > 0) { var sources = creep.room.find(FIND_SOURCES); if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) { creep.moveTo(sources[0]); } } else { if( creep.transfer(Game.spawns['Spawn1'], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE ) { creep.moveTo(Game.spawns['Spawn1']); } } }这是目前全部的脚本,只需要加上前面缺少的判断和送回相关语句。 正在往回送货。。。 这个 「Creep」 之后就以收割者(这么翻译总让人觉得它还有攻击性,但其实攻击相关的行为和方法在后面的教学关里,提前说一下不要搞混)的身份工作到狗带。几乎所有 「Creep」 的生命周期都是 1500 game ticks,之后它们就老掉了(教学关里狗带被关掉了)。 现在来再创建一个“工作细胞”(这么说是不是很形象)来帮助之前的 Harvester1。创建需要 200 点能量,所以需要等 Harvester1 收集足够的能量给 「Spawn」,这期间调用 spawnCreep 方法会返回错误代码 ERR_NOT_ENOUGH_ENERGY(-6) 直到有足够能量生产”工作细胞“。 如果命令只执行一次就用控制台。(脚本里的代码会反复执行,一直生产一个名字的对象后面也会报错) 生产第二个 「Creep」,称作 Harvester2,和 Harvester1 只有名字上的差别。 文档: StructureSpawn.spawnCreep Game.spawns['Spawn1'].spawnCreep( [WORK, CARRY, MOVE], 'Harvester2' );现在有两个收割者了,第二个因为没收到命令所以原地待命,现在要把它写到脚本里去,让它一直工作。 因为只有两个收割者,直接复制一份代码改对象名就行。更好的方法是用 for 循环包括所有的 「Creep」(目前所有的 「Creep」 都是收割者,所以不要紧,以后肯定还会有更多的收割者,还会有其他类型的 「Creep」,之后肯定还要改这里的代码) 文档: for...in loops代码就是要不断优化,这些“工蚁”(形象的比喻)的行为可以分离到一个 module 里。 创建一个名叫 role.harvester 的模块,在 module.exports 对象里定义一个函数 run 来包含 「Creep」 的行为 文档: Organizing scripts using modules var roleHarvester = { /** @param {Creep} creep **/ run: function(creep) { if(creep.store.getFreeCapacity() > 0) { var sources = creep.room.find(FIND_SOURCES); if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) { creep.moveTo(sources[0]); } } else { if(creep.transfer(Game.spawns['Spawn1'], RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { creep.moveTo(Game.spawns['Spawn1']); } } } }; module.exports = roleHarvester;创建模块在左下角直接输入名字 有了模块以后代码结构就更清晰了,把主模块里多余的代码删掉,只留循环,用 require('role.harvester') 调用刚才新创建的模块。 这样教学关第一关就完成了,最后提醒的是让我们给代码分层,善用 role 和 module 来掌控各种各样的 「Creep」,下一关我们会开发新的 「Creep」 角色。 参考网页screeps.com/ github.com/screeps/scr… docs.screeps.com/ screeps-cn.github.io/ screeps.com/a/#!/sim/tu… |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |