import 'dart:async'; import 'dart:typed_data'; import 'dart:ui'; import 'package:flame/collisions.dart'; import 'package:flame/text.dart'; import 'package:flutter/material.dart'; import 'package:funny_letters/runner/bonuses/bonus.dart'; import 'package:flame/components.dart'; import 'package:flame/flame.dart' as flame; final _colors = [ const Color(0xffF35050), const Color(0xffF38335), const Color(0xffFfc211), const Color(0xffFFF371), const Color(0xffD9F17F), const Color(0xffB2F250), const Color(0xff55d2b0), const Color(0xff55d2e9), const Color(0xff20a0f0), const Color(0xff8666f9), const Color(0xffd6a9f8), const Color(0xffB250F3), const Color(0xffF250F3), const Color(0xffF350B2), const Color(0xffaaaaaa), const Color(0xff555555), const Color(0xffeeeeee), ]; class LetterBonus extends PositionComponent with CollisionCallbacks, Bonus { LetterBonus(Vector2 size, this.letter) { this.size = size; this.anchor = Anchor.center; } final String letter; static Future rasterize(Component component, double width) async { final recorder = PictureRecorder(); final canvas = Canvas( recorder, Rect.fromPoints( const Offset(0, 0), Offset(width, width), ), ); await component.onLoad(); component.render(canvas); final picture = recorder.endRecording(); final image = await picture.toImage(width.toInt(), width.toInt()); final byteData = await image.toByteData(format: ImageByteFormat.png); return byteData!.buffer.asUint8List(); } static Widget image({ required String letter, required double width, }) { return FutureBuilder( future: rasterize(LetterBonus(Vector2(width, width), letter), width), builder: (context, snapshot) { if (snapshot.hasData == false) { return SizedBox( width: width, height: width, ); } return Image.memory( snapshot.requireData, width: width, height: width, ); }); } @override FutureOr onLoad() async { // final engLetter = letter // .replaceAll('á,', 'a') // .replaceAll('é', 'e') // .replaceAll('í', 'i') // .replaceAll('ó', 'o') // .replaceAll('ú', 'u') // .replaceAll('ü', 'u') // .replaceAll('ñ', 'n'); // sprite = await letterSprite(engLetter); addAll( [ RoundedComponent( size: size, color: _colors[letter.codeUnitAt(0) % _colors.length], cornerRadius: size.x / 6, shadow: true, ), TextComponent( text: letter.toUpperCase(), textRenderer: TextPaint( style: TextStyle( fontWeight: FontWeight.w900, fontFamily: 'Nunito', fontSize: size.y * 0.9, textBaseline: TextBaseline.alphabetic, color: const Color(0xff000000), ), ), anchor: Anchor.center, position: size * 0.5, size: size, ), ], ); add( RectangleHitbox( size: this.size * 0.9, position: size / 2, anchor: Anchor.center), ); } } class RoundedComponent extends PositionComponent { final Color color; final double cornerRadius; final bool shadow; RoundedComponent({ required super.size, this.color = const Color(0xFFFFFFFF), this.cornerRadius = 50, this.shadow = false, super.position, }); @override void render(Canvas canvas) { if (shadow) { canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, height / 10, width, height), Radius.circular(cornerRadius), ), Paint() ..color = const Color(0x44000000) ..style = PaintingStyle.fill, ); } canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, width, height), Radius.circular(cornerRadius), ), Paint() ..color = color ..style = PaintingStyle.fill, ); canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, width, height), Radius.circular(cornerRadius), ), Paint() ..color = const Color(0xFFdddddd) ..style = PaintingStyle.stroke, ); } }