Flutter魔法卡牌游戏插件magic_the_gathering_flutter的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter魔法卡牌游戏插件magic_the_gathering_flutter的使用

通过开发自定义的MTG Flutter小部件,可以轻松地创建《魔法风云会》(MTG)应用。该插件完全支持MTG的法术力和其他符号。

示例

以下展示了如何使用MTG Flutter小部件:

展示四张示例卡片的图像

还支持“Un”系列的卡片:

展示四张示例“Un”系列卡片的图像

功能

  • 表示一张MTG卡片的模型
  • 支持双面卡
  • 使用支持的 fromMap 构造函数将JSON转换为模型实例
  • 所有MTG符号的SVG,并提供了方便的方法来显示它们
  • 最小的外部依赖项 - 只使用了 <a href="https://pub.dev/packages/flutter_svg">flutter_svg</a><a href="https://pub.dev/packages/equatable">equatable</a>
  • 支持Android、iOS、Linux、MacOS、Web和Windows平台

入门指南

你需要自己提供MTG卡片的数据。可以考虑使用 <a href="https://scryfall.com/docs/api" rel="ugc">Scryfall API</a> 下载或请求数据(此包完全与之兼容)!

然后使用模型的 fromMap 构造函数实例化一个 MTGCard 对象。

final blackLotus = MTGCard.fromMap({
    "keywords": [],
    "lang": "en",
    "rarity": "bonus",
    "released_at": "2014-06-16",
    "reserved": true,
    "set": "vma",
    "set_name": "Vintage Masters",
    "artist": "Chris Rahn",
    "image_uris": {
    "art_crop":
        "https://cards.scryfall.io/art_crop/front/b/d/bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd.jpg?1614638838",
    },
    "mana_cost": "{0}",
    "cmc": 0.0,
    "name": "Black Lotus",
    "oracle_text":
        "{T}, Sacrifice Black Lotus: Add three mana of any one color.",
    "type_line": "Artifact",
});

目前不支持 MTGCard 模型的默认构造函数。推荐的做法是存储或请求MTG卡片数据作为JSON并将其解析为Dart Map 对象。

API

MTGCard

方法

方法 描述 返回类型
preparedManaCost 使用MTG符号SVG显示卡片的法术力费用 List<Widget>?
preparedOracleText 使用MTG符号SVG显示卡片的说明文本 TextSpan?

属性

属性 描述 返回类型
hasMultipleFaces 卡片对象是否有多个面 bool
sizeRatio MTG卡片的高度与宽度的比例 double
cornerRatio MTG卡片的高度与其圆角半径的比例 int

MTGSymbol

方法

方法 描述 返回类型
toSvg 将MTGSymbol对象转换为SVG小部件 SVGPicture

属性

属性 描述 返回类型
regex 匹配可以转换为MTGSymbol的文本 RegExp

示例

下面展示了如何显示一个简单的部件。该示例假定你已经有一个名为 blackLotusMTGCard 实例。

final cardImage = blackLotus.images?['art_crop'];
final child = Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
    Row(
        children: [
        Text(blackLotus.name),
        const Spacer(),
        ...?blackLotus.preparedManaCost(),
        ],
    ),
    const SizedBox(height: 8.0),
    if (cardImage != null) Image.network(cardImage),
    const SizedBox(height: 8.0),
    Text(blackLotus.typeLine),
    Text.rich(blackLotus.preparedOracleText() ??
        TextSpan(text: blackLotus.oracleText)),
    ],
);
return Scaffold(
    appBar: AppBar(
    backgroundColor: Theme.of(context).colorScheme.inversePrimary,
    title: Text('Magic: the Gathering Flutter App'),
    ),
    body: SafeArea(
    child: Center(child: child),
    ),
);

为了更详细的示例,请查看 <a href="https://github.com/zmuranaka/magic_the_gathering_flutter/tree/main/example" rel="ugc">example</a> 目录下的代码。

示例代码

以下是完整的示例代码,展示了如何在Flutter应用中使用 magic_the_gathering_flutter 插件。

import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:magic_the_gathering_flutter/models/mtg_card.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Magic: the Gathering Flutter App',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _cards = <MTGCard>[];

  [@override](/user/override)
  void initState() {
    super.initState();
    _loadMagicCards();
  }

  Future<void> _loadMagicCards() async {
    final jsonString = await rootBundle.loadString('assets/cards.json');
    if (!mounted) return;
    final json = jsonDecode(jsonString);
    if (json is! List) {
      throw ArgumentError.value(json, 'json', 'Expected type List');
    }
    for (final card in json) {
      _cards.add(MTGCard.fromMap(card));
    }
    setState(() {});
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text('Magic: the Gathering Flutter App'),
      ),
      body: SafeArea(
        child: Center(
          child: _cards.isEmpty
              ? const CircularProgressIndicator()
              : ListView.separated(
                  padding: EdgeInsets.symmetric(horizontal: 16.0),
                  itemCount: _cards.length,
                  itemBuilder: (context, index) => MTGCardTile(
                    card: _cards[index],
                  ),
                  separatorBuilder: (context, index) => Divider(thickness: 2.0),
                ),
        ),
      ),
    );
  }
}

class MTGCardTile extends StatelessWidget {
  const MTGCardTile({super.key, required this.card});

  final MTGCard card;

  [@override](/user/override)
  Widget build(BuildContext context) {
    final cardImage = card.images?['art_crop'];
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Text(card.name),
            const Spacer(),
            ...?card.preparedManaCost(),
          ],
        ),
        const SizedBox(height: 8.0),
        if (cardImage != null) Image.network(cardImage),
        const SizedBox(height: 8.0),
        Text(card.typeLine),
        Text.rich(card.preparedOracleText() ?? TextSpan(text: card.oracleText)),
      ],
    );
  }
}

更多关于Flutter魔法卡牌游戏插件magic_the_gathering_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter魔法卡牌游戏插件magic_the_gathering_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成并使用magic_the_gathering_flutter插件的示例代码。这个插件可能是一个假想的或第三方插件,用于与“Magic: The Gathering”(万智牌)相关的功能,比如查询卡牌信息、展示卡牌图片等。由于实际插件的API和可用功能可能有所不同,以下示例代码将基于假设的功能进行演示。

首先,确保你已经在pubspec.yaml文件中添加了该插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  magic_the_gathering_flutter: ^x.y.z  # 替换为实际版本号

然后,运行flutter pub get来获取依赖。

接下来,在你的Flutter应用中,你可以这样使用该插件:

import 'package:flutter/material.dart';
import 'package:magic_the_gathering_flutter/magic_the_gathering_flutter.dart';  // 假设的导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Magic: The Gathering Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CardSearchScreen(),
    );
  }
}

class CardSearchScreen extends StatefulWidget {
  @override
  _CardSearchScreenState createState() => _CardSearchScreenState();
}

class _CardSearchScreenState extends State<CardSearchScreen> {
  final TextEditingController _controller = TextEditingController();
  String _searchResult = '';

  void _searchCard() async {
    String query = _controller.text;
    if (query.isNotEmpty) {
      try {
        // 假设插件提供了一个searchCards方法
        var result = await MagicTheGathering.searchCards(query);
        
        // 假设返回的结果是一个包含卡牌信息的列表
        if (result.isNotEmpty) {
          setState(() {
            _searchResult = result.first.name;  // 仅显示第一个结果作为示例
            // 你可以在这里处理更多结果,比如显示一个列表
          });
        } else {
          setState(() {
            _searchResult = 'No cards found for "${query}"';
          });
        }
      } catch (e) {
        setState(() {
          _searchResult = 'Error searching for cards: ${e.message}';
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Search Magic Cards'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Search for a card',
                suffixIcon: IconButton(
                  icon: Icon(Icons.search),
                  onPressed: _searchCard,
                ),
              ),
            ),
            SizedBox(height: 16.0),
            Text(
              _searchResult,
              style: TextStyle(fontSize: 20),
            ),
            // 你可以在这里添加更多代码来显示卡牌图片、详细信息等
          ],
        ),
      ),
    );
  }
}

// 假设的MagicTheGathering类(实际使用时,这个类应由插件提供)
class MagicTheGathering {
  static Future<List<Card>> searchCards(String query) async {
    // 这里应该是调用插件提供的API来搜索卡牌
    // 返回一个模拟的卡牌列表作为示例
    return [
      Card(name: 'Island', type: 'Land'),
      Card(name: 'Mountain', type: 'Land'),
      // ... 更多卡牌
    ];
  }
}

// 假设的卡牌类(实际使用时,这个类应由插件提供或根据需要自定义)
class Card {
  final String name;
  final String type;
  // 可以添加更多属性,如manaCost, power, toughness, imageUrl等

  Card({required this.name, required this.type});
}

请注意,上述代码中的MagicTheGathering类和Card类是基于假设的,因为实际的插件API和返回的数据结构可能会有所不同。你需要参考插件的官方文档来调整这些代码。

另外,由于magic_the_gathering_flutter可能是一个虚构的插件名,你需要找到实际的插件名并替换上述代码中的导入路径和依赖项。如果插件提供了不同的方法或数据结构,你也需要相应地调整代码。

回到顶部