Пример #1
0
    // 一時変数を共有するクロージャとイテレータを同時に使うのを避けるため関数化する
    // TODO:
    // 周囲八マスからランダムに選ぶ
    // その位置に敵がいないことを確認
    private Func <IEnumerator>[] Summon(Loc src, MainSystem sys)
    {
        var xs = new List <Loc>(src.Neighbors());

        Utils.Shuffle(xs);

        var rand = new System.Random();
        int n    = rand.Next(2, 3);
        var locs = new List <Loc>();

        for (int i = 0; i < xs.Count; i++)
        {
            // TODO: 敵の配置だけでなく、敵が配置可能かも調べる
            if (!sys.ExistsEnemy(xs[i]))
            {
                locs.Add(xs[i]);

                if (locs.Count == n)
                {
                    break;
                }
            }
        }

        List <Func <IEnumerator> > fns = new List <Func <IEnumerator> >();

        for (int i = 0; i < locs.Count; i++)
        {
            int p = i;
            fns.Add(() => sys.Summon(locs[p]));
        }
        return(fns.ToArray());
    }
Пример #2
0
    protected override IEnumerator Run(MainSystem sys)
    {
        // 攻撃キャラを、ターゲットとの中間に移動させる(攻撃アニメーションの代替)
        var src = Actor.Position;
        var dst = src;

        dst.x          = (src.x + _target.Position.x) / 2;
        dst.y          = (src.y + _target.Position.y) / 2;
        Actor.Position = dst;

        // ターゲットの方を向く
        Actor.ChangeDir(Actor.Loc.Toward(_target.Loc));
        _target.HideDirection();

        // ターゲットは攻撃者の方を向く。ただし以下の場合は振り向かない
        // - 目の前に敵が存在する
        // - 攻撃者が透明状態
        if (!sys.ExistsEnemy(_target.Front()) && !Actor.IsInvisible())
        {
            _target.ChangeDir(_target.Loc.Toward(Actor.Loc));
        }

        _target.RemoveStatus(StatusType.Sleep);
        var dmg = 16 + new System.Random().Next(30);

        yield return(Anim.Par(sys,
                              () => _target.DamageAnim(dmg),
                              () => EffectAnim.PopupWhiteDigits(_target, dmg)));

        _target.DamageHp(dmg);
        Actor.Position = src;
    }