import 'package:flutter/material.dart'; import '../services/formation_generator.dart'; import '../data/formation_positions.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { Map? _result; List> _visiblePlayers = []; bool _isAnimating = false; // 低確率スタイルモード(デコイラン / ナンバー10 などの確率を下げる) bool _lowProbabilityMode = false; Future _generateFormation() async { setState(() { _result = null; _visiblePlayers = []; _isAnimating = true; }); // ★ 低確率モードを渡してフォメ+スカッド生成 final newFormation = FormationGenerator.generate( lowProbMode: _lowProbabilityMode, ); setState(() { _result = newFormation; }); final players = newFormation['positions'] as List; // 1枚ずつアニメーション的に追加 for (int i = 0; i < players.length; i++) { await Future.delayed(const Duration(milliseconds: 150)); setState(() { _visiblePlayers.add(Map.from(players[i])); }); } setState(() { _isAnimating = false; }); } // ポジションで色分け(表示はしないが色には使う) Color _getColor(String pos) { if (pos == 'GK') return Colors.orange; if (['CB', 'LSB', 'RSB'].contains(pos)) return Colors.blue; if (['DMF', 'CMF', 'OMF', 'LMF', 'RMF'].contains(pos)) return Colors.green; if (['CF', 'ST', 'RWG', 'LWG'].contains(pos)) return Colors.red; return Colors.grey; } // カード:表示はプレースタイルのみ Widget _buildPlayerCard(String pos, String style) { final color = _getColor(pos); return Container( width: 80, height: 60, decoration: BoxDecoration( color: color.withOpacity(0.9), borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.white, width: 1), ), padding: const EdgeInsets.all(4), child: Center( child: Text( style, textAlign: TextAlign.center, maxLines: 3, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold, ), ), ), ); } // ピッチにカードを並べる Widget _buildPitch(String formation, List> roles) { final layout = formationLayouts[formation]; if (layout == null) { return Center( child: Text( 'レイアウトが定義されていません: $formation', style: const TextStyle(color: Colors.white), ), ); } return LayoutBuilder( builder: (context, constraints) { final width = constraints.maxWidth; final height = constraints.maxHeight; const cardW = 80.0; const cardH = 60.0; final List children = []; // 背景(ピッチ) children.add(Container( width: width, height: height, decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.green.shade800, Colors.green.shade700], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), )); int index = 0; for (int row = 0; row < layout.length; row++) { for (int col = 0; col < layout[row].length; col++) { if (index >= roles.length) break; final posData = roles[index]; index++; final xNorm = layout[row][col]['x'] ?? 0.5; final yNorm = layout[row][col]['y'] ?? 0.5; final left = width * xNorm - cardW / 2; final top = height * yNorm - cardH / 2; children.add( Positioned( left: left, top: top, child: _buildPlayerCard( posData['pos'] ?? '', posData['style'] ?? '', ), ), ); } } return Stack(children: children); }, ); } @override Widget build(BuildContext context) { final formation = _result?['formation'] as String?; final positions = _visiblePlayers; return Scaffold( backgroundColor: Colors.green[900], appBar: AppBar( title: const Text('eFootball スカッドシミュレーター'), centerTitle: true, backgroundColor: Colors.green[900], ), body: Column( children: [ const SizedBox(height: 8), // 低確率モードスイッチ SwitchListTile( title: const Text( '低確率スタイルモード(デコイラン等の出現率を下げる)', style: TextStyle(color: Colors.white), ), value: _lowProbabilityMode, onChanged: (v) { setState(() { _lowProbabilityMode = v; }); }, ), const SizedBox(height: 4), // 抽選ボタン ElevatedButton.icon( onPressed: _isAnimating ? null : _generateFormation, icon: const Icon(Icons.shuffle), label: const Text('フォーメーション抽選'), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.green[900], ), ), const SizedBox(height: 8), // フォーメーション表示 if (formation != null) Text( 'フォーメーション: $formation', style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), // ピッチ Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: formation == null ? const Center( child: Text( '抽選ボタンを押してスカッドを生成', style: TextStyle(color: Colors.white70, fontSize: 16), ), ) : _buildPitch(formation, positions), ), ), ], ), ); } }