【问题标题】:How can I track steps in Game Maker Studio 2 for random encounters如何在 Game Maker Studio 2 中跟踪随机遭遇的步骤
【发布时间】: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 以检查这一点,并在停止移动时停止它,这样您就不会每帧生成一个随机数。

标签: c# c++ game-development game-maker-studio-2


【解决方案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. 
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-06
      • 2020-07-04
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      相关资源
      最近更新 更多