Screeps Arena 游戏基础教程

本文介绍了ScreepsArena这款基于编程的RTS游戏中的基础教程,包括循环和导入、移动、攻击、爬虫身体部分、存储和转移、地形利用、生产爬虫、收割能源、建设和最终测试等内容,帮助玩家掌握编程策略以在对战中获胜。
摘要由CSDN通过智能技术生成

Screeps Arena 是一款纯编程的RTS游戏(即时战略游戏),通过编写JavaScript(或其他语言)代码,控制从采集资源、生产单位、建造、移动、攻击的各种操作和应变逻辑,来让自己的战略运行起来,和其他的代码成果进行对局。

一. 游戏内教程汉化

1. 循环和导入(Loop and Import)

欢迎来到本教程,您将学习如何通过编码发挥爬虫竞技场 (Screeps Arena) 的基础知识。

你通过在本地文件夹中编写代码来玩游戏,游戏内的编辑器不好使,所有我们推荐你们使用一些其他的代码编辑器,例如vscode来编写代码。

循环:
当您点击PLAY按钮时,这些文件被提交给服务器。如果你的代码中没有语法错误,游戏就会开始,你就可以观看了。你不能在游戏期间更改提交的代码,比赛几秒钟后就结束了之后,你可以用任何速度观看。

每一个回合(或者我们称之为tick),游戏都会运行你的主函数 loop() 。该函数在main.mjs中被定义:

export function loop() {
    // Your code goes here
}

这个函数中的所有内容都将被反复执行,直到游戏结束。

导入:
有一个特殊的函数getTicks(),您可以调用它来确定当前的刻度是多少。为了调用它,你必须将它从/game/utils模块导入到你的代码中:

import { getTicks } from 'game/utils';

export function loop() {
    console.log('Current tick:', getTicks());
}

有许多方法和对象可以通过这种方式导入。请参阅文档了解。console.log()输出游戏控制台面板中的任何值,以便您可以调试和检查正在运行的代码。你不需要导入这个函数,它是全局可用的。

让我们开始:
在教程的第一步,我们没有任何游戏对象,游戏地图完全是空的。完成这一步所要的就是打印循环的一些信息。只需要将上面的代码复制粘贴到你的main.mjs文件中,然后点击PLAY按钮运行。
在这里插入图片描述


2. 简单移动(Simple move)

每个爬虫可以做各种动作,显然它可以移动。

creep.moveTo(target);

这个命令会让你的爬虫向目标移动一步,如果你在每次循环迭代中都执行它,你的爬虫就会一直移动到目的地。(在调用此函数时立即执行,但只能在循环函数完成之后执行移动。)

从代码访问你的爬虫,有一个特殊的函数叫做getObjectsByPrototype( ) ,它返回一个数组,其中包含所有具有给定原型或类的游戏对象。你可以像下面这样选择游戏中的所有爬虫:

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep);
}

在本教程的步骤中,我们有一个Flag对象,它也有它的原型名称。

最终目标:使用移动的方法让你的爬虫踩到旗子上。

代码如下:

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep);
    let flags = getObjectsByPrototype(Flag);
    creeps[0].moveTo(flags[0]);
}

3. 首次攻击(First Attack)

Screeps Arena是一款多人PvP游戏,你的爬虫将会和对手的爬虫战斗,所有让我们来简单学习一下攻击。

如何判断哪些是你的爬虫,使用JavaScript标准的Array.filter( )Array.find( )方法返回给定条件的元素数组。

filter( ) 方法返回提供的数组中满足所提供测试函数的所有元素的数组。

const words = ['spray', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter((word) => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]

find() 方法返回提供的数组中满足所提供测试函数的第一个元素。

const array1 = [5, 12, 8, 130, 44];
const found = array1.find((element) => element > 10);
console.log(found);
// Expected output: 12

在下面的例子中,可以基于爬虫的属性来查找指定爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';

export function loop() {
    var myCreep = getObjectsByPrototype(Creep).find(creep => creep.my);
    var enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);
}

现在我们可以使用attack方法攻击敌人了,当它无法到达目标时,他将返回ERR_NOT_IN_RANGE的错误信息,所以你需要先使用moveTo:

if(myCreep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
    myCreep.moveTo(enemyCreep);
}

本节最终目标:消灭敌方爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';
import { ERR_NOT_IN_RANGE } from 'game/constants';

export function loop() {
    let myCreep = getObjectsByPrototype(Creep).find(creep => creep.my);
    let enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);
    if(myCreep.attack(enemyCreep) === ERR_NOT_IN_RANGE) {
        myCreep.moveTo(enemyCreep);
    }
}

4. 爬虫的身体部分(Creeps Bodies)

你可以调用爬虫的很多函数来完成某个行为,但是并非所有函数都可以用于某个爬虫。爬虫可以调用什么函数取决于它的身体部位。你可以检查他的body属性,它是一个数组,其中数组每个元素代表某种类型的一个主体部分:

MOVE:使爬虫移动。
ATTACK:允许它近战范围内攻击。
RANGED_ATTACK:允许它攻击3格外的目标。
HEAL:允许治疗它自己或另一个爬虫。
WORK:可以建造建筑或收集能量。
CARRY:增加爬虫携带资源的能力,身上可以携带更多的资源。
TOUGH :没有任何效果。

if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
    // this creep has ATTACK body parts
}

Array..some() 是 JavaScript 中用于数组的方法之一,它用于检查数组中是否至少有一个元素满足指定的条件。这个方法会遍历数组的每个元素,直到找到一个满足条件的元素,然后立即返回 true。如果没有找到满足条件的元素,则返回 false。

array.some(callback(element[, index[, array]])[, thisArg])

参数说明:
callback:一个用于测试每个元素的函数,它可以接受三个参数:
element:当前正在处理的数组元素。
index(可选):当前正在处理的元素的索引。
array(可选):调用 some 方法的数组本身。
thisArg(可选):可选参数,函数执行时的 this 值。

每一个身体部位都会使爬虫的攻击力提高100点。当爬虫受到伤害时,他的身体部分也会受到伤害,如果该部分的数值被攻击清零了,它就会失去该部分的功能。同一类型的身体部位越多,这种类型的效果就越强。

现在,本教程步骤中我们有3种不同的部位:ATTACKRANGED_ATTACKHEAL的爬虫。只有协调好对手的行动,你才能打败他们。

为了做到这一点,使用与前一个教程步骤相同的方法,但根据他们的身体部位区分他们的行动,伤害发送者应该使用不同的方法(attackrangedAttack)进行伤害,治疗者应该使用heal方法治疗你受伤的爬虫。

import { getObjectsByPrototype } from 'game/utils';
import { Creep } from 'game/prototypes';
import { ERR_NOT_IN_RANGE, ATTACK, RANGED_ATTACK, HEAL } from 'game/constants';

export function loop() {
    let myCreeps = getObjectsByPrototype(Creep).filter(creep => creep.my);
    let enemyCreep = getObjectsByPrototype(Creep).find(creep => !creep.my);

    for(let creep of myCreeps) {
        if(creep.body.some(bodyPart => bodyPart.type == ATTACK)) {
            if(creep.attack(enemyCreep) == ERR_NOT_IN_RANGE) {
                creep.moveTo(enemyCreep);
            }
        }
        if(creep.body.some(bodyPart => bodyPart.type == RANGED_ATTACK)) {
            if(creep.rangedAttack(enemyCreep) == ERR_NOT_IN_RANGE) {
                creep.moveTo(enemyCreep);
            }
        }
        if(creep.body.some(bodyPart => bodyPart.type == HEAL)) {
            let myDamagedCreeps = myCreeps.filter(i => i.hits < i.hitsMax);
            if(myDamagedCreeps.length > 0) {
                if(creep.heal(myDamagedCreeps[0]) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(myDamagedCreeps[0]);
                }
            }
        }
    }
}

for...of 语句执行一个循环,该循环处理来自可迭代对象的值序列。可迭代对象包括内置对象的实例,例如 Array、String、TypedArray、Map、Set、NodeList(以及其他 DOM 集合),还包括 arguments 对象、由生成器函数生成的生成器,以及用户定义的可迭代对象。

const array1 = ['a', 'b', 'c'];
for (const element of array1) {
  console.log(element);
}
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"

5. 存储和转移 (Store and Transfer)

在不同的区域,有不同的可用资源。但是有一种常见的资源类型RESOURCE_ENERGY,用来建造建筑、生产爬虫等各种活动。

塔(Tower)可以造成50点的范围攻击伤害,尽管它的效率随着距离的增加而降低。在本教程的步骤中,我们将使用能量来给塔充能,以击败敌人。

tower.attack(target);

塔每次射击消耗10个能量单位。为了给它装载能量,你需要使用一个将能量传递给它的爬虫。

creep.transfer(tower, RESOURCE_ENERGY);

从哪里获得能量?附近有一个容器(Container),它的store有一些能量。你可以移动爬虫去容器中回收能量:

creep.withdraw(container, RESOURCE_ENERGY);

当塔内有足够能量时,他会攻击并摧毁目标。

如果你使用我们的示例代码,请注意我们现在是如何以不同的方式导入内容的(不是特别定义他们,而是从/game模块导入整个命名空间。)用哪种导入的写法,根据自己的喜好来:

import { prototypes, utils, constants } from 'game';

export function loop() {
    const tower = utils.getObjectsByPrototype(prototypes.StructureTower)[0];
    if(tower.store[constants.RESOURCE_ENERGY] < 10) {
        let myCreep = utils.getObjectsByPrototype(prototypes.Creep).find(creep => creep.my);
        if(myCreep.store[constants.RESOURCE_ENERGY] == 0) {
            let container = utils.getObjectsByPrototype(prototypes.StructureContainer)[0];
            myCreep.withdraw(container, constants.RESOURCE_ENERGY);
        } else {
            myCreep.transfer(tower, constants.RESOURCE_ENERGY);
        }
    } else {
        let target = utils.getObjectsByPrototype(prototypes.Creep).find(creep => !creep.my);
        tower.attack(target);
    }
}

6. 地形 (Terrain)

游戏中5种地形:平原地形、天然的坚不可摧的墙壁、建造的可摧毁的墙、沼泽、道路。

沼泽和道路上移动与爬虫的重量相关联。每个爬虫的身体部位,除了MOVE,都会增加了他的重量。(一个空的CARRY 身体部位不会增加重量),但如果爬虫体内有资源将会增加它的身体重量。每个MOVE部位能增加爬虫的移动速度。如果的MOVE身体部位和所有其他身体部位数量数量相同时,你的爬虫将勉勉强强能够在平原地形上移动。否则小于的话,他会感到疲劳,动弹不得。

但是有相同身体部位的爬虫在沼泽上,它会变得更加疲劳,并且每5 tick才只能移动一次。为了让你每次tick都能移动,你的爬虫将需要5倍以上的MOVE部件。

相反,道路减少了你的爬虫对MOVE部件的需求。例如,如果你的爬虫有10个负重的身体部位,你在道路上移动就只需要5个MOVE身体部件就可以使这个爬虫每次循环移动。

注意,当你需要使用寻路算法从一个数组中找到一个位置最近的对象时,可以使用findClosestByPath 函数。

let flags = getObjectsByPrototype(Flag);
let closestFlag = creep.findClosestByPath(flags);

在本节教程中,你只需要将每个爬虫移动到相应的旗子。代码如下:

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag } from 'game/prototypes';

export function loop() {
    let creeps = getObjectsByPrototype(Creep).filter(i => i.my);
    let flags = getObjectsByPrototype(Flag);
    for(let creep of creeps) {
        let flag = creep.findClosestByPath(flags);
        creep.moveTo(flag);
    }
}

7. 生产爬虫(Spawn Creeps)

当你在一个有Spawn结构的竞技场上玩游戏时,你可以使用spawnCreep方法创建新的爬虫。您需要将新爬虫的主体定义为包含其主体部分的数组。

你想要刷出的爬虫越大,它消耗的能量就越多,具体数值如下:
MOVE:50能量
ATTACK:80能量
RANGED_ATTACK:150能量
HEAL:250能量
WORK:100能量
CARRY:50能量
TOUGH :10能量

spawnCreep方法返回一个稍后使用的Creep实例。

let creep = mySpawn.spawnCreep([MOVE, ATTACK]).object;

你甚至可以在loop函数之外定义变量,以便在tick之间使用它们:

let creep;
export function loop() {
    if(!creep) {
        creep = mySpawn.spawnCreep([MOVE, ATTACK]).object;
    }
}

请注意,您可以为这个爬虫对象分配任何属性,如果你想要给爬虫分布一些目标、角色或其他数据,这可能会很有用:

creep.target = flag;

在本教程步骤中,你有一个刷出和两个旗帜。目标:刷出两个爬虫,并将每个爬虫移动到每个旗帜上。

import { getObjectsByPrototype } from 'game/utils';
import { Creep, Flag, StructureSpawn } from 'game/prototypes';
import { MOVE } from 'game/constants';

let creep1, creep2;

export function loop() {
    let mySpawn = getObjectsByPrototype(StructureSpawn)[0];
    let flags = getObjectsByPrototype(Flag);

    if(!creep1) {
        creep1 = mySpawn.spawnCreep([MOVE]).object;
    } else {
        creep1.moveTo(flags[0]);

        if(!creep2) {
            creep2 = mySpawn.spawnCreep([MOVE]).object;
        } else {
            creep2.moveTo(flags[1]);
        }
    }
}

8. 收割能源(Harvest Energy)

能源可以以不同的形式获得,它可以存储在容器中,但是也可以从Sources中收获,如果你的爬虫有work身体部位,那么它就可以使用使用harvest方法从Source提取一些能量。

creep.harvest(source);

你的爬虫必须靠近能源才能执行这个动作。它拥有的WORK身体部位越多,每一次从能源处提取的能量就越多。能源中的能量储备是无限的,一段时间后会重新刷满。

本节目标:收割和转移1000能量到Spawn

import { prototypes, utils, constants } from 'game';

export function loop() {
    let creep = utils.getObjectsByPrototype(prototypes.Creep).find(i => i.my);
    let source = utils.getObjectsByPrototype(prototypes.Source)[0];
    let spawn = utils.getObjectsByPrototype(prototypes.StructureSpawn).find(i => i.my);

    if(creep.store.getFreeCapacity(constants.RESOURCE_ENERGY)) {
        if(creep.harvest(source) == constants.ERR_NOT_IN_RANGE) {
            creep.moveTo(source);
        }
    } else {
        if(creep.transfer(spawn, constants.RESOURCE_ENERGY) == constants.ERR_NOT_IN_RANGE) {
            creep.moveTo(spawn);
        }
    }
}

9. 建设(Construction)

你不仅可以生成爬虫,还可以建造建筑!只需要一点能量和一个工人就能完成工作。

首先,使用createConstructionSite函数放置一个名为StructureTower在某个地方,你需要指定建筑的坐标和原型。

import { createConstructionSite } from 'game/utils';
import { StructureTower } from 'game/prototypes';

export function loop() {
    let constructionSite = createConstructionSite({x: 50, y: 55}, StructureTower).object;
}

你带着能量的爬虫必须接近建筑工地建造他:

creep.build(constructionSite);

每一次成功的建造行动都会消耗你的爬虫体内存储的一些能量,所以你的爬虫需要在你的能量供应处和建筑工地之间来回穿梭。

本节目标:建造一座塔。

import { prototypes, utils } from 'game';
import { RESOURCE_ENERGY, ERR_NOT_IN_RANGE } from 'game/constants';

export function loop() {
    const creep = utils.getObjectsByPrototype(prototypes.Creep).find(i => i.my);
    if(!creep.store[RESOURCE_ENERGY]) {
        const container = utils.findClosestByPath(creep, utils.getObjectsByPrototype(prototypes.StructureContainer));
        if(creep.withdraw(container, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
            creep.moveTo(container);
        }
    } else {
        const constructionSite = utils.getObjectsByPrototype(prototypes.ConstructionSite).find(i => i.my);
        if(!constructionSite) {
            utils.createConstructionSite(50,55, prototypes.StructureTower);
        } else {
            if(creep.build(constructionSite) == ERR_NOT_IN_RANGE) {
                creep.moveTo(constructionSite);
            }
        }
    }
}

10. 最终测试(Final Test)

现在你已经学会了如何控制爬虫,攻击敌人,使用能量,产生新的爬虫,建造新的结构。看起来你已经为最终测试做好了准备!

在本教程步骤中,你有一个Spawn和一个Source。有一群敌人的爬虫,你要产生更多的爬虫,并击败他们。这次我们甚至不会给你提供示例代码! 当你完成本教程,你可以移动到真正的PvP竞技场,并开始在多人模式下与其他人战斗。祝你好运!

目标:在攻击中幸存下来,杀死所有的敌人并完成教程。

本节就不写示例代码了,每个人都有每个人自己的写法,正好做一个小小测试。

游戏官方已经提供了比较全面的vscode代码补全功能了,你只要用vscode打开对应模式的文件夹(注意不要单打开文件,而应该打开文件夹!)就能使用代码补全来编写代码了。然后在第一行加上// @ts-nocheck就不会报错啦。

以后打算再汉化一下官方的API文档,敬请期待,希望能帮到大家!

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
arena14是一个流行的仿真软件,用于模拟和分析复杂的系统和流程。它可以帮助用户在模拟环境中制定最佳决策,并有效地优化系统的性能。 arena14的仿真教程包含了使用此软件进行模拟的详细步骤和实例。在教程中,用户会学习如何创建模型、定义实体、资源和操作,并设置模拟参数。教程还介绍了一些常用的技术和策略,如统计分析、优化和变动实验。 在开始教程之前,使用者需要对arena14的基本概念和界面有一定的了解。教程可以从基础入门开始,逐渐引导用户从简单的模型到复杂的系统。它通常包括丰富的图文说明和示例文件,帮助用户更好地理解和应用仿真技术。 通过跟随arena14仿真教程,用户可以掌握以下技能: 1. 建模能力:了解如何建立一个合理的模型,包括实体、资源、操作和排队等要素。 2. 仿真参数设置:掌握如何设置仿真的时间、实验和统计参数,以便准确地模拟系统的行为。 3. 数据分析:学会如何使用arena14的统计工具来分析和解释仿真结果,以发现系统中的瓶颈和改进点。 4. 优化策略:了解如何使用arena14的优化功能来改进系统性能和效率。 5. 场景分析:学会使用变动实验来评估不同场景或决策对系统行为的影响。 总而言之,arena14仿真教程对于想要学习和应用仿真技术的用户来说是非常有价值的资源。它不仅可以帮助用户掌握arena14软件的使用,还能提升用户的建模和分析能力,为解决实际问题提供深入的见解和方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

害恶细君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值