創造を続け、成長を加速させましょう!「ナゲッツデイリーニュープラン・6月アップデートチャレンジ」に参加して7日目です。クリックしてイベントの詳細をご覧ください。
序文
これは、 Zhang Fengjietlieによって作成され、Nuggetsコミュニティで公開されているFlutter&Flame
一連です。他のプラットフォームでこの記事を表示している場合は、ナゲッツに移動してリンクに従って表示できます。記事は更新および改訂される可能性があるため、ナゲッツの記事のバージョンが優先されます。このシリーズの記事のリスト:
- 【Flutter&FlameGame-One】新しい世界への扉を開く
- 【Flutter&Flameゲーム-Ⅱ】ジョイスティックとキャラクターの動き
- 【Flutter&FlameGame-3】キーボードイベントとジェスチャー操作
- 【Flutter&Flameゲーム-4】スプライト画像の読み込み方法
- 【Flutter&FlameGame-Wu】CanvasParticipation | Character's Health Bar
- 【Flutter&Flameゲーム-Lu】ダメージ値|テキストコンポーネントの使用(
本文
)
1.言葉の価値
それがアプリケーションであろうとゲームであろうと、文字
永遠の表示対象です。图片
人類の文明は言葉を継承に依存しており、言葉の最大の価値は情報を伝えることにあります。以下は陰陽師の戦いのスクリーンショットです。キャラクターのダメージ、現在のパフォーマンス、幽霊の数、重大かどうか、式神の生存状況などはすべて、インタラクティブな情報を表示およびフィードバックするためにテキストに依存しています。プレイヤー。
ここでは、最初に、以下に示すように、血液バーに血液量情報を表示します。
2.テキストコンポーネント-TextComponent
Flame
で、TextComponent
ウィジェットを使用してテキストを表示します。図面内のクラスを介してテキストを描画できることはわかっFlutter
ています。実際、構造は本質的にカプセル化のレイヤーです。使用するクラスれています。TextPainter
TextComponent
TextPainter
TextPaint
以下Liveable
はでの処理です。TextComponent
オブジェクトを作成し、add
メソッドだけです。また、どのコンポーネントでもフレーム情報を表示add(RectangleHitbox)
できる、占有エリアの表示に便利です。コードを参照してください:【06/01】
final TextStyle _defaultTextStyle = const TextStyle(fontSize: 10, color: Colors.white);
late final TextComponent _text;
void initPaint({
required double lifePoint,
Color lifeColor = Colors.red,
Color outlineColor = Colors.white,
}) {
// 略...
// 添加生命值文字
_text = TextComponent(textRenderer: TextPaint(style: _defaultTextStyle));
_updateLifeText();
// 添加外框信息
_text.add(RectangleHitbox()..debugMode = true);
add(_text);
}
void _updateLifeText(){
_text.text = 'Hp ${_currentLife.toInt()}';
}
复制代码
以下に示すように、デフォルトTextComponent
で、親領域の左上隅に配置されます。さらに、TextComponent
はPositionComponent
コンポーネントのファミリーでもあり、平行移動、スケーリング、回転などの操作を実行できます。
たとえば、以下は指定されたtag1
位置に配置され、_text
左側はヘルスバーに揃えられ、ヘルスバーの上に配置されます。position
// 添加生命值文字
_text = TextComponent(textRenderer: TextPaint(style: _defaultTextStyle));
_updateLifeText();
double y = -(offsetY+_text.height+2);
double x = (size.x/2)*(1-widthRadio);
_text.position = Vector2(x, y); // tag1
add(_text);
复制代码
情報ボックスを削除すると、次のように表示され、クリックすると寿命が短くなります。テキストを_updateLifeText
更新する
3.損傷データを表示します
モンスターが攻撃されると、通常、ダメージデータが表示され、オペレーターがより直感的に体験できるようになります。これで、モンスターが怪我をした場合、左側にダメージ量が表示され1s
、ダメージ量を維持すると自動的に。以下に示すように:コード[06/02]を参照してください
伤害数据是在 Liveable
中维护的,虽然可以直接在 Liveable
中添加文字。但这样的话会使得 Liveable
的职能过于复杂,也不利于后续的拓展。我们可以单独定义一个 DamageText
构件,来维护伤害数值的显示逻辑。
如下代码所示,在 Liveable
中添加一个 addDamage
的方法,在 tag1
处添加 damageText
文字。然后使用 Future.delayed
方法,延迟 1s
中,调用 damageText.removeFromParent
方法即可移除。
class DamageText extends PositionComponent{
final TextStyle _damageTextStyle = const TextStyle(
fontSize: 14,
color: Colors.white,
fontFamily: 'Menlo',
shadows: [
Shadow(color: Colors.red, offset: Offset(1, 1), blurRadius: 1),
]);
Future<void> addDamage(int damage) async {
TextComponent damageText =
TextComponent(textRenderer: TextPaint(style: _damageTextStyle));
damageText.text = damage.toString();
damageText.position = Vector2(-30, 0);
add(damageText); // tag1
await Future.delayed(const Duration(seconds: 1));
damageText.removeFromParent();
}
}
复制代码
这样在 Liveable
中就不必处理具体添加伤害文字的逻辑,只需要通过 DamageText
来管理即可。比如在 loss
方法中,当角色受到伤害,通过 _damageText.addDamage
来添加伤害文字,这样处理就非常方便。想要对伤害文字进行显示进行修改或拓展,直接在 DamageText
处理即可,这就是职责的分离。
final DamageText _damageText = DamageText();
void initPaint({
required double lifePoint,
Color lifeColor = Colors.red,
Color outlineColor = Colors.white,
}) {
// 略...
add(_damageText);
}
void loss(double point) {
_damageText.addDamage(-point.toInt());
// 略...
}
复制代码
4. 暴击伤害
这里来模拟一下产生暴击的情况:如下图所示,伤害时有一定概率产生暴击,此时使用另一种文字样式。并给出 暴击
的字样提示:代码见 【06/03】
实现也比较简单,在 addDamage
中,传入 isCrit
的入参,区分是否暴击。如果是暴击,使用 _addCritDamage
进行处理,添加黄色伤害和暴击字样即可。
---->[DamageText]----
void addDamage(int damage,{bool isCrit = false}) {
if(!isCrit){
_addWhiteDamage(damage);
}else{
_addCritDamage(damage);
}
}
Future<void> _addCritDamage(int damage) async {
TextComponent damageText =
TextComponent(textRenderer: TextPaint(style: _critDamageTextStyle));
damageText.text = damage.toString();
damageText.position = Vector2(-30, 0);
TextStyle style = _critDamageTextStyle.copyWith(fontSize: 10);
TextComponent infoText = TextComponent(textRenderer: TextPaint(style:style ));
infoText.text = '暴击';
infoText.position = Vector2(-30+damageText.width-infoText.width/2, -infoText.height/2);
add(infoText);
add(damageText);
await Future.delayed(const Duration(seconds: 1));
infoText.removeFromParent();
damageText.removeFromParent();
}
复制代码
暴击和爆伤,本应是角色的属性,这里暂时不搞这么复杂,在 Liveable
的 loss
方法中,用 75%
暴击和 165%
爆伤进行简单的测试,代码如下:
---->[Liveable]----
final Random _random = Random();
void loss(double point) {
double crit = 0.75;
double critDamage = 1.65;
bool isCrit = _random.nextDouble() < crit;
if (isCrit) {
point = point * critDamage;
}
_damageText.addDamage(-point.toInt(),isCrit: isCrit);
// 略...
}
复制代码
5.多次伤害
1s
ダメージはその後消えます。連続ダメージが1秒以内の場合、または1つのダメージに複数のダメージが追加された場合、オクルージョンが発生します。したがって、複数の損傷に対してオフセット処理を実行する必要があり、その効果は次のとおりです。コード[06/04]を参照してください。
ここComponent
でおり、それぞれにサブコンポーネントのコレクションを表すプロパティComponent
があります。ではchildren
、追加されたテキストのオフセットを決定するために、コレクションに従って最後の要素を取得するだけで済みます。addDamage
void addDamage(int damage,{bool isCrit = false}) {
Vector2 offset = Vector2(-30, 0);
if(children.isNotEmpty){
final PositionComponent last;
if(children.last is PositionComponent){
last = children.last as PositionComponent;
offset = last.position + Vector2(5, last.height);
}
}
if(!isCrit){
_addWhiteDamage(damage,offset);
}else{
_addCritDamage(damage,offset);
}
}
复制代码
テキスト自体は比較的単純ですが、テキストに関連するデータの保守と論理処理は依然として非常に複雑です。この記事では、役割の生命值
合計を表示することにより伤害值
、テキストがどのように使用されるかを簡単に説明します。一般的なゲームでは、陰陽師のダメージ数などの写真がテキストとして使用されます。6000
の文字列など、フォント内の関連する画像に対応するフォントを形成するための画像用のツールが必要であることを忘れないでください。ただし、flame
フレームワークいます。
この記事は以上です、また明日〜
@张风捷特烈 2022.05.31 未允禁转
我的 公众号: 编程之王
我的 掘金主页
:張鳳凰寺我的 B站主页
:張鳳凰寺我的 github 主页
:toly1994328
\