@@ -7,13 +7,19 @@ use bevy::{
77 prelude:: * ,
88 render:: { camera:: ScalingMode , view:: RenderLayers } ,
99} ;
10+ use bevy_tweening:: {
11+ lens:: TransformPositionLens , Animator , Delay , EaseFunction , Tween , TweeningType ,
12+ } ;
1013use iyes_loopless:: prelude:: * ;
1114use strum:: { EnumCount , IntoEnumIterator } ;
1215use strum_macros:: { Display , EnumCount , EnumIter , EnumVariantNames } ;
1316
1417use crate :: {
15- board:: { BoardPrefab , BoardState , Element , Match } ,
18+ board:: {
19+ BoardPrefab , BoardState , Element , Match , Tile , BETWEEN_MATCH_DELAY , MATCH_START_DELAY ,
20+ } ,
1621 cards:: { CardsPrefab , CardsState } ,
22+ particles:: ParticleEmitter ,
1723 player:: { Player , Spell } ,
1824 prefab:: { spawn, Prefab } ,
1925 transitions:: { FadeScreenPrefab , TransitionDirection , TransitionEnd } ,
@@ -50,14 +56,17 @@ impl Plugin for BattlePlugin {
5056 ConditionSet :: new ( )
5157 . run_in_state ( BattleState :: PlayerTurn )
5258 . with_system ( track_matches)
59+ . with_system ( animate_matches)
5360 . with_system ( start_outtro)
5461 . with_system ( kill_enemies)
5562 . with_system ( end_player_turn. run_in_state ( BoardState :: End ) )
5663 . into ( ) ,
5764 )
5865 . add_enter_system (
5966 BoardState :: End ,
60- player_attack. run_in_state ( BattleState :: PlayerTurn ) ,
67+ player_attack
68+ . chain ( animate_attack)
69+ . run_in_state ( BattleState :: PlayerTurn ) ,
6170 )
6271 . add_enter_system ( BattleState :: EnemyTurn , enemies_attack)
6372 . add_system_set (
@@ -301,6 +310,146 @@ fn track_matches(mut events: EventReader<Match>, mut matches: ResMut<Matches>) {
301310 matches. 0 . extend ( events. iter ( ) . cloned ( ) ) ;
302311}
303312
313+ fn animate_matches (
314+ mut events : EventReader < Match > ,
315+ mut commands : Commands ,
316+ tiles : Query < & GlobalTransform , With < Tile > > ,
317+ mut materials : ResMut < Assets < StandardMaterial > > ,
318+ asset_server : Res < AssetServer > ,
319+ player : Res < Player > ,
320+ ) {
321+ if let Some ( spell) = player. active_spell . as_ref ( ) {
322+ let start_delay = Duration :: from_secs_f32 ( MATCH_START_DELAY ) ;
323+ let delay_between_matches = Duration :: from_secs_f32 ( BETWEEN_MATCH_DELAY ) ;
324+
325+ let mut delay = start_delay;
326+ for event in events
327+ . iter ( )
328+ . filter ( |x| spell. elements . contains ( & x. element ) )
329+ {
330+ let material = materials. add ( StandardMaterial {
331+ base_color : event. element . color ( ) ,
332+ base_color_texture : Some ( asset_server. load ( "particles/star_06.png" ) ) ,
333+ double_sided : true ,
334+ unlit : true ,
335+ alpha_mode : AlphaMode :: Blend ,
336+ ..default ( )
337+ } ) ;
338+
339+ for tile in & event. tiles {
340+ let transform = tiles. get ( * tile) . unwrap ( ) ;
341+
342+ let transform = transform. compute_transform ( ) * Transform :: from_xyz ( 0.0 , 0.0 , 1.0 ) ;
343+ commands
344+ . spawn_bundle ( SpatialBundle {
345+ transform,
346+ ..default ( )
347+ } )
348+ . insert ( BOARD_LAYER )
349+ . insert ( DelayedDespawn :: from_seconds ( 0.7 ) )
350+ . insert ( Animator :: new ( Delay :: new ( delay) . then ( Tween :: new (
351+ EaseFunction :: QuadraticInOut ,
352+ TweeningType :: Once ,
353+ Duration :: from_secs_f32 ( 0.5 ) ,
354+ TransformPositionLens {
355+ start : transform. translation ,
356+ end : Vec3 :: new ( 0.0 , -2.5 , 1.0 ) ,
357+ } ,
358+ ) ) ) )
359+ . with_children ( |c| {
360+ c. spawn_bundle ( SpatialBundle :: default ( ) )
361+ . insert ( ParticleEmitter {
362+ material : material. clone ( ) ,
363+ timer : Timer :: from_seconds ( 1.0 / 200.0 , true ) ,
364+ size_range : 0.2 ..0.3 ,
365+ velocity_range : -0.01 ..0.01 ,
366+ lifetime_range : 0.5 ..1.0 ,
367+ particles_track : true ,
368+ } ) ;
369+
370+ c. spawn_bundle ( SpatialBundle :: default ( ) )
371+ . insert ( ParticleEmitter {
372+ material : material. clone ( ) ,
373+ timer : Timer :: from_seconds ( 1.0 / 100.0 , true ) ,
374+ size_range : 0.2 ..0.3 ,
375+ velocity_range : -0.01 ..0.01 ,
376+ lifetime_range : 0.2 ..0.5 ,
377+ particles_track : false ,
378+ } ) ;
379+ } ) ;
380+
381+ delay += delay_between_matches;
382+ }
383+ }
384+ }
385+ }
386+
387+ fn animate_attack (
388+ matches : Res < Matches > ,
389+ mut commands : Commands ,
390+ mut materials : ResMut < Assets < StandardMaterial > > ,
391+ asset_server : Res < AssetServer > ,
392+ player : Res < Player > ,
393+ ) {
394+ if let Some ( spell) = player. active_spell . as_ref ( ) {
395+ for event in matches
396+ . 0
397+ . iter ( )
398+ . filter ( |x| spell. elements . contains ( & x. element ) )
399+ {
400+ let material = materials. add ( StandardMaterial {
401+ base_color : event. element . color ( ) ,
402+ base_color_texture : Some ( asset_server. load ( "particles/star_06.png" ) ) ,
403+ double_sided : true ,
404+ unlit : true ,
405+ alpha_mode : AlphaMode :: Blend ,
406+ ..default ( )
407+ } ) ;
408+
409+ for _ in & event. tiles {
410+ let transform = Transform :: from_xyz ( 0.0 , -2.5 , 1.0 ) ;
411+ commands
412+ . spawn_bundle ( SpatialBundle {
413+ transform,
414+ ..default ( )
415+ } )
416+ . insert ( BOARD_LAYER )
417+ . insert ( DelayedDespawn :: from_seconds ( 0.7 ) )
418+ . insert ( Animator :: new ( Tween :: new (
419+ EaseFunction :: QuadraticInOut ,
420+ TweeningType :: Once ,
421+ Duration :: from_secs_f32 ( 0.5 ) ,
422+ TransformPositionLens {
423+ start : transform. translation ,
424+ end : Vec3 :: new ( 0.0 , 2.1 , 1.0 ) ,
425+ } ,
426+ ) ) )
427+ . with_children ( |c| {
428+ c. spawn_bundle ( SpatialBundle :: default ( ) )
429+ . insert ( ParticleEmitter {
430+ material : material. clone ( ) ,
431+ timer : Timer :: from_seconds ( 1.0 / 200.0 , true ) ,
432+ size_range : 0.2 ..0.3 ,
433+ velocity_range : -0.01 ..0.01 ,
434+ lifetime_range : 0.5 ..1.0 ,
435+ particles_track : true ,
436+ } ) ;
437+
438+ c. spawn_bundle ( SpatialBundle :: default ( ) )
439+ . insert ( ParticleEmitter {
440+ material : material. clone ( ) ,
441+ timer : Timer :: from_seconds ( 1.0 / 100.0 , true ) ,
442+ size_range : 0.2 ..0.3 ,
443+ velocity_range : -0.01 ..0.01 ,
444+ lifetime_range : 0.2 ..0.5 ,
445+ particles_track : false ,
446+ } ) ;
447+ } ) ;
448+ }
449+ }
450+ }
451+ }
452+
304453fn player_attack (
305454 mut enemies : Query < ( & mut Enemy , & mut EnemyAnimator , & EnemyAnimations ) > ,
306455 mut animation_players : Query < & mut AnimationPlayer > ,
0 commit comments