update : icon image
This commit is contained in:
@@ -1,277 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../providers/battle_provider.dart';
|
||||
import '../../game/model/item.dart';
|
||||
import '../../utils/item_utils.dart';
|
||||
import '../../game/enums.dart';
|
||||
import '../../game/config/theme_config.dart';
|
||||
|
||||
class ShopUI extends StatelessWidget {
|
||||
final BattleProvider battleProvider;
|
||||
|
||||
const ShopUI({super.key, required this.battleProvider});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final player = battleProvider.player;
|
||||
final shopItems = battleProvider.currentStage.shopItems;
|
||||
|
||||
return Container(
|
||||
color: ThemeConfig.shopBg,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// Header: Merchant Icon & Player Gold
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Row(
|
||||
children: [
|
||||
Icon(Icons.store, size: 32, color: ThemeConfig.mainIconColor),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
"Merchant",
|
||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.monetization_on, color: ThemeConfig.statGoldColor),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
"${player.gold} G",
|
||||
style: const TextStyle(
|
||||
color: ThemeConfig.statGoldColor,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(color: ThemeConfig.textColorGrey),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Shop Items Grid
|
||||
Expanded(
|
||||
child: shopItems.isEmpty
|
||||
? const Center(
|
||||
child: Text(
|
||||
"Sold Out",
|
||||
style: TextStyle(color: ThemeConfig.textColorGrey, fontSize: 24),
|
||||
),
|
||||
)
|
||||
: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2, // 2 columns
|
||||
crossAxisSpacing: 16.0,
|
||||
mainAxisSpacing: 16.0,
|
||||
childAspectRatio: 0.8, // Taller cards
|
||||
),
|
||||
itemCount: shopItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = shopItems[index];
|
||||
final canBuy = player.gold >= item.price;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => _showBuyConfirmation(context, item),
|
||||
child: Card(
|
||||
color: ThemeConfig.shopItemCardBg,
|
||||
shape: item.rarity != ItemRarity.magic
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: ItemUtils.getRarityColor(item.rarity),
|
||||
width: 2.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
)
|
||||
: null,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Icon
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
ItemUtils.getIcon(item.slot),
|
||||
size: 48,
|
||||
color: ItemUtils.getColor(item.slot),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Name
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: Text(
|
||||
item.name,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ItemUtils.getRarityColor(item.rarity),
|
||||
fontSize: 12,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Stats
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: _buildItemStatText(item),
|
||||
),
|
||||
// Price Button
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: canBuy ? ThemeConfig.statGoldColor : ThemeConfig.btnDisabled,
|
||||
foregroundColor: Colors.black,
|
||||
padding: EdgeInsets.zero,
|
||||
),
|
||||
onPressed: canBuy
|
||||
? () => _showBuyConfirmation(context, item)
|
||||
: null,
|
||||
child: Text(
|
||||
"${item.price} G",
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Footer Buttons (Reroll & Leave)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: ThemeConfig.btnRerollBg,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
onPressed: player.gold >= 50
|
||||
? () => battleProvider.rerollShopItems()
|
||||
: null,
|
||||
icon: const Icon(Icons.refresh, color: ThemeConfig.textColorWhite),
|
||||
label: const Text(
|
||||
"Reroll (50 G)",
|
||||
style: TextStyle(color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: ThemeConfig.btnLeaveBg,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
onPressed: () => battleProvider.proceedToNextStage(),
|
||||
icon: const Icon(Icons.exit_to_app, color: ThemeConfig.textColorWhite),
|
||||
label: const Text(
|
||||
"Leave Shop",
|
||||
style: TextStyle(color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showBuyConfirmation(BuildContext context, Item item) {
|
||||
if (battleProvider.player.gold < item.price) return;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: const Text("Buy Item"),
|
||||
content: Text("Buy ${item.name} for ${item.price} G?"),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text("Cancel"),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: ThemeConfig.statGoldColor),
|
||||
onPressed: () {
|
||||
battleProvider.buyItem(item);
|
||||
Navigator.pop(ctx);
|
||||
},
|
||||
child: const Text("Buy", style: TextStyle(color: Colors.black)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildItemStatText(Item item) {
|
||||
List<String> stats = [];
|
||||
if (item.atkBonus > 0) stats.add("ATK +${item.atkBonus}");
|
||||
if (item.hpBonus > 0) stats.add("HP +${item.hpBonus}");
|
||||
if (item.armorBonus > 0) stats.add("DEF +${item.armorBonus}");
|
||||
if (item.luck > 0) stats.add("LUCK +${item.luck}");
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (stats.isNotEmpty)
|
||||
Text(
|
||||
stats.join(", "),
|
||||
style: const TextStyle(fontSize: 10, color: Colors.white70),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (item.effects.isNotEmpty)
|
||||
Text(
|
||||
item.effects.first.type.name.toUpperCase(),
|
||||
style: const TextStyle(fontSize: 9, color: ThemeConfig.rarityLegendary),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class RestUI extends StatelessWidget {
|
||||
final BattleProvider battleProvider;
|
||||
|
||||
const RestUI({super.key, required this.battleProvider});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.local_hotel, size: 64, color: ThemeConfig.btnRestBg),
|
||||
const SizedBox(height: 16),
|
||||
const Text("Rest Area", style: TextStyle(fontSize: 24, color: ThemeConfig.textColorWhite)),
|
||||
const SizedBox(height: 8),
|
||||
const Text("Take a breath and heal.", style: TextStyle(color: ThemeConfig.textColorWhite)),
|
||||
const SizedBox(height: 32),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
battleProvider.player.heal(20);
|
||||
battleProvider.proceedToNextStage();
|
||||
},
|
||||
child: const Text("Rest & Leave (+20 HP)"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user