Continuez à créer, accélérez la croissance ! C'est le 12ème jour de ma participation au "Nuggets Daily New Plan · June Update Challenge", cliquez pour voir les détails de l'événement
avant-propos
Il s'agit d'une série de tutoriels produits par Zhang Fengjietlie et publiés dans la communauté Nuggets. Flutter&Flame
Si vous voyez cet article sur d'autres plateformes, vous pouvez vous déplacer vers les Nuggets pour le consulter selon le lien. Étant donné que l'article peut être mis à jour et révisé, la version de l'article Nuggets prévaudra. Liste des articles de cette série :
- 【Flutter & Flame Game-One】Ouvrez la porte à un nouveau monde
- 【Flutter & Flame Game - Ⅱ】Joystick et mouvement des personnages
- 【Flutter & Flame Game - 3】Événements du clavier et opération gestuelle
- 【Jeu Flutter & Flame - 4】Méthode de chargement d'image Sprite
- 【Flutter&Flame Game - Wu】Participation à la toile | Barre de santé du personnage
- 【Flutter&Flame Game - Lu】Critical Dash | Utilisation de composants de texte
- 【Flutter & Flame Game - 7】 Les gens suivent le doigt | Animation tactile et mouvement
- 【Flutter&Flame Game - 摌】Rechargement terminé | Lancement de l'arme du personnage
- 【Flutter & Flame Game - Nine】Explore Component | Qu'est-ce qu'un composant
- [Flutter&Flame Game - Pickup] Explorer le composant | Rappel du cycle de vie du composant
- 【Flutter & Flame Game - Choisissez un】 Explorer le composant | Détails d'utilisation du composant (
本文
)
1. À propos de l'arborescence des composants
Comme le montre la scène ci-dessous, chaque objet affiché est Component
, ils forment une arborescence. Voir [11/01] pour le code
Divers rôles sont ajoutés à l'arborescence via la add
méthode , et la structure de l'arborescence à ce stade est la suivante :
Il y a maintenant un problème : étant donné que la barre de santé et le volume sont ajoutés au Adventurer
widget , Adventurer
le comportement de transformation du entraînera également la modification de la barre de santé. Les caractères suivants sont mis en miroir le long de l'axe Y, et vous pouvez voir que la barre de santé et le texte sont également mis en miroir, ce qui n'est pas ce à quoi nous nous attendions.
Comment le résoudre? L' idée est très simple, Adventurer
puisqu'il faut un miroir séparé, il ne peut pas être le parent de la barre de santé. La relation entre les deux peut être changée d'une relation parent-enfant à une relation fraternelle. Ici, la barre de sang est encapsulée comme LifeComponent
build , et Adventurer
existe avec HeroComponent
dans :
2. Inversion du miroir dans le mouvement des personnages
Maintenant, je veux obtenir l'effet suivant : si le point de contact est sur le côté gauche du personnage, le personnage sera inversé vers la gauche, sinon, le miroir sera inversé vers la droite. Le but de ceci est que le personnage puisse choisir la direction de l'attaque, comme faire face à gauche pour attaquer le monstre de gauche : voir le code [11/02]
Étant donné que seules la gauche et la droite sont inversées ici HeroComponent
, définissez une valeur deisLeft
in pour enregistrer l'état. bool
Si vous avez besoin de prendre en charge d'autres directions, telles que le haut, le bas, le haut à gauche, le bas à droite, etc., vous pouvez le conserver par énumération.
---->[HeroComponent]----
bool isLeft = true;
late Adventurer adventurer;
late LifeComponent lifeComponent;
复制代码
Lorsque l'on clique sur l'écran, la toTarget
méthode . Au début, _checkFlip
la isLeft
propriété S'il faut l'inverser, c'est par le flip
rôle inverse :
---->[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;
}
}
}
复制代码
Utilisé pour ne vouloir inverser que le protagoniste, donc flip
dans , exécutez adventurer.flip
. Cela n'affectera pas l'affichage de la barre de sang :
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);
}
复制代码
De plus, concernant l'inversion, vous devez également faire attention à la direction dans laquelle la balle est tirée. Parce que la balle avant est toujours tirée vers la droite, si elle est tournée vers la gauche, elle devrait se déplacer vers la gauche, comme ceci :
C'est aussi relativement simple à gérer, selon isLeft
qu'on est vraiment à gauche ou à droite pour lancer, comme suittag1
---->[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. À propos de l'entretien des propriétés
Afin de faciliter la démonstration, les attributs des personnages sont relativement dispersés, comme la vitesse et la puissance d'attaque. Puisqu'il peut être encapsulé ici HeroComponent
pour maintenir la classe protagoniste. Vous pouvez définir une HeroAttr
classe pour conserver les propriétés du personnage principal, comme suit :
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,
});
}
复制代码
De cette manière, HeroComponent
lors HeroAttr
de , transmettez l'objet pour déterminer les informations d'attribut de l'objet.
---->[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);
复制代码
De cette façon, la perte de valeur de vie du monstre peut être calculée selon HeroAttr
l' attribut de :
---->[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);
}
复制代码
Lors de l'ajout de balles, la vitesse et la portée d'attaque peuvent être déterminées en fonction HeroAttr
des informations d'attribut de :
Dans cet article, nous continuons à développer la fonction des rôles, sachant que la transformation des composants parents affectera les composants enfants, vous devez donc faire attention à la relation entre les composants lors de l'utilisation des composants. De plus, les informations sur le personnage sont HeroAttr
encapsulées , de sorte que via HeroComponent
, vous pouvez ajouter plusieurs nœuds de protagoniste et vous pouvez combattre des monstres en mode double.
À ce stade, vous pouvez voir TolyGame
que c'est très chaotique.Dans le chapitre suivant, je présenterai comment gérer plusieurs personnages et monstres, y compris la génération de monstres, tirer des balles, frapper le protagoniste, etc. C'est tout pour cet article, à demain ~
@张风捷特烈 2022.06.05 未允禁转
我的 公众号: 编程之王
我的 掘金主页
: Zhang Fengjieteli我的 B站主页
: Zhang Fengjieteli我的 github 主页
: toly1994328
\