如何在 Game Maker Studio 2 中跟踪随机遭遇的步骤

Posted

技术标签:

【中文标题】如何在 Game Maker Studio 2 中跟踪随机遭遇的步骤【英文标题】:How can I track steps in Game Maker Studio 2 for random encounters 【发布时间】:2020-11-06 09:51:26 【问题描述】:

我正在尝试制作一个简单的角色扮演游戏,只是为了好玩。

我目前正在研究一个随机遭遇系统,我在 Reddit 上发现了这段代码,它可能很有用;

///This code should be under your object's create event:

encounterSteps = irandom_range(10,20);

///This code should run when you take a step:

if (steps > encounterSteps) 
    steps = 0;
    encounterSteps = irandom_range(10,20);
    room_goto(rm_battle);

但是有一个问题,这个系统使用了一个名为“steps”的变量,而我目前没有那个变量。现在我显然知道我需要计算我的步数才能使它起作用,但我不完全确定我将如何计算我的步数。我目前正在使用以下代码进行移动:

var moveSpeed = 4;

if (_kLeft && !place_meeting(x - moveSpeed, y, oWall))

    x -= moveSpeed;
    sprite_index = sPlayerLeft;
    image_speed = 0.5;

    
if (_kRight && !place_meeting(x + moveSpeed, y, oWall))

    x += moveSpeed;
    sprite_index = sPlayerRight;
    image_speed = 0.5;

    
if (_kUp && !place_meeting(x, y - moveSpeed, oWall))

    y -= moveSpeed;
    sprite_index = sPlayerUp;
    image_speed = 0.5;

    
if (_kDown && !place_meeting(x, y + moveSpeed, oWall))

    y += moveSpeed;
    sprite_index = sPlayerDown;
    image_speed = 0.5;


我假设我必须将此代码更改为更像是一次一步的系统。

现在我的问题是:如何使用我当前的移动系统制作一个跟踪步数或生成随机遭遇的系统?

【问题讨论】:

另一个选项:每次角色移动,你将一个变量“encounterRisk”加1,得到一个介于0和另一个变量“encounterRate”之间的随机数,如果结果低于“encounterRisk” ,重置“遭遇风险”并开始战斗。由您为“encounterRate”定义一个合适的值。您还可以在开始移动时每隔 100 毫秒或其他时间启动一个带有回调函数的 Timer 以检查这一点,并在停止移动时停止它,这样您就不会每帧生成一个随机数。 【参考方案1】:

我无法谈论您正在使用的代码,因为我没有您项目的上下文。但我相信这是我自己会使用的版本。

首先,您需要两个变量/属性来定义当前的遭遇风险和遭遇率。

当你移动时第一个会增加,你会定期在一个随机数和encounterRate之间进行检查。当随机数低于encounterRisk时,开始战斗并重置encounterRisk

您可以每帧都执行此检查,但这可能会占用大量资源。一个更好的主意是在 Timer 的回调函数中进行。

我不知道你的班级看起来如何,所以你必须适应这个。

private int MoveSpeed  get;  = 4;
private Timer EncounterTimer  get; set; 
private int EncounterRisk  get; set;  = 0;
private int EncounterRate  get; set;  = 1000; // to fine tune depending on your needs

public YourClassConstructor()

    EncounterTimer = new System.Timers.Timer(100);
    EncounterTimer.Elapsed += CheckForEncounter;


public void CheckForEncounter()

    EncounterRisk++;
    
    // Maybe use something bigger than 0 here, otherwise there is a non-zero chance that you get 2 encounters in a row without being able to move
    var random = new Random().Next(0, EncounterRate);

    if (random < EncounterRisk)
    
        EncounterRisk = 0;
        // start a battle
    


// your moving function
public void Move()

    var moving = false;
    var xMoveAmount = 0;
    var yMoveAmount = 0;

    if (_kLeft && !place_meeting(x - MoveSpeed, y, oWall))
    
        xMoveAmount -= MoveSpeed;
        sprite_index = sPlayerLeft;
        moving = true;
    

    if (_kRight && !place_meeting(x + MoveSpeed, y, oWall))
    
        xMoveAmount += MoveSpeed;
        sprite_index = sPlayerRight;
        moving = true;
    

    if (_kUp && !place_meeting(x, y - MoveSpeed, oWall))
    
        yMoveAmount -= MoveSpeed;
        sprite_index = sPlayerUp;
        moving = true;
    

    if (_kDown && !place_meeting(x, y + MoveSpeed, oWall))
    
        yMoveAmount += MoveSpeed;
        sprite_index = sPlayerDown;
        moving = true;
    

    if (moving)
    
        image_speed = 0.5; // not sure if you need to set that every frame, maybe you can put it under the following "if"
        x += xMoveAmount;
        y += yMoveAmount;

        if (!EncounterTimer.Enabled)
        
            EncounterTimer.Enabled = true;
        
    
    else
    
       EncounterTimer.Enabled = false;
    

【讨论】:

【参考方案2】:

Kilazu 有一个很好的方法来解决这个问题,但是如果我们从游戏制作工作室的角度来看,那么我们已经有了一些只读变量,可以让我们看到它在哪个帧上,例如 image_index。所以至少,它很容易实现(即使它可能不是最优化的方法)。这是我个人尝试使用的一种方法:

//--Create--//
encounterRate = irandom(30,40);
encounterSteps = 0;
// We condition lock steps so it's only counting it the one time for that cycle
stepOneCounted = false, stepTwoCounted = false, stepCountComplete = false;
//--Step--//
if (sprite_index == spr_player_walking) 
    // sprite_get_number returns real numb and not whole numb (i.e. 1-2-3 not 0-1-2-3) | also, function needs at least 1 sub img to work
    totalWalkAniFrames = sprite_get_number(sprite_index)-1;
    // Left step
    if (image_index == 3 && !stepOneCounted)  
        encounterSteps += 1; 
        stepOneCounted = true;
    
    // Right step
    if (image_index == 5 && !stepTwoCounted)  
        encounterSteps += 1; 
        stepTwoCounted = true;
    
    // Cycle completed
    if (image_index == totalWalkAniFrames && !stepCountComplete) 
        stepOneCounted = false;
        stepTwoCounted = false;
        stepCountComplete = true;
    
    // Do this again
    if (image_index == 0)  
        stepCountComplete = false; 
    

// ...
if (encounterRate >= encounterSteps)
    // do the thing and reset the encounter rate & encounter steps
    // also, be sure to default the 'step counted' variables in case it stops in a weird spot like step one's true, but step twos false still. 

最后,请务必根据移动动画的帧调整图像索引号。一个非常简单和通用的解决方案,但希望这会有所帮助。

【讨论】:

以上是关于如何在 Game Maker Studio 2 中跟踪随机遭遇的步骤的主要内容,如果未能解决你的问题,请参考以下文章

使用 Game Maker Studio 2 中的快速排序算法对列表进行排序

我在 Game Maker Studio 2 上的程序没有显示货币符号(如 £、$ 等)

XBOX 在插槽 0 中检测到一个游戏手柄,但在 Game Maker Studio 2 中未检测到输入

Game Maker Studio的位置问题

Game Maker Studio:前 10 名高分(认真)

Game Maker Studio 网络客户端到服务器通信