【Flutter&Flame Game - Pick One】Explore Component | Component Usage Details

Continue to create, accelerate growth! This is the 12th day of my participation in the "Nuggets Daily New Plan · June Update Challenge", click to view the event details


foreword

This is a series of tutorials produced by Zhang Fengjietlie and published in the Nuggets community. Flutter&FlameIf you see this article on other platforms, you can move to the Nuggets to view it according to the link. Because the article may be updated and revised, the version of the Nuggets article shall prevail. List of articles in this series:


1. About the component tree

As shown in the scene below, each displayed object is Component, they form a tree structure. See [11/01] for the code

Various roles are added to the tree through the addmethod , and the tree structure at this time is as follows:

Now there's a problem: because the health bar and volume are added to the Adventurerwidget , Adventurerthe transformation behavior of the will also cause the health bar to change. The following characters are mirrored along the Y axis, and you can see that the health bar and text are also mirrored, which is not what we expected.

How to solve it? The idea is very simple, since Adventurerthere is a need for a separate mirror, it cannot be the parent of the health bar. The relationship between the two can be changed from a parent-child relationship to a brother relationship. Here, the blood bar is encapsulated as LifeComponentbuild , and Adventurerexist together with HeroComponentin :


2. Mirror reversal in character movement

Now I want to achieve the following effect: if the touch point is on the left side of the character, the character will be mirrored to the left, otherwise, the mirror will be reversed to the right. The purpose of this is so that the character can choose the direction of the attack, such as facing the left to attack the monster on the left: see the code [11/02]


Since only the left and right are reversed here HeroComponent, define a value ofisLeft in to record the state. boolIf you need to support other directions, such as up, down, top left, bottom right, etc., you can maintain it through enumeration.

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

When the screen is clicked, the toTargetmethod . At the beginning, the method can be _checkFlipused to maintain the isLeftproperty . If it needs to be flipreversed, the role is reversed:

---->[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;
    }
  }
}
复制代码

Used to only want to reverse the protagonist, so flipin , execute adventurer.flip. This will not affect the display of the blood bar:

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);
}
复制代码

In addition, regarding the reversal, you also need to pay attention to the direction in which the bullet is fired. Because the front bullet is always fired to the right, if facing left, it should move left, like this:

It is also relatively simple to deal with, according to whether isLeftit is really left or right to launch, as followstag1

---->[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. About the maintenance of properties

In order to facilitate the demonstration, the attributes of the characters are relatively scattered, such as speed and attack power. Since it can be encapsulated here HeroComponentto maintain the protagonist class. You can define a HeroAttrclass to maintain the properties of the main character, as follows:

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,
  });
}
复制代码

In this way, HeroComponentwhen , pass HeroAttrin the object to determine the attribute information of the object.

---->[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);
复制代码

In this way, the loss of life value in the monster can be calculated according to HeroAttrthe attribute of :

---->[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);
}
复制代码

When adding bullets, the attack speed and range can be determined according to HeroAttrthe attribute information of :


In this article, we continue to expand the function of roles, knowing that the transformation of parent components will affect child components, so you need to pay attention to the relationship between components when using components. In addition, the character information is HeroAttrencapsulated , so that through HeroComponent, you can add multiple protagonist nodes, and you can fight monsters in double mode.

At this point, you can see TolyGamethat it is very chaotic. In the next chapter, I will introduce how to manage multiple characters and monsters, including the generation of monsters, firing bullets, hitting the protagonist, etc. That's it for this article, see you tomorrow~

\

Guess you like

Origin juejin.im/post/7105584277143699470