Flutter像素艺术生成插件pixel_art_generator的使用

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

Flutter像素艺术生成插件pixel_art_generator的使用

Pub

一个用于从可选模板生成像素艺术精灵的Flutter包。

示例

Humanoids Robots Spaceships

示例代码

生成单个像素艺术图块

final template = generateRandomPixelDataTemplate(
  5, 
  5,
  mirrorX: true,
  mirrorY: false,
  outline: true,
);
final pixelData = generateRandomPixelData(
  1,
  template,
).first;

从模板生成多个像素艺术图块

预定义的模板可以在这里找到。

// 加载assets/templates.json中的模板
final jsonString = await rootBundle.loadString('assets/templates.json');
final templates = loadPixelTemplatesFromJson(jsonString);
final humanoidTemplate = templates[...];
final pixelData = generateRandomPixelData(9, humanoidTemplate);

支持这个项目

其他项目

感谢

创建者 @albemala (Twitter)

受启发于 Pixel Sprite Generator

完整示例代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pixel_art_generator/pixel_art_generator.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Pixel Art Generator',
      home: AppContentView(),
    );
  }
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pixel Art Generator'),
      ),
      body: const PixelArtGeneratorView(),
    );
  }
}

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

  [@override](/user/override)
  State<PixelArtGeneratorView> createState() => _PixelArtGeneratorViewState();
}

class _PixelArtGeneratorViewState extends State<PixelArtGeneratorView> {
  static const randomTemplateName = 'Random';

  bool isRandomTemplateName(String name) {
    return name == randomTemplateName;
  }

  final dataColorConverter = CustomPixelDataColorConverter();

  int tilesCount = 3;

  final availableTemplates = <PixelDataTemplate>[];

  final allTemplates = <String>[
    randomTemplateName,
  ];
  String selectedTemplateName = randomTemplateName;

  int dataSize = 4;
  bool mirrorX = false;
  bool mirrorY = false;
  bool outline = false;

  var pixelData = <PixelData>[];

  PixelDataTemplate get selectedTemplate {
    return availableTemplates.firstWhere((element) {
      return element.name == selectedTemplateName;
    });
  }

  int get selectedTemplateDataSize {
    return isRandomTemplateName(selectedTemplateName)
        ? dataSize
        : selectedTemplate.width;
  }

  bool get selectedTemplateMirrorX {
    return isRandomTemplateName(selectedTemplateName)
        ? mirrorX
        : selectedTemplate.options.mirrorX;
  }

  bool get selectedTemplateMirrorY {
    return isRandomTemplateName(selectedTemplateName)
        ? mirrorY
        : selectedTemplate.options.mirrorY;
  }

  bool get selectedTemplateOutline {
    return isRandomTemplateName(selectedTemplateName)
        ? outline
        : selectedTemplate.options.outline;
  }

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

  Future<void> _init() async {
    // 加载assets/templates.json中的模板
    final jsonString = await rootBundle.loadString('assets/templates.json');
    availableTemplates.addAll(loadPixelTemplatesFromJson(jsonString));
    setState(() {
      allTemplates.addAll(availableTemplates.map((e) => e.name));
    });
  }

  void updateData() {
    setState(() {
      final template = isRandomTemplateName(selectedTemplateName)
          ? generateRandomPixelDataTemplate(
              dataSize,
              dataSize,
              mirrorX: mirrorX,
              mirrorY: mirrorY,
              outline: outline,
            )
          : selectedTemplate;
      pixelData = generateRandomPixelData(
        tilesCount * tilesCount,
        template,
      );
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Row(
      children: [
        Padding(
          padding: const EdgeInsets.all(8),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Tiles count $tilesCount'),
              SizedBox(
                width: 240,
                child: Slider(
                  value: tilesCount.toDouble(),
                  min: 3,
                  max: 9,
                  divisions: 6,
                  onChanged: (value) {
                    tilesCount = value.toInt();
                    updateData();
                  },
                ),
              ),
              const SizedBox(height: 16),
              const Text('Template'),
              SizedBox(
                width: 240,
                child: DropdownButton<String>(
                  value: selectedTemplateName,
                  onChanged: (value) {
                    selectedTemplateName = value ?? randomTemplateName;
                    updateData();
                  },
                  items: allTemplates.map((e) {
                    return DropdownMenuItem<String>(
                      value: e,
                      child: Text(e),
                    );
                  }).toList(),
                ),
              ),
              const SizedBox(height: 16),
              Text('Data size $selectedTemplateDataSize'),
              if (isRandomTemplateName(selectedTemplateName))
                SizedBox(
                  width: 240,
                  child: Slider(
                    value: dataSize.toDouble(),
                    min: 4,
                    max: 16,
                    divisions: 12,
                    onChanged: (value) {
                      dataSize = value.toInt();
                      updateData();
                    },
                  ),
                ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Checkbox(
                    value: selectedTemplateMirrorX,
                    onChanged: (value) {
                      if (isRandomTemplateName(selectedTemplateName)) {
                        mirrorX = value ?? false;
                        updateData();
                      }
                    },
                  ),
                  const Text('Mirror X'),
                ],
              ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Checkbox(
                    value: selectedTemplateMirrorY,
                    onChanged: (value) {
                      if (isRandomTemplateName(selectedTemplateName)) {
                        mirrorY = value ?? false;
                        updateData();
                      }
                    },
                  ),
                  const Text('Mirror Y'),
                ],
              ),
              const SizedBox(height: 16),
              Row(
                children: [
                  Checkbox(
                    value: selectedTemplateOutline,
                    onChanged: (value) {
                      if (isRandomTemplateName(selectedTemplateName)) {
                        outline = value ?? false;
                        updateData();
                      }
                    },
                  ),
                  const Text('Outline'),
                ],
              ),
              const SizedBox(height: 16),
              FilledButton(
                onPressed: () {
                  updateData();
                },
                child: const Text('Generate'),
              ),
            ],
          ),
        ),
        Expanded(
          child: GridView.builder(
            itemCount: pixelData.length,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: tilesCount,
            ),
            itemBuilder: (BuildContext context, int index) {
              return Padding(
                padding: const EdgeInsets.all(12),
                child: PixelDataViewer(
                  pixelData: pixelData[index],
                  colorConverter: dataColorConverter,
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

class CustomPixelDataColorConverter extends PixelDataColorConverter {
  CustomPixelDataColorConverter();

  [@override](/user/override)
  Color convert(int value) {
    switch (value) {
      case backgroundData:
        return Colors.grey[100]!;
      case foregroundData:
        return Colors.grey[400]!;
      case accentData:
        return Colors.grey[600]!;
      case outlineData:
        return Colors.grey[800]!;
    }
    return Colors.red;
  }
}

更多关于Flutter像素艺术生成插件pixel_art_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter像素艺术生成插件pixel_art_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用pixel_art_generator插件的一个基本示例。这个插件假设能帮助你生成像素艺术图像。首先,确保你已经在pubspec.yaml文件中添加了该插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  pixel_art_generator: ^latest_version  # 替换为实际的最新版本号

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

以下是一个简单的Flutter应用示例,演示如何使用pixel_art_generator插件来生成像素艺术图像:

import 'package:flutter/material.dart';
import 'package:pixel_art_generator/pixel_art_generator.dart';  // 假设插件提供的主要类是 PixelArtGenerator

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pixel Art Generator Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PixelArtGeneratorPage(),
    );
  }
}

class PixelArtGeneratorPage extends StatefulWidget {
  @override
  _PixelArtGeneratorPageState createState() => _PixelArtGeneratorPageState();
}

class _PixelArtGeneratorPageState extends State<PixelArtGeneratorPage> {
  late Uint8List generatedPixelArt;

  @override
  void initState() {
    super.initState();
    generatePixelArt();
  }

  void generatePixelArt() async {
    // 假设 PixelArtGenerator 提供了一个静态方法 generate,可以生成像素艺术
    // 这里需要根据你的插件实际API进行调整
    generatedPixelArt = await PixelArtGenerator.generate(
      width: 64,  // 像素艺术图像的宽度
      height: 64, // 像素艺术图像的高度
      // 其他可能的参数,比如颜色模式、随机种子等
    );

    // 如果生成是异步的,并且需要在UI中使用结果,可以使用setState来更新状态
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Pixel Art Generator Demo'),
      ),
      body: Center(
        child: generatedPixelArt != null
            ? Image.memory(generatedPixelArt)
            : CircularProgressIndicator(), // 在生成过程中显示加载指示器
      ),
    );
  }
}

注意

  1. 上面的代码假设pixel_art_generator插件提供了一个名为PixelArtGenerator的类和一个静态方法generate,该方法返回一个Uint8List,代表生成的像素艺术图像数据。实际上,你需要查阅插件的文档来了解具体的API和用法。
  2. generate方法的参数(如宽度和高度)以及它可能返回的其他参数或配置,都需要根据插件的实际API进行调整。
  3. 如果插件没有提供直接生成图像数据的方法,可能需要使用其他图像绘制或处理库来显示生成的像素艺术。

确保查阅pixel_art_generator插件的官方文档和示例代码,以获得最准确和最新的使用方法。

回到顶部