如何让 FlxAsyncLoop 在 HaxeFlixel 中制作进度条?

how do i make FlxAsyncLoop work for making a progress bar in HaxeFlixel?

所以,我尝试为我的游戏制作一个异步循环(制作一个进度条),但当状态加载时游戏崩溃了...

我尝试更改循环位置,以免它们发生冲突,并且所有代码均来自 FlxAsyncLoop 演示,但包含其他变量和一些其他更改。

代码如下:

import flixel.FlxCamera;
import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.addons.util.FlxAsyncLoop;
import flixel.group.FlxGroup;
import flixel.math.FlxPoint;
import flixel.math.FlxVelocity;
import flixel.text.FlxText;
import flixel.ui.FlxBar;
import flixel.util.FlxColor;

class PlayState extends FlxState
{
public static var player:FlxSprite;

var ground:FlxSprite;
var axe:FlxSprite;
var wood:FlxSprite;
var base:FlxSprite;
var txt:FlxText;

var playerPos:FlxPoint;

var enemy:FlxSprite;

var move = false;

var progressR:FlxGroup;
var progressE:FlxGroup;

var resourceGroup:FlxGroup;
var enemyGroup:FlxGroup;

var maxItems:Int = 100;

var bar1:FlxBar;
var bartxt1:FlxText;
var bar2:FlxBar;
var bartxt2:FlxText;

var loopR:FlxAsyncLoop;
var loopE:FlxAsyncLoop;

public function addR()
{
    var wood = new FlxSprite(FlxG.random.int(100, 2500), FlxG.random.int(100, 1800));
    wood.makeGraphic(40, 100, FlxColor.BROWN);
    add(wood);

    bar1.value = (resourceGroup.members.length / maxItems) * 100;
    bartxt1.text = "Loading resources... " + resourceGroup.members.length + " / " + maxItems;
    bartxt1.screenCenter();
}

public function addE()
{
    var enemy = new FlxSprite(FlxG.random.int(300, 2500), FlxG.random.int(300, 1800));
    enemy.makeGraphic(32, 32, FlxColor.RED);
    add(enemy);

    bar2.value = (enemyGroup.members.length / maxItems) * 100;
    bartxt2.text = "Loading enemys... " + enemyGroup.members.length + " / " + maxItems;
    bartxt2.screenCenter();
}

override public function create()
{
    super.create();

    resourceGroup = new FlxGroup(maxItems);
    enemyGroup = new FlxGroup(maxItems);

    loopR = new FlxAsyncLoop(maxItems, addR);
    loopE = new FlxAsyncLoop(maxItems, addE);

    FlxG.camera.zoom = 0.5;

    playerPos = FlxPoint.get();

    ground = new FlxSprite(0, 0);
    ground.makeGraphic(2500, 1800, FlxColor.GREEN);
    add(ground);

    player = new FlxSprite(100, 100);
    player.loadGraphic(AssetPaths.n1__png);

    axe = new FlxSprite(player.x + 60, player.y);
    axe.loadGraphic(AssetPaths.axeR__png);

    camera = new FlxCamera(0, 0, 2500, 1800);
    camera.bgColor = FlxColor.TRANSPARENT;
    camera.setScrollBoundsRect(0, 0, ground.width, ground.height);
    FlxG.cameras.reset(camera);
    camera.target = player;

    if (FlxG.collide(wood, player))
        FlxObject.separate(wood, player);

    if (FlxG.collide(wood, enemy))
        FlxObject.separate(wood, enemy);

    if (FlxG.collide(enemy, player))
        FlxObject.separate(enemy, player);

    progressR = new FlxGroup();

    bar1 = new FlxBar(0, 0, LEFT_TO_RIGHT, FlxG.width, 50, null, "", 0, 100, true);
    bar1.value = 0;
    bar1.screenCenter();
    progressR.add(bar1);

    bartxt1 = new FlxText(0, 0, FlxG.width, "Loading resources... 0 / " + maxItems);
    bartxt1.setFormat(null, 28, FlxColor.WHITE, CENTER, OUTLINE);
    bartxt1.screenCenter();
    progressR.add(bartxt1);

    progressE = new FlxGroup();

    bar2 = new FlxBar(0, 0, LEFT_TO_RIGHT, FlxG.width, 50, null, "", 0, 100, true);
    bar2.value = 0;
    bar2.screenCenter();
    progressE.add(bar2);

    bartxt2 = new FlxText(0, 0, FlxG.width, "Loading enemys... 0 / " + maxItems);
    bartxt2.setFormat(null, 28, FlxColor.WHITE, CENTER, OUTLINE);
    bartxt2.screenCenter();
    progressE.add(bartxt2);

    resourceGroup.visible = false;
    resourceGroup.active = false;
    enemyGroup.visible = false;
    enemyGroup.active = false;

    add(progressR);
    add(progressE);
    add(resourceGroup);
    add(enemyGroup);
    add(loopR);
}

override public function update(elapsed:Float)
{
    super.update(elapsed);

    if (FlxG.keys.pressed.LEFT && move)
    {
        player.x -= 5;
        axe.loadGraphic(AssetPaths.axeL__png);
    }

    if (FlxG.keys.pressed.RIGHT && move)
    {
        player.x += 5;
        axe.loadGraphic(AssetPaths.axeR__png);
    }

    if (FlxG.keys.pressed.UP && move)
    {
        player.y -= 5;
    }

    if (FlxG.keys.pressed.DOWN && move)
    {
        player.y += 5;
    }

    axe.x = player.x + 60;
    axe.y = player.y;

    playerPos = FlxPoint.get();
    playerPos = player.getMidpoint();

    FlxVelocity.moveTowardsPoint(enemy, playerPos, 70);

    if (!loopR.started)
    {
        loopR.start();
    }
    else
    {
        if (loopR.finished)
        {
            resourceGroup.visible = true;
            progressR.visible = false;
            resourceGroup.active = true;
            progressR.active = false;

            loopR.kill();
            loopR.destroy();

            add(loopE);
            loopE.start();
        }
    }

    if (loopE.finished)
    {
        move = true;
        add(player);
        add(axe);

        enemyGroup.visible = true;
        progressE.visible = false;
        enemyGroup.active = true;
        progressE.active = false;

        loopE.kill();
        loopE.destroy();
    }
}

}

我展示了所有可能导致此问题的功能和其他因素

(我的英语不好,如果我遗漏了什么...)

在不知道具体错误的情况下,我怀疑问题出在你调用

if (FlxG.collide(wood, player))
    FlxObject.separate(wood, player);

if (FlxG.collide(wood, enemy))
    FlxObject.separate(wood, enemy);

if (FlxG.collide(enemy, player))
    FlxObject.separate(enemy, player);

在您的 create 函数中 - woodenemy 是在其他函数中声明的,并不存在于那里。

有几件事我会在这里做不同的事情:

(注意:我没有测试此代码,因此可能仍然存在问题,但这可能会帮助您指明正确的方向...)

class PlayState extends FlxState
{
    public static var player:FlxSprite;

    var ground:FlxSprite;
    var axe:FlxSprite;

    var base:FlxSprite;
    var txt:FlxText;

    var playerPos:FlxPoint;

    var move:Bool = false;

    var progressR:FlxGroup;
    var progressE:FlxGroup;

    var resourceGroup:FlxTypedGroup<FlxSprite>;
    var enemyGroup:FlxTypedGroup<FlxSprite>;

    var maxItems:Int = 100;

    var bar1:FlxBar;
    var bartxt1:FlxText;
    var bar2:FlxBar;
    var bartxt2:FlxText;

    var loopR:FlxAsyncLoop;
    var loopE:FlxAsyncLoop;

    public function addR()
    {
        var wood = new FlxSprite(FlxG.random.int(100, 2500), FlxG.random.int(100, 1800));
        wood.makeGraphic(40, 100, FlxColor.BROWN);
        resourceGroup.add(wood);

        bar1.value = (resourceGroup.members.length / maxItems) * 100;
        bartxt1.text = "Loading resources... " + resourceGroup.members.length + " / " + maxItems;
        bartxt1.screenCenter();

        FlxG.collide(player, resourceGroup) // should not need to call `seperate` - it's automatic when using `collide` vs `overlap`
    }

    public function addE()
    {
        var enemy = new FlxSprite(FlxG.random.int(300, 2500), FlxG.random.int(300, 1800));
        enemy.makeGraphic(32, 32, FlxColor.RED);
        enemyGroup.add(enemy);

        FlxG.collide(enemyGroup, resourceGroup)

        FlxG.collide(player, resourceGroup)

        bar2.value = (enemyGroup.members.length / maxItems) * 100;
        bartxt2.text = "Loading enemys... " + enemyGroup.members.length + " / " + maxItems;
        bartxt2.screenCenter();
    }

    override public function create()
    {
        super.create();

        resourceGroup = new FlxTypedGroup<FlxSprite>(maxItems);
        enemyGroup = new FlxTypedGroup<FlxSprite>(maxItems);

        loopR = new FlxAsyncLoop(maxItems, addR);
        loopE = new FlxAsyncLoop(maxItems, addE);

        FlxG.camera.zoom = 0.5;

        playerPos = FlxPoint.get();

        ground = new FlxSprite(0, 0);
        ground.makeGraphic(2500, 1800, FlxColor.GREEN);
        add(ground);

        player = new FlxSprite(100, 100);
        player.loadGraphic(AssetPaths.n1__png);

        axe = new FlxSprite(player.x + 60, player.y);
        axe.loadGraphic(AssetPaths.axeR__png);

        camera = new FlxCamera(0, 0, 2500, 1800);
        camera.bgColor = FlxColor.TRANSPARENT;
        camera.setScrollBoundsRect(0, 0, ground.width, ground.height);
        FlxG.cameras.reset(camera);
        camera.target = player;

        progressR = new FlxGroup();

        bar1 = new FlxBar(0, 0, LEFT_TO_RIGHT, FlxG.width, 50, null, "", 0, 100, true);
        bar1.value = 0;
        bar1.screenCenter();
        progressR.add(bar1);

        bartxt1 = new FlxText(0, 0, FlxG.width, "Loading resources... 0 / " + maxItems);
        bartxt1.setFormat(null, 28, FlxColor.WHITE, CENTER, OUTLINE);
        bartxt1.screenCenter();
        progressR.add(bartxt1);

        progressE = new FlxGroup();

        bar2 = new FlxBar(0, 0, LEFT_TO_RIGHT, FlxG.width, 50, null, "", 0, 100, true);
        bar2.value = 0;
        bar2.screenCenter();
        progressE.add(bar2);

        bartxt2 = new FlxText(0, 0, FlxG.width, "Loading enemys... 0 / " + maxItems);
        bartxt2.setFormat(null, 28, FlxColor.WHITE, CENTER, OUTLINE);
        bartxt2.screenCenter();
        progressE.add(bartxt2);

        resourceGroup.visible = false;
        resourceGroup.active = false;
        enemyGroup.visible = false;
        enemyGroup.active = false;

        add(progressR);
        add(progressE);
        add(resourceGroup);
        add(enemyGroup);
        add(loopR);
    }

    public function gamePlay(elapsed:Float):Void
    {
        if (FlxG.keys.pressed.LEFT && move)
        {
            player.x -= 5; // why +/- position and not .velocity?

            // THIS is probably not right - you want to use a sprite sheet with animations and call axe.play("left") or something...
            axe.loadGraphic(AssetPaths.axeL__png);
        }

        if (FlxG.keys.pressed.RIGHT && move)
        {
            player.x += 5;
            axe.loadGraphic(AssetPaths.axeR__png);
        }

        if (FlxG.keys.pressed.UP && move)
        {
            player.y -= 5;
        }

        if (FlxG.keys.pressed.DOWN && move)
        {
            player.y += 5;
        }

        axe.x = player.x + 60;
        axe.y = player.y;

        playerPos = FlxPoint.get();
        playerPos = player.getMidpoint();

        for (e in enemyGroup)
        {
            FlxVelocity.moveTowardsPoint(e, playerPos, 70);
        }
    }

    public function loading(elapsed:Float):Void
    {
        if (!loopR.started)
        {
            loopR.start();
        }
        else if (loopR.finished)
        {
            resourceGroup.visible = true;
            progressR.visible = false;
            resourceGroup.active = true;
            progressR.active = false;

            loopR.kill();
            loopR.destroy();

            add(loopE);
            loopE.start();
        }
        else if (loopE.finished)
        {
            move = true;
            add(player);
            add(axe);

            enemyGroup.visible = true;
            progressE.visible = false;
            enemyGroup.active = true;
            progressE.active = false;

            loopE.kill();
            loopE.destroy();
        }
    }

    override public function update(elapsed:Float)
    {
        super.update(elapsed);

        if (!move)
        {
            loading(elapsed);
        }
        else
        {
            gamePlay(elapsed);
        }
    }
}