【Flutter&Flameゲーム-1つ選ぶ】コンポーネントの探索|コンポーネントの使用法の詳細

創造を続け、成長を加速させましょう!「ナゲッツデイリーニュープラン・6月アップデートチャレンジ」に参加して12日目です。クリックしてイベント詳細をご覧ください。


序文

これは、 Zhang Fengjietlieによって作成され、Nuggetsコミュニティで公開されているFlutter&Flame一連です。他のプラットフォームでこの記事を表示している場合は、ナゲッツに移動してリンクに従って表示できます。記事は更新および改訂される可能性があるため、ナゲッツの記事のバージョンが優先されます。このシリーズの記事のリスト:


1.コンポーネントツリーについて

下のシーンに示すように、表示される各オブジェクトはComponentであり、ツリー構造を形成します。コードについては[11/01]を参照してください

addメソッドを介してツリーにさまざまな役割が追加されます。このときのツリー構造は次のとおりです。

ここで問題があります。ヘルスバーとボリュームがAdventurerウィジェット、Adventurerの変換動作によってヘルスバーも変更されます。次の文字はY軸に沿ってミラーリングされており、ヘルスバーとテキストもミラーリングされていることがわかります。これは予想とは異なります。

それを解決する方法は?Adventurer別のミラーが必要なため、ヘルスバーの親になることはできません。2つの関係は、親子関係から兄弟関係に変更できます。ここでは、ブラッドバーはLifeComponentビルド、:と一緒に存在しAdventurerます。HeroComponent


2.キャラクターの動きのミラー反転

ここで、次の効果を実現したいと思います。タッチポイントがキャラクターの左側にある場合、キャラクターは左側にミラーリングされます。そうでない場合、ミラーは右側に反転します。これの目的は、キャラクターが攻撃の方向を選択できるようにすることです。たとえば、左側を向いて左側のモンスターを攻撃するなどです。コード[11/02]を参照してください。


ここHeroComponentで、inの値をisLeft定義して状態を記録します。bool上、下、左上、右下など、他の方向をサポートする必要がある場合は、列挙によって維持できます。

---->[HeroComponent]----
bool isLeft = true;
late Adventurer adventurer;
late LifeComponent lifeComponent;
复制代码

画面がクリックされると、toTargetメソッドされます。最初は_checkFlipisLeftプロパティ逆にする必要がある場合は、flip逆の役割を使用します。

---->[HeroComponent#toTarget]----
void toTarget(Vector2 target) {
  _checkFlip(target);
  // 略同...
}

void _checkFlip(Vector2 target){
  if (target.x < position.x) {
    if (isLeft) {
      flip();
      isLeft = false;
    }
  }
  if (target.x > position.x) {
    if (!isLeft) {
      flip();
      isLeft = true;
    }
  }
}
复制代码

主人公を逆転させたいだけだったのでflip、で、を実行しadventurer.flipます。これは、血液バーの表示には影響しません。

void flip({
  bool x = false,
  bool y = true,
}) {
  adventurer.flip(x: x, y: y);
}
复制代码

---->[HeroComponent#flip]----
void flip({
  bool x = false,
  bool y = true,
}) {
  adventurer.flip(x: x, y: y);
}
复制代码

また、反転に関しては、弾丸が発射される方向にも注意を払う必要があります。前弾は常に右に発射されるため、左を向いている場合は、次のように左に移動する必要があります。

また、次のように、起動するのisLeftが本当にtag1

---->[Bullet]----
@override
void update(double dt) {
  super.update(dt);
  Vector2 ds = Vector2(isLeft ? 1 : -1, 0) * speed * dt; // tag1
  _length += ds.length;
  position.add(ds);
  if (_length > maxRange) {
    _length = 0;
    removeFromParent();
  }
}
复制代码

3.物件の維持について

デモンストレーションを容易にするために、速度や攻撃力など、キャラクターの属性は比較的分散しています。ここにカプセル化して主人公クラスHeroComponentをです。次のように、メインキャラクターのプロパティを維持するHeroAttrクラス。

class HeroAttr {
  double life; // 生命值
  double speed; // 速度
  double attackSpeed; // 攻击速度
  double attackRange; // 射程
  double attack; // 攻击力
  double crit; // 暴击率
  double critDamage;  // 暴击伤害

  HeroAttr({
    required this.life,
    required this.speed,
    required this.attackSpeed,
    required this.attackRange,
    required this.attack,
    required this.crit,
    required this.critDamage,
  });
}
复制代码

このようにHeroComponent、構築するときは、オブジェクトを渡しHeroAttrて、オブジェクトの属性情報を決定します。

---->[TolyGame#onLoad]----
final HeroAttr heroAttr = HeroAttr(
  life: 3000,
  speed: 100,
  attackSpeed: 200,
  attackRange: 200,
  attack: 50,
  crit: 0.75,
  critDamage: 1.5,
);
player = HeroComponent(attr: heroAttr);
add(player);
复制代码

このようにして、モンスターのライフの損失値は、次HeroAttrの。

---->[Liveable]----
void loss(HeroAttr attr) {
  double point = attr.attack;
  double crit = attr.crit;
  double critDamage = attr.critDamage;
  bool isCrit = _random.nextDouble() < crit;
  if (isCrit) {
    point = point * critDamage;
  }
  _damageText.addDamage(-point.toInt(), isCrit: isCrit);
}
复制代码

弾丸を追加する場合、攻撃速度と範囲は次HeroAttrの。


この記事では、親コンポーネントの変換が子コンポーネントに影響を与えることを認識して、ロールの機能を拡張し続けます。したがって、コンポーネントを使用するときは、コンポーネント間の関係に注意する必要があります。さらに、キャラクター情報はを介してHeroAttrカプセル化ため、を介してHeroComponent複数の主人公ノードを追加したり、ダブルモードでモンスターと戦ったりすることができます。

この時点で非常に混沌とTolyGameしていること。次の章では、モンスターの生成、弾丸の発射、主人公の攻撃など、複数のキャラクターやモンスターを管理する方法を紹介します。この記事は以上です、また明日〜

  • @张风捷特烈 2022.06.05 未允禁转
  • 我的 公众号: 编程之王
  • 我的 掘金主页張鳳凰寺
  • 我的 B站主页張鳳凰寺
  • 我的 github 主页toly1994328

\

おすすめ

転載: juejin.im/post/7105584277143699470