From 73b7c136f1e97178f0544fc950be348ef7080384 Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Mon, 15 Jun 2026 19:40:25 +0330 Subject: [PATCH] feat: add depth to game --- lib/core/theme/app_theme.dart | 7 +++ lib/features/game/flame/card_component.dart | 24 +++++++++ lib/features/game/flame/table_pieces.dart | 46 +++++++++++++---- lib/features/lobby/lobby_screen.dart | 56 +++++++++++++++++++-- 4 files changed, 117 insertions(+), 16 deletions(-) diff --git a/lib/core/theme/app_theme.dart b/lib/core/theme/app_theme.dart index e376ed3..e0eb1b6 100644 --- a/lib/core/theme/app_theme.dart +++ b/lib/core/theme/app_theme.dart @@ -56,12 +56,19 @@ class AppTheme { backgroundColor: AppColors.accent, foregroundColor: AppColors.text, minimumSize: const Size.fromHeight(54), + elevation: 8, + shadowColor: Colors.black, textStyle: const TextStyle( fontFamily: fontFamily, fontSize: 18, fontWeight: FontWeight.bold), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), side: const BorderSide(color: AppColors.gold, width: 1.5), ), + ).copyWith( + // افکتِ فشار: کمی فرورفتن هنگام لمس برای حسِ عمق. + elevation: WidgetStateProperty.resolveWith( + (states) => states.contains(WidgetState.pressed) ? 2.0 : 8.0, + ), ), ), ); diff --git a/lib/features/game/flame/card_component.dart b/lib/features/game/flame/card_component.dart index d7c1449..258ea96 100644 --- a/lib/features/game/flame/card_component.dart +++ b/lib/features/game/flame/card_component.dart @@ -106,6 +106,14 @@ class CardComponent extends PositionComponent final radius = Radius.circular(size.x * 0.09); final rrect = RRect.fromRectAndRadius(rect, radius); + // سایه‌ی سبک و ارزان (بدون blurِ هر-فریمی) فقط برای کارت‌های رو ⇒ عمق بدون افت کارایی. + // (drawShadow هر فریم برای ده‌ها کارت بسیار سنگین بود و باعث لگ می‌شد.) + if (faceUp) { + final off = _dragging ? size.x * 0.10 : size.x * 0.03; + canvas.drawRRect(rrect.shift(Offset(off * 0.4, off)), + Paint()..color = Color(_dragging ? 0x66000000 : 0x44000000)); + } + if (_sprite != null) { canvas.save(); canvas.clipRRect(rrect); @@ -117,6 +125,22 @@ class CardComponent extends PositionComponent _drawVectorBack(canvas, rrect); } + // براقیتِ ملایم از بالا فقط برای کارت‌های رو. + if (faceUp) { + canvas.save(); + canvas.clipRRect(rrect); + canvas.drawRect( + Rect.fromLTWH(0, 0, size.x, size.y * 0.5), + Paint() + ..shader = const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0x2BFFFFFF), Color(0x00FFFFFF)], + ).createShader(Rect.fromLTWH(0, 0, size.x, size.y * 0.5)), + ); + canvas.restore(); + } + if (dimmed) { canvas.drawRRect(rrect, Paint()..color = const Color(0x73000000)); } diff --git a/lib/features/game/flame/table_pieces.dart b/lib/features/game/flame/table_pieces.dart index 8a4c7dd..1f60aaf 100644 --- a/lib/features/game/flame/table_pieces.dart +++ b/lib/features/game/flame/table_pieces.dart @@ -7,24 +7,48 @@ import 'package:flutter/material.dart'; const _gold = Color(0xFFE9B949); const _goldDark = Color(0xFFB8860B); -/// نمدِ سبزِ بیضی‌شکلِ میز با حاشیه‌ی طلایی. +/// نمدِ سبزِ بیضی‌شکلِ میز با عمق: لبه‌ی برجسته، گرادیانِ شعاعی و وینیت. class Felt extends PositionComponent with HasGameReference { @override void render(Canvas canvas) { final w = game.size.x, h = game.size.y; - final rect = Rect.fromCenter( - center: Offset(w / 2, h / 2), - width: w * 0.86, - height: h * 0.62, - ); - final rrect = RRect.fromRectAndRadius(rect, Radius.circular(h * 0.3)); - canvas.drawRRect(rrect, Paint()..color = const Color(0xFF1B5E20)); + final center = Offset(w / 2, h / 2); + final rect = Rect.fromCenter(center: center, width: w * 0.86, height: h * 0.62); + final radius = Radius.circular(h * 0.3); + final felt = RRect.fromRectAndRadius(rect, radius); + + // ۱) لبه‌ی چوبیِ بیرونی (ریل) با گرادیان — حسِ برجستگی بدون drawShadowِ هر-فریمی. + final rail = RRect.fromRectAndRadius( + rect.inflate(w * 0.03), Radius.circular(h * 0.33)); canvas.drawRRect( - rrect, + rail, + Paint() + ..shader = const LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0xFF5A2E12), Color(0xFF2E1608)], + ).createShader(rail.outerRect), + ); + + // ۲) حلقه‌ی طلایی بین ریل و نمد. + canvas.drawRRect( + RRect.fromRectAndRadius(rect.inflate(w * 0.008), radius), Paint() ..style = PaintingStyle.stroke - ..strokeWidth = 6 - ..color = _goldDark, + ..strokeWidth = w * 0.012 + ..color = _gold, + ); + + // ۳) نمدِ سبز با گرادیانِ شعاعی (مرکز روشن، لبه‌ها تیره) — خودش حسِ وینیت/عمق می‌دهد. + canvas.drawRRect( + felt, + Paint() + ..shader = RadialGradient( + center: Alignment.center, + radius: 0.95, + colors: const [Color(0xFF34A03F), Color(0xFF0E3614)], + stops: const [0.45, 1.0], + ).createShader(rect), ); } } diff --git a/lib/features/lobby/lobby_screen.dart b/lib/features/lobby/lobby_screen.dart index c76c129..144de65 100644 --- a/lib/features/lobby/lobby_screen.dart +++ b/lib/features/lobby/lobby_screen.dart @@ -195,13 +195,59 @@ class _MenuButton extends StatelessWidget { @override Widget build(BuildContext context) { + // رنگِ تیره‌ترِ پایه برای بِوِل (لبه‌ی پایینیِ برجسته). + final dark = Color.lerp(color, Colors.black, 0.45)!; + final light = Color.lerp(color, Colors.white, 0.12)!; return SizedBox( width: 280, - child: ElevatedButton.icon( - style: ElevatedButton.styleFrom(backgroundColor: color), - onPressed: onTap, - icon: Icon(icon, color: AppColors.gold), - label: Text(label), + child: Material( + color: Colors.transparent, + borderRadius: BorderRadius.circular(16), + child: InkWell( + borderRadius: BorderRadius.circular(16), + onTap: onTap, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 15), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [light, color, dark], + stops: const [0, 0.5, 1], + ), + borderRadius: BorderRadius.circular(16), + border: Border.all(color: AppColors.gold, width: 1.6), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.55), + blurRadius: 10, + offset: const Offset(0, 5), + ), + // هایلایتِ بالا برای حسِ شیشه‌ای/برجسته. + BoxShadow( + color: Colors.white.withValues(alpha: 0.12), + blurRadius: 1, + offset: const Offset(0, 1), + spreadRadius: -1, + ), + ], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon, color: AppColors.gold), + const SizedBox(width: 10), + Text(label, + style: const TextStyle( + color: AppColors.text, + fontSize: 18, + fontWeight: FontWeight.bold, + shadows: [Shadow(color: Colors.black54, blurRadius: 3)], + )), + ], + ), + ), + ), ), ); }