【Flutter&Flame 게임 - 하나 선택】구성 요소 탐색 | 구성 요소 사용 세부 정보

계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 6월 업데이트 챌린지" 참여 12일차입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다.


머리말

이것은 Zhang Fengjietlie 가 제작하고 Nuggets 커뮤니티에 게시된 Flutter&Flame일련 . 다른 플랫폼에서 이 글을 보게 된다면 너겟으로 이동하여 링크에 따라 볼 수 있습니다. 기사가 업데이트 및 수정될 수 있으므로 Nuggets 기사 버전이 우선합니다. 이 시리즈의 기사 목록:


1. 컴포넌트 트리 정보

아래 장면과 같이 표시되는 각 객체는 Component이며 트리 구조를 형성합니다. 코드는 [11/01] 참조

add메소드 를 통해 트리에 다양한 역할이 추가되며, 이때 트리 구조는 다음과 같다.

이제 문제가 있습니다. Adventurer위젯 Adventurer의 변환 동작으로 인해 체력 표시줄도 변경됩니다. 다음 캐릭터는 Y축을 따라 미러링되며, 체력 바와 텍스트도 미러링된 것을 볼 수 있습니다. 이는 우리가 예상했던 것과 다릅니다.

그것을 해결하는 방법? 아이디어는 매우 Adventurer간단 합니다. 별도의 미러가 필요하기 때문에 헬스바의 부모가 될 수 없습니다. 이 둘의 관계는 부모-자식 관계에서 형제 관계로 변경될 수 있으며, 여기서 블러드 바는 LifeComponentbuild 과 같이Adventurer 존재합니다 .HeroComponent


2. 캐릭터 이동의 미러 반전

이제 다음 효과를 얻고 싶습니다. 터치 포인트가 캐릭터의 왼쪽에 있으면 캐릭터가 왼쪽으로 미러링되고, 그렇지 않으면 미러가 오른쪽으로 반전됩니다. 이렇게 하는 목적은 왼쪽에 있는 몬스터를 공격하기 위해 왼쪽을 바라보는 것과 같이 캐릭터가 공격 방향을 선택할 수 있도록 하기 위함입니다. 코드 [11/02] 참조


여기서는 왼쪽과 오른쪽만 HeroComponent반전 되므로 상태를 기록하기 위해 in 값을isLeft 정의합니다. bool위, 아래, 왼쪽 위, 오른쪽 아래 등 다른 방향을 지원해야 하는 경우 열거를 통해 유지할 수 있습니다.

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

화면을 클릭하면 toTarget메소드 되며 처음 _checkFlip에는 메소드를 통해 isLeft속성 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다음 장 에서는 몬스터 생성, 총알 발사, 주인공 타격 등 여러 캐릭터와 몬스터를 관리하는 방법을 소개하겠습니다. 이번 글은 여기까지, 내일 만나요~

\

추천

출처juejin.im/post/7105584277143699470