update
This commit is contained in:
@@ -723,14 +723,9 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
onPressed: () {
|
||||
bool success = battleProvider.selectReward(item);
|
||||
if (!success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
"${AppStrings.inventoryFull} Cannot take item.",
|
||||
),
|
||||
backgroundColor:
|
||||
ThemeConfig.snackBarErrorBg,
|
||||
),
|
||||
ToastUtils.showTopToast(
|
||||
context,
|
||||
"${AppStrings.inventoryFull} Cannot take item.",
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export 'utils/game_math.dart';
|
||||
export 'utils/item_utils.dart';
|
||||
export 'utils/toast_utils.dart';
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../game/config.dart';
|
||||
|
||||
class ToastUtils {
|
||||
static void showTopToast(
|
||||
BuildContext context,
|
||||
String message, {
|
||||
Color? color,
|
||||
}) {
|
||||
final overlay = Overlay.of(context);
|
||||
late OverlayEntry overlayEntry;
|
||||
|
||||
overlayEntry = OverlayEntry(
|
||||
builder: (context) => Positioned(
|
||||
top: MediaQuery.of(context).padding.top + 10,
|
||||
left: 20,
|
||||
right: 20,
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0.0, end: 1.0),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeOutBack,
|
||||
builder: (context, value, child) {
|
||||
return Transform.translate(
|
||||
offset: Offset(0, -50 * (1 - value)),
|
||||
child: Opacity(
|
||||
opacity: value.clamp(0.0, 1.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: color ?? ThemeConfig.snackBarErrorBg,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.info_outline, color: Colors.white),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
message,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: ThemeConfig.fontSizeMedium,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
overlay.insert(overlayEntry);
|
||||
|
||||
// Auto remove after duration
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
overlayEntry.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,12 @@ class BattleHeader extends StatelessWidget {
|
||||
const BattleHeader({super.key});
|
||||
|
||||
String _getStageDisplayString(int stage) {
|
||||
// 3 Stages per Tier logic
|
||||
// Tier 1: 1, 2, 3 -> Underground Illegal Arena
|
||||
// Tier 2: 4, 5, 6 -> Colosseum
|
||||
// Tier 3: 7, 8, 9 -> King's Arena
|
||||
// Tier 1: 1-12 -> Underground Illegal Arena
|
||||
// Tier 2: 13-24 -> Colosseum
|
||||
// Tier 3: 25-36 -> King's Arena
|
||||
|
||||
final int tier = (stage - 1) ~/ 3 + 1;
|
||||
final int round = (stage - 1) % 3 + 1;
|
||||
final int tier = (stage - 1) ~/ 12 + 1;
|
||||
final int round = (stage - 1) % 12 + 1;
|
||||
String tierName = "";
|
||||
|
||||
switch (tier) {
|
||||
@@ -29,6 +28,10 @@ class BattleHeader extends StatelessWidget {
|
||||
break;
|
||||
}
|
||||
|
||||
if (round == 12) {
|
||||
return "$tierName - BOSS";
|
||||
}
|
||||
|
||||
return "$tierName - $round";
|
||||
}
|
||||
|
||||
|
||||
@@ -122,11 +122,24 @@ class CharacterStatusCard extends StatelessWidget {
|
||||
size: 60,
|
||||
color: ThemeConfig.textColorWhite,
|
||||
) // 플레이어 아이콘
|
||||
: Image.asset(
|
||||
'assets/data/enemy/enemy_01.png',
|
||||
: (character.image != null && character.image!.isNotEmpty)
|
||||
? Image.asset(
|
||||
character.image!,
|
||||
width: 200,
|
||||
height: 200,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return const Icon(
|
||||
Icons.psychology,
|
||||
size: 60,
|
||||
color: ThemeConfig.textColorWhite,
|
||||
);
|
||||
},
|
||||
)
|
||||
: const Icon(
|
||||
Icons.psychology,
|
||||
size: 60,
|
||||
color: ThemeConfig.textColorWhite,
|
||||
), // 적 이미지
|
||||
),
|
||||
),
|
||||
|
||||
@@ -6,6 +6,7 @@ import '../../../game/model/item.dart';
|
||||
import '../../../game/config/theme_config.dart';
|
||||
import '../../../game/config/game_config.dart';
|
||||
import '../../../game/model/entity.dart';
|
||||
import '../../utils.dart'; // Import for ToastUtils
|
||||
import '../inventory/inventory_grid_widget.dart';
|
||||
import '../common/item_card_widget.dart';
|
||||
|
||||
@@ -115,6 +116,7 @@ class ShopUI extends StatelessWidget {
|
||||
item,
|
||||
shopProvider,
|
||||
player,
|
||||
battleProvider, // Pass battleProvider
|
||||
),
|
||||
child: ItemCardWidget(
|
||||
item: item,
|
||||
@@ -155,11 +157,9 @@ class ShopUI extends StatelessWidget {
|
||||
battleProvider.stage,
|
||||
);
|
||||
if (!success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Not enough gold to reroll!"),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
ToastUtils.showTopToast(
|
||||
context,
|
||||
"Not enough gold to reroll!",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -205,13 +205,13 @@ class ShopUI extends StatelessWidget {
|
||||
Item item,
|
||||
ShopProvider shopProvider,
|
||||
Character player,
|
||||
BattleProvider battleProvider,
|
||||
) {
|
||||
if (player.gold < item.price) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text("Not enough gold!"),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
ToastUtils.showTopToast(
|
||||
context,
|
||||
"Not enough gold!",
|
||||
color: ThemeConfig.snackBarErrorBg,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -236,18 +236,16 @@ class ShopUI extends StatelessWidget {
|
||||
|
||||
if (success) {
|
||||
battleProvider.refreshUI(); // Update UI
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text("Bought ${item.name}"),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
ToastUtils.showTopToast(
|
||||
context,
|
||||
"Bought ${item.name}",
|
||||
color: Colors.green,
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(shopProvider.lastShopMessage),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
ToastUtils.showTopToast(
|
||||
context,
|
||||
shopProvider.lastShopMessage,
|
||||
color: ThemeConfig.snackBarErrorBg,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user