2024-06-07 20:02:06 +02:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|
|
|
import '../models/player.dart';
|
|
|
|
import '../models/role.dart';
|
|
|
|
|
|
|
|
class PlayerGridView extends StatefulWidget {
|
|
|
|
final List<Player> players;
|
|
|
|
|
|
|
|
const PlayerGridView({required this.players, Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
2024-06-07 20:08:07 +02:00
|
|
|
// ignore: library_private_types_in_public_api
|
2024-06-07 20:02:06 +02:00
|
|
|
_PlayerGridViewState createState() => _PlayerGridViewState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _PlayerGridViewState extends State<PlayerGridView> {
|
|
|
|
bool isNight = true;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
title: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
isNight ? Icons.nights_stay : Icons.wb_sunny,
|
|
|
|
size: 24,
|
|
|
|
color: isNight ? Colors.grey[300] : Colors.yellow,
|
|
|
|
),
|
2024-06-07 20:08:07 +02:00
|
|
|
const SizedBox(width: 10),
|
2024-06-07 20:02:06 +02:00
|
|
|
Text(
|
|
|
|
isNight ? 'Nacht' : 'Tag',
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
centerTitle: true,
|
|
|
|
actions: [
|
|
|
|
IconButton(
|
2024-06-07 20:08:07 +02:00
|
|
|
icon: const Icon(Icons.info),
|
2024-06-07 20:02:06 +02:00
|
|
|
onPressed: () {
|
|
|
|
_showRolesDialog();
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
leading: IconButton(
|
|
|
|
icon: const Icon(FontAwesomeIcons.xmark),
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.popUntil(context, ModalRoute.withName('/'));
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
body: Container(
|
|
|
|
color: isNight
|
|
|
|
? const Color(0xff2d2d2d)
|
2024-06-07 20:26:41 +02:00
|
|
|
: Color.fromARGB(255, 194, 216, 225),
|
2024-06-07 20:02:06 +02:00
|
|
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: GridView.builder(
|
|
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
crossAxisCount: 2,
|
|
|
|
mainAxisSpacing: 10,
|
|
|
|
crossAxisSpacing: 10,
|
|
|
|
),
|
|
|
|
itemCount: widget.players.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
widget.players[index];
|
|
|
|
|
|
|
|
return GestureDetector(
|
|
|
|
onTap: () {
|
|
|
|
setState(() {
|
|
|
|
if (!widget.players[index].isDead) {
|
|
|
|
_killPlayer(widget.players[index]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
child: Card(
|
|
|
|
color: widget.players[index].isDead
|
|
|
|
? Colors.grey
|
|
|
|
: Theme.of(context).colorScheme.primary,
|
|
|
|
child: Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
widget.players[index].name,
|
2024-06-07 20:08:07 +02:00
|
|
|
style: const TextStyle(fontSize: 24),
|
2024-06-07 20:02:06 +02:00
|
|
|
textAlign: TextAlign.center,
|
|
|
|
maxLines: 3,
|
|
|
|
overflow: TextOverflow.ellipsis,
|
|
|
|
),
|
|
|
|
if (widget.players[index].isDead)
|
2024-06-07 20:26:41 +02:00
|
|
|
const Icon(Icons.close,
|
|
|
|
color: Colors.red, size: 48),
|
2024-06-07 20:02:06 +02:00
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
2024-06-07 20:08:07 +02:00
|
|
|
const Divider(
|
2024-06-07 20:02:06 +02:00
|
|
|
height: 1,
|
|
|
|
color: Colors.grey,
|
|
|
|
),
|
|
|
|
Padding(
|
2024-06-07 20:26:41 +02:00
|
|
|
padding: const EdgeInsets.only(bottom: 60, top: 10),
|
2024-06-07 20:02:06 +02:00
|
|
|
child: ElevatedButton(
|
|
|
|
onPressed: _changePhase,
|
|
|
|
child: Text(isNight ? 'Tag skippen' : 'Nacht skippen'),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void _killPlayer(Player player) {
|
|
|
|
if (isNight) {
|
|
|
|
if (player.role != Role.werwolf) {
|
|
|
|
player.isDead = true;
|
|
|
|
_checkWinCondition();
|
|
|
|
isNight = false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
player.isDead = true;
|
|
|
|
_checkWinCondition();
|
|
|
|
if (player.role == Role.joker) {
|
|
|
|
_showWinDialog('Der Joker hat gewonnen!');
|
|
|
|
}
|
|
|
|
isNight = true;
|
|
|
|
}
|
|
|
|
setState(() {});
|
|
|
|
}
|
|
|
|
|
|
|
|
void _changePhase() {
|
|
|
|
if (isNight) {
|
|
|
|
isNight = false;
|
|
|
|
} else {
|
|
|
|
isNight = true;
|
|
|
|
}
|
|
|
|
setState(() {});
|
|
|
|
}
|
|
|
|
|
|
|
|
void _checkWinCondition() {
|
|
|
|
int countWolves = widget.players
|
|
|
|
.where((player) => !player.isDead && player.role == Role.werwolf)
|
|
|
|
.length;
|
|
|
|
int countVillagers = widget.players
|
|
|
|
.where((player) => !player.isDead && player.role != Role.werwolf)
|
|
|
|
.length;
|
|
|
|
|
|
|
|
if (countWolves == 0) {
|
|
|
|
_showWinDialog('Die Dorfbewohner haben gewonnen!');
|
|
|
|
} else if (countWolves >= countVillagers) {
|
|
|
|
_showWinDialog('Die Werwölfe haben gewonnen!');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void _showWinDialog(String message) {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return AlertDialog(
|
2024-06-07 20:08:07 +02:00
|
|
|
title: const Text('Spielende'),
|
2024-06-07 20:02:06 +02:00
|
|
|
content: Text(message),
|
|
|
|
actions: <Widget>[
|
|
|
|
TextButton(
|
2024-06-07 20:08:07 +02:00
|
|
|
child: const Text('Spiel beenden'),
|
2024-06-07 20:02:06 +02:00
|
|
|
onPressed: () {
|
|
|
|
Navigator.popUntil(context, ModalRoute.withName('/'));
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void _showRolesDialog() {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return AlertDialog(
|
2024-06-07 20:08:07 +02:00
|
|
|
title: const Text('Spielerrollen'),
|
|
|
|
content: SizedBox(
|
2024-06-07 20:02:06 +02:00
|
|
|
width: double.maxFinite,
|
|
|
|
child: ListView.builder(
|
|
|
|
shrinkWrap: true,
|
|
|
|
itemCount: widget.players.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
final player = widget.players[index];
|
|
|
|
return ListTile(
|
|
|
|
title: Text(
|
|
|
|
player.name,
|
|
|
|
style: Theme.of(context).textTheme.labelLarge,
|
|
|
|
),
|
|
|
|
subtitle: Text(
|
|
|
|
player.role.name,
|
|
|
|
style: TextStyle(
|
|
|
|
color: Theme.of(context).colorScheme.primary,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
actions: <Widget>[
|
|
|
|
TextButton(
|
2024-06-07 20:08:07 +02:00
|
|
|
child: const Text('OK'),
|
2024-06-07 20:02:06 +02:00
|
|
|
onPressed: () {
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|