diff --git a/assets/images/Main Characters/Wife Father/Idle (32x32).png b/assets/images/Main Characters/Wife Father/Idle (32x32).png new file mode 100644 index 0000000..1b24363 Binary files /dev/null and b/assets/images/Main Characters/Wife Father/Idle (32x32).png differ diff --git a/assets/images/Main Characters/Wife Father/Idle (32x32).psd b/assets/images/Main Characters/Wife Father/Idle (32x32).psd new file mode 100644 index 0000000..987bfab Binary files /dev/null and b/assets/images/Main Characters/Wife Father/Idle (32x32).psd differ diff --git a/assets/images/Main Characters/Wife Father/Run (32x32).png b/assets/images/Main Characters/Wife Father/Run (32x32).png new file mode 100644 index 0000000..1b24363 Binary files /dev/null and b/assets/images/Main Characters/Wife Father/Run (32x32).png differ diff --git a/assets/images/Main Characters/Wife Mom/Idle (32x32).png b/assets/images/Main Characters/Wife Mom/Idle (32x32).png new file mode 100644 index 0000000..bd51da2 Binary files /dev/null and b/assets/images/Main Characters/Wife Mom/Idle (32x32).png differ diff --git a/assets/images/Main Characters/Wife Mom/Run (32x32).png b/assets/images/Main Characters/Wife Mom/Run (32x32).png new file mode 100644 index 0000000..bd51da2 Binary files /dev/null and b/assets/images/Main Characters/Wife Mom/Run (32x32).png differ diff --git a/lib/components/CharacterShadow.dart b/lib/components/CharacterShadow.dart new file mode 100644 index 0000000..b3d1053 --- /dev/null +++ b/lib/components/CharacterShadow.dart @@ -0,0 +1,20 @@ +import 'dart:ui'; + +import 'package:flame/components.dart'; +import 'package:flutter/material.dart'; + +class CharacterShadow extends PositionComponent { + @override + void render(Canvas canvas) { + // Draw an ellipse for the shadow + final paint = Paint()..color = Colors.black.withOpacity(0.5); + canvas.drawOval( + Rect.fromCenter( + center: Offset(size.x / 2, size.y), + width: size.x * 0.8, + height: size.y * 0.2, + ), + paint, + ); + } +} diff --git a/lib/components/WifesFather.dart b/lib/components/WifesFather.dart index 9fa14d8..5eb2e3d 100644 --- a/lib/components/WifesFather.dart +++ b/lib/components/WifesFather.dart @@ -1,7 +1,9 @@ +import 'dart:math'; import 'dart:ui'; - +import 'package:moonshiner_game/components/CharacterShadow.dart'; import 'package:moonshiner_game/components/npc.dart'; import 'package:flame/components.dart'; +import 'package:moonshiner_game/components/utils.dart'; class WifesFather extends AbstractNPC { WifesFather({required Vector2 position}) @@ -15,12 +17,61 @@ class WifesFather extends AbstractNPC { ); @override - Color getColorForNPC() => const Color(0xFFAA0000); // Dark red for the father + Future onLoad() async { + loadAllAnimations(); + + // Create a shadow component + final shadow = CharacterShadow() + ..size = Vector2(16, 4) // Adjust size based on your character + ..position = + Vector2(8, size.y - 4); // Position the shadow below the character + + // Add the shadow as a child + add(shadow); + return super.onLoad(); + } @override - void updateMovement(double dt) { - // This NPC does not move, so velocity is always zero + Color getColorForNPC() => const Color(0xFFFFAAAA); // Light pink for the mom + + @override + void loadAllAnimations() { + final idleAnimation = spriteAnimation('Idle', 11); + final walkingAnimation = spriteAnimation('Run', 11); + + animations = { + NPCState.idle: idleAnimation, + NPCState.walking: walkingAnimation, + }; current = NPCState.idle; - velocity = Vector2.zero(); + } + + @override + SpriteAnimation spriteAnimation(String state, int amount) { + return SpriteAnimation.fromFrameData( + game.images.fromCache('Main Characters/Wife Father/$state (32x32).png'), + SpriteAnimationData.sequenced( + amount: amount, + stepTime: 0.05, + textureSize: Vector2.all(32), + ), + ); + } + + @override + void update(double dt) { + checkCollisions(); + + velocity = Vector2.all(0); + + super.update(dt); + } + + @override + void checkCollisions() {} + + @override + void updateMovement(double dt) { + // TODO: implement updateMovement } } diff --git a/lib/components/WifesMom.dart b/lib/components/WifesMom.dart index 002ad8f..e6b77d9 100644 --- a/lib/components/WifesMom.dart +++ b/lib/components/WifesMom.dart @@ -1,12 +1,14 @@ +import 'dart:math'; import 'dart:ui'; - +import 'package:moonshiner_game/components/CharacterShadow.dart'; import 'package:moonshiner_game/components/npc.dart'; import 'package:flame/components.dart'; +import 'package:moonshiner_game/components/utils.dart'; class WifesMom extends AbstractNPC { WifesMom({required Vector2 position}) : super( - npcCharacter: 'Wifes Mother', + npcCharacter: 'Wife\'s Mother', dialogues: [ "Farewell, my dear daughter!", "Please take care of yourself and your husband.", @@ -14,13 +16,62 @@ class WifesMom extends AbstractNPC { position: position, ); + @override + Future onLoad() async { + loadAllAnimations(); + + // Create a shadow component + final shadow = CharacterShadow() + ..size = Vector2(16, 4) // Adjust size based on your character + ..position = + Vector2(8, size.y - 4); // Position the shadow below the character + + // Add the shadow as a child + add(shadow); + return super.onLoad(); + } + @override Color getColorForNPC() => const Color(0xFFFFAAAA); // Light pink for the mom @override - void updateMovement(double dt) { - // This NPC does not move, so velocity is always zero + void loadAllAnimations() { + final idleAnimation = spriteAnimation('Idle', 11); + final walkingAnimation = spriteAnimation('Run', 11); + + animations = { + NPCState.idle: idleAnimation, + NPCState.walking: walkingAnimation, + }; current = NPCState.idle; - velocity = Vector2.zero(); + } + + @override + SpriteAnimation spriteAnimation(String state, int amount) { + return SpriteAnimation.fromFrameData( + game.images.fromCache('Main Characters/Wife Mom/$state (32x32).png'), + SpriteAnimationData.sequenced( + amount: amount, + stepTime: 0.05, + textureSize: Vector2.all(32), + ), + ); + } + + @override + void update(double dt) { + checkCollisions(); + + velocity = Vector2.all(0); + + super.update(dt); + } + + @override + void checkCollisions() {} + + @override + void updateMovement(double dt) { + // TODO: implement updateMovement } } diff --git a/lib/components/level.dart b/lib/components/level.dart index ec112de..aa812ac 100644 --- a/lib/components/level.dart +++ b/lib/components/level.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flame/components.dart'; import 'package:flame/game.dart'; import 'package:flame_tiled/flame_tiled.dart'; +import 'package:moonshiner_game/components/WifesMom.dart'; import 'package:moonshiner_game/components/background_tile.dart'; import 'package:moonshiner_game/components/baker.dart'; import 'package:moonshiner_game/components/clouds.dart'; diff --git a/lib/components/npc.dart b/lib/components/npc.dart index 50c14a9..0e0a13d 100644 --- a/lib/components/npc.dart +++ b/lib/components/npc.dart @@ -42,7 +42,10 @@ abstract class AbstractNPC extends SpriteAnimationGroupComponent @override Future onLoad() async { - _loadAllAnimations(); + // Only load default animations if they haven't been overridden by a subclass + if (animations == null || animations!.isEmpty) { + loadAllAnimations(); + } add(RectangleHitbox()..debugMode = false); return super.onLoad(); } @@ -54,9 +57,9 @@ abstract class AbstractNPC extends SpriteAnimationGroupComponent width: 14, ); - void _loadAllAnimations() { - final idleAnimation = _spriteAnimation('Idle', 11); - final walkingAnimation = _spriteAnimation('Run', 12); + void loadAllAnimations() { + final idleAnimation = spriteAnimation('Idle', 11); + final walkingAnimation = spriteAnimation('Run', 12); animations = { NPCState.idle: idleAnimation, @@ -65,7 +68,7 @@ abstract class AbstractNPC extends SpriteAnimationGroupComponent current = NPCState.walking; } - SpriteAnimation _spriteAnimation(String state, int amount) { + SpriteAnimation spriteAnimation(String state, int amount) { return SpriteAnimation.fromFrameData( game.images.fromCache('Main Characters/Journal Guy/$state (32x32).png'), SpriteAnimationData.sequenced( @@ -148,7 +151,7 @@ abstract class AbstractNPC extends SpriteAnimationGroupComponent final Vector2 playerPosition = gameRef.player.position; final double distanceToPlayer = playerPosition.distanceTo(position); - _checkCollisions(); + checkCollisions(); // Show dialogue if player is close, hide if far away if (distanceToPlayer < 50) { @@ -164,7 +167,7 @@ abstract class AbstractNPC extends SpriteAnimationGroupComponent super.update(dt); } - void _checkCollisions() { + void checkCollisions() { for (final block in collisionBlocks) { if (checkCollision(this, block)) { if (velocity.x != 0 || velocity.y != 0) { diff --git a/lib/components/player.dart b/lib/components/player.dart index 78615fe..b2b8787 100644 --- a/lib/components/player.dart +++ b/lib/components/player.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flame/collisions.dart'; import 'package:flame/components.dart'; import 'package:flutter/services.dart'; +import 'package:moonshiner_game/components/CharacterShadow.dart'; import 'package:moonshiner_game/components/custom_hitbox.dart'; import 'package:moonshiner_game/components/npc.dart'; import 'package:moonshiner_game/components/itemTip.dart'; @@ -58,6 +59,14 @@ class Player extends SpriteAnimationGroupComponent add(RectangleHitbox( position: Vector2(hitbox.offsetX, hitbox.offsetY), size: Vector2(hitbox.width, hitbox.height))); + // Create a shadow component + final shadow = CharacterShadow() + ..size = Vector2(16, 4) // Adjust size based on your character + ..position = + Vector2(8, size.y - 4); // Position the shadow below the character + + // Add the shadow as a child + add(shadow); return super.onLoad(); } diff --git a/pubspec.yaml b/pubspec.yaml index f2c874e..573a234 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,6 +78,8 @@ flutter: - assets/images/Main Characters/Pink Man/ - assets/images/Main Characters/Journal Guy/ - assets/images/Main Characters/Virtual Guy/ + - assets/images/Main Characters/Wife Mom/ + - assets/images/Main Characters/Wife Father/ - assets/images/Main Characters/Guy/ - assets/images/HUD/ - assets/images/Items/Objects/