import 'dart:math'; import 'package:flame_audio/flame_audio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_first_station/muyu/animate_text.dart'; import 'package:flutter_first_station/muyu/options/select_audio.dart'; import 'package:uuid/uuid.dart'; import 'models/audio_option.dart'; import 'models/image_option.dart'; import 'models/merit_record.dart'; import 'muyu_image.dart'; import 'count_panel.dart'; import 'muyu_app_bar.dart'; import 'options/select_image.dart'; import 'record_history.dart'; class MuyuPage extends StatefulWidget { const MuyuPage({Key? key}) : super(key: key); @override State createState() => _MuyuPageState(); } class _MuyuPageState extends State { int _counter = 0; MeritRecord? _cruRecord; int _activeImageIndex = 0; int _activeAudioIndex = 0; final Random _random = Random(); final Uuid uuid = Uuid(); List _records = []; final List audioOptions = const [ AudioOption('音效1', 'muyu_1.mp3'), AudioOption('音效2', 'muyu_2.mp3'), AudioOption('音效3', 'muyu_3.mp3'), ]; final List imageOptions = const [ ImageOption('基础版', 'assets/images/muyu.png', 1, 3), ImageOption('尊享版', 'assets/images/muyu2.png', 3, 6), ]; AudioPool? pool; @override void initState() { super.initState(); _initAudioPool(); } void _initAudioPool() async { pool = await FlameAudio.createPool( 'muyu_1.mp3', maxPlayers: 1, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: MuyuAppBar( onTapHistory: _toHistory, ), body: Column( children: [ Expanded( child: CountPanel( count: _counter, onTapSwitchAudio: _onTapSwitchAudio, onTapSwitchImage: _onTapSwitchImage, ), ), Expanded( child: Stack( alignment: Alignment.topCenter, children: [ MuyuAssetsImage( image: activeImage, onTap: _onKnock, ), if (_cruRecord != null) AnimateText(record: _cruRecord!,) ], ), ), ], ), ); } void _toHistory() { Navigator.of(context).push(MaterialPageRoute(builder: (_)=>RecordHistory(record: _records.reversed.toList()))); } void _onTapSwitchAudio() { showCupertinoModalPopup( context: context, builder: (BuildContext context) { return AudioOptionPanel( audioOptions: audioOptions, activeIndex: _activeAudioIndex, onSelect: _onSelectAudio, ); }, ); } void _onTapSwitchImage() { showCupertinoModalPopup( context: context, builder: (BuildContext context) { return ImageOptionPanel( imageOptions: imageOptions, activeIndex: _activeImageIndex, onSelect: _onSelectImage, ); }, ); } void _onKnock() { pool?.start(); setState(() { String id = uuid.v4(); _cruRecord = MeritRecord( id, DateTime.now().millisecondsSinceEpoch, knockValue, activeImage, audioOptions[_activeAudioIndex].name, ); _counter += _cruRecord!.value; // 添加功德记录 _records.add(_cruRecord!); }); } String get activeImage => imageOptions[_activeImageIndex].src; int get knockValue { int min = imageOptions[_activeImageIndex].min; int max = imageOptions[_activeImageIndex].max; return min + _random.nextInt(max + 1 - min); } void _onSelectImage(int value) { Navigator.of(context).pop(); if (value == _activeImageIndex) return; setState(() { _activeImageIndex = value; }); } String get activeAudio => audioOptions[_activeAudioIndex].src; void _onSelectAudio(int value) async{ Navigator.of(context).pop(); if (value == _activeAudioIndex) return; _activeAudioIndex = value; pool = await FlameAudio.createPool( activeAudio, maxPlayers: 1, ); } }