11import * as PIXI from 'pixi.js' ;
22import React , { useEffect , useRef , useState } from 'react' ;
3- import { Element , GameState , Opponent , PlayerStats } from '../types' ;
3+ import { Element , GameState } from '../types' ;
44
55import BattleEffects from './BattleEffects' ;
66
77interface BattleAnimationPixiProps {
88 gameState : GameState ;
99 opponentElement : Element ;
1010 onAnimationComplete : ( ) => void ;
11+ battleResult ?: 'player' | 'opponent' | 'draw' | undefined ;
1112}
1213
1314const BattleAnimationPixi : React . FC < BattleAnimationPixiProps > = ( {
1415 gameState,
1516 opponentElement,
1617 onAnimationComplete,
18+ battleResult,
1719} ) => {
1820 const [ phase , setPhase ] = useState <
1921 'intro' | 'cards' | 'elements' | 'elementals' | 'clash' | 'result'
@@ -57,7 +59,7 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
5759 // Create magic particles
5860 for ( let i = 0 ; i < 100 ; i ++ ) {
5961 const particle = new PIXI . Sprite ( PIXI . Texture . WHITE ) ;
60- particle . width = particle . height = Math . random ( ) * 3 + 1 ;
62+ particle . width = particle . height = Math . random ( ) * 2 + 0.5 ;
6163 particle . x = Math . random ( ) * app . screen . width ;
6264 particle . y = Math . random ( ) * app . screen . height ;
6365 particle . alpha = Math . random ( ) * 0.5 + 0.1 ;
@@ -118,27 +120,23 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
118120
119121 // Create user card component
120122 const UserCard : React . FC < {
121- player : PlayerStats | Opponent ;
122- isOpponent ?: boolean ;
123123 element : Element ;
124124 isAnimating ?: boolean ;
125- } > = ( { player , isOpponent = false , element, isAnimating = false } ) => {
125+ } > = ( { element, isAnimating = false } ) => {
126126 const elementInfo = elementData [ element ] ;
127127
128128 return (
129129 < div
130130 className = { `user-card ${ isAnimating ? 'card-animate' : '' } ` }
131131 style = { {
132132 background : `linear-gradient(135deg, ${ elementInfo . color } 20 0%, ${ elementInfo . color } 10 100%)` ,
133- border : `2px solid ${ elementInfo . color } ` ,
134- borderRadius : '20px' ,
135- padding : '20px' ,
136- width : '280px' ,
133+ borderRadius : '10px' ,
134+ padding : '10px' ,
135+ width : '140px' ,
137136 textAlign : 'center' ,
138137 color : 'white' ,
139138 position : 'relative' ,
140139 overflow : 'hidden' ,
141- transform : isOpponent ? 'scaleX(-1)' : 'scaleX(1)' ,
142140 } }
143141 >
144142 { /* Card glow effect */ }
@@ -151,65 +149,28 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
151149 right : 0 ,
152150 bottom : 0 ,
153151 background : `radial-gradient(circle at center, ${ elementInfo . color } 30 0%, transparent 70%)` ,
154- borderRadius : '20px ' ,
152+ borderRadius : '10px ' ,
155153 animation : isAnimating
156154 ? 'glowPulse 1s ease-in-out infinite'
157155 : 'none' ,
158156 } }
159157 />
160158
161- { /* Avatar */ }
162- < div
163- style = { {
164- width : '80px' ,
165- height : '80px' ,
166- borderRadius : '50%' ,
167- background : `linear-gradient(135deg, ${ elementInfo . color } 0%, ${ elementInfo . color } 80 100%)` ,
168- margin : '0 auto 15px' ,
169- display : 'flex' ,
170- alignItems : 'center' ,
171- justifyContent : 'center' ,
172- fontSize : '2.5rem' ,
173- boxShadow : `0 0 20px ${ elementInfo . color } 50` ,
174- } }
175- >
176- { elementInfo . emoji }
177- </ div >
178-
179- { /* Player info */ }
180- < h3
181- style = { { margin : '0 0 10px' , fontSize : '1.2rem' , fontWeight : 'bold' } }
182- >
183- { player . name }
184- </ h3 >
185-
186- < div style = { { fontSize : '0.9rem' , opacity : 0.8 , marginBottom : '10px' } } >
187- Level { player . level || 1 }
188- </ div >
189-
190159 { /* Element info */ }
191160 < div
192161 style = { {
193162 background : `${ elementInfo . color } 30` ,
194163 padding : '8px' ,
195- borderRadius : '10px' ,
196- marginBottom : '10px' ,
164+ borderRadius : '8px' ,
197165 } }
198166 >
199- < div style = { { fontSize : '1.5rem ' , marginBottom : '5px' } } >
167+ < div style = { { fontSize : '2rem ' , marginBottom : '5px' } } >
200168 { elementInfo . emoji }
201169 </ div >
202170 < div style = { { fontSize : '0.8rem' , opacity : 0.9 } } >
203171 { elementInfo . name }
204172 </ div >
205173 </ div >
206-
207- { /* Stats */ }
208- { 'mana' in player && (
209- < div style = { { fontSize : '0.8rem' , opacity : 0.7 } } >
210- Mana: { player . mana }
211- </ div >
212- ) }
213174 </ div >
214175 ) ;
215176 } ;
@@ -261,8 +222,8 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
261222 < div
262223 style = { {
263224 position : 'absolute' ,
264- width : '500px ' ,
265- height : '500px ' ,
225+ width : '300px ' ,
226+ height : '300px ' ,
266227 border : '2px solid rgba(255, 255, 255, 0.1)' ,
267228 borderRadius : '50%' ,
268229 animation : 'rotate 20s linear infinite' ,
@@ -271,8 +232,8 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
271232 < div
272233 style = { {
273234 position : 'absolute' ,
274- width : '400px ' ,
275- height : '400px ' ,
235+ width : '250px ' ,
236+ height : '250px ' ,
276237 border : '1px solid rgba(255, 255, 255, 0.05)' ,
277238 borderRadius : '50%' ,
278239 animation : 'rotate 15s linear infinite reverse' ,
@@ -286,16 +247,16 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
286247 color : 'white' ,
287248 zIndex : 1 ,
288249 width : '100%' ,
289- maxWidth : '1200px ' ,
250+ maxWidth : '800px ' ,
290251 } }
291252 >
292253 { phase === 'intro' && (
293254 < div style = { { animation : 'fadeIn 1s ease-in' } } >
294255 < h1
295256 style = { {
296- fontSize : '4rem ' ,
297- marginBottom : '2rem ' ,
298- textShadow : '0 0 30px rgba(255, 255, 255, 0.8)' ,
257+ fontSize : '2.5rem ' ,
258+ marginBottom : '1.5rem ' ,
259+ textShadow : '0 0 20px rgba(255, 255, 255, 0.8)' ,
299260 background : 'linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1)' ,
300261 backgroundClip : 'text' ,
301262 WebkitBackgroundClip : 'text' ,
@@ -304,85 +265,71 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
304265 >
305266 ⚔️ EPIC BATTLE ⚔️
306267 </ h1 >
307- < div style = { { fontSize : '1.5rem ' , opacity : 0.8 } } >
268+ < div style = { { fontSize : '1rem ' , opacity : 0.8 } } >
308269 Prepare for the ultimate elemental clash!
309270 </ div >
310271 </ div >
311272 ) }
312273
313274 { phase === 'cards' && (
314275 < div style = { { animation : 'fadeIn 1s ease-in' } } >
315- < h2 style = { { fontSize : '2.5rem ' , marginBottom : '3rem ' } } >
276+ < h2 style = { { fontSize : '1.8rem ' , marginBottom : '2rem ' } } >
316277 Champions Enter the Arena!
317278 </ h2 >
318279 < div
319280 style = { {
320281 display : 'flex' ,
321282 justifyContent : 'center' ,
322283 alignItems : 'center' ,
323- gap : '4rem ' ,
284+ gap : '2.5rem ' ,
324285 flexWrap : 'wrap' ,
325286 } }
326287 >
327288 < UserCard
328- player = { gameState . player }
329289 element = { gameState . player . selectedElement || 'fire' }
330290 isAnimating = { true }
331291 />
332292
333293 < div
334294 style = { {
335- fontSize : '3rem ' ,
295+ fontSize : '2rem ' ,
336296 animation : 'pulse 1s ease-in-out infinite' ,
337- textShadow : '0 0 20px rgba(255, 255, 255, 0.8)' ,
297+ textShadow : '0 0 15px rgba(255, 255, 255, 0.8)' ,
338298 } }
339299 >
340300 ⚔️
341301 </ div >
342302
343- < UserCard
344- player = {
345- gameState . currentOpponent || {
346- name : 'Mysterious Opponent' ,
347- avatar : '👤' ,
348- level : 1 ,
349- rarity : 'common' ,
350- wager : 0 ,
351- }
352- }
353- element = { opponentElement }
354- isOpponent = { true }
355- isAnimating = { true }
356- />
303+ < UserCard element = { opponentElement } isAnimating = { true } />
357304 </ div >
358305 </ div >
359306 ) }
360307
361308 { phase === 'elements' && (
362309 < div style = { { animation : 'fadeIn 1s ease-in' } } >
363- < h2 style = { { fontSize : '2.5rem ' , marginBottom : '3rem ' } } >
310+ < h2 style = { { fontSize : '1.8rem ' , marginBottom : '2rem ' } } >
364311 Elements Awaken!
365312 </ h2 >
366313 < div
367314 style = { {
368315 display : 'flex' ,
369316 justifyContent : 'center' ,
370317 alignItems : 'center' ,
371- gap : '6rem ' ,
372- fontSize : '6rem ' ,
318+ gap : '4rem ' ,
319+ fontSize : '4rem ' ,
373320 } }
374321 >
375322 < div
376323 style = { {
377324 animation : 'elementFloat 2s ease-in-out infinite' ,
378- filter : 'drop-shadow(0 0 20px rgba(255, 107, 107, 0.8))' ,
325+ filter : 'drop-shadow(0 0 15px rgba(255, 107, 107, 0.8))' ,
379326 } }
380327 >
381328 { elementData [ gameState . player . selectedElement || 'fire' ] . emoji }
382329 </ div >
383330 < div
384331 style = { {
385- fontSize : '3rem ' ,
332+ fontSize : '2rem ' ,
386333 animation : 'shake 0.5s ease-in-out infinite' ,
387334 color : '#ff6b6b' ,
388335 } }
@@ -392,7 +339,7 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
392339 < div
393340 style = { {
394341 animation : 'elementFloat 2s ease-in-out infinite 1s' ,
395- filter : 'drop-shadow(0 0 20px rgba(55, 66, 250, 0.8))' ,
342+ filter : 'drop-shadow(0 0 15px rgba(55, 66, 250, 0.8))' ,
396343 } }
397344 >
398345 { elementData [ opponentElement ] . emoji }
@@ -403,20 +350,20 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
403350
404351 { phase === 'elementals' && (
405352 < div style = { { animation : 'fadeIn 1s ease-in' } } >
406- < h2 style = { { fontSize : '2.5rem ' , marginBottom : '3rem ' } } >
353+ < h2 style = { { fontSize : '1.8rem ' , marginBottom : '2rem ' } } >
407354 Elementals Summoned!
408355 </ h2 >
409356 < div
410357 style = { {
411- fontSize : '8rem ' ,
358+ fontSize : '5rem ' ,
412359 animation : 'elementalSummon 3s ease-in-out infinite' ,
413- filter : 'drop-shadow(0 0 30px rgba(255, 255, 255, 0.9))' ,
360+ filter : 'drop-shadow(0 0 20px rgba(255, 255, 255, 0.9))' ,
414361 } }
415362 >
416363 ✨
417364 </ div >
418365 < div
419- style = { { fontSize : '1.5rem ' , marginTop : '2rem ' , opacity : 0.8 } }
366+ style = { { fontSize : '1rem ' , marginTop : '1.5rem ' , opacity : 0.8 } }
420367 >
421368 The ancient spirits answer the call!
422369 </ div >
@@ -428,17 +375,17 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
428375 < div
429376 style = { {
430377 animation : 'epicClash 2s ease-in-out infinite' ,
431- fontSize : '5rem ' ,
378+ fontSize : '3rem ' ,
432379 color : '#ff6b6b' ,
433- textShadow : '0 0 40px rgba(255, 107, 107, 1)' ,
380+ textShadow : '0 0 25px rgba(255, 107, 107, 1)' ,
434381 } }
435382 >
436383 💥 EPIC CLASH! 💥
437384 </ div >
438385 < div
439386 style = { {
440- fontSize : '3rem ' ,
441- marginTop : '2rem ' ,
387+ fontSize : '2rem ' ,
388+ marginTop : '1.5rem ' ,
442389 animation : 'shake 0.2s ease-in-out infinite' ,
443390 } }
444391 >
@@ -449,22 +396,45 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
449396
450397 { phase === 'result' && (
451398 < div style = { { animation : 'fadeIn 1s ease-in' } } >
452- < h2 style = { { fontSize : '2.5rem ' , marginBottom : '2rem ' } } >
399+ < h2 style = { { fontSize : '1.8rem ' , marginBottom : '1.5rem ' } } >
453400 Battle Complete!
454401 </ h2 >
455402 < div
456403 style = { {
457- fontSize : '6rem' ,
458- animation : 'victoryDance 3s ease-in-out infinite' ,
459- filter : 'drop-shadow(0 0 30px rgba(255, 215, 0, 0.8))' ,
404+ fontSize : '4rem' ,
405+ animation : 'resultPulse 3s ease-in-out infinite' ,
406+ filter :
407+ battleResult === 'player'
408+ ? 'drop-shadow(0 0 20px rgba(16, 185, 129, 0.8))'
409+ : battleResult === 'opponent'
410+ ? 'drop-shadow(0 0 20px rgba(239, 68, 68, 0.8))'
411+ : 'drop-shadow(0 0 20px rgba(218, 165, 32, 0.8))' ,
460412 } }
461413 >
462- 🏆
414+ { battleResult === 'player'
415+ ? '🏆'
416+ : battleResult === 'opponent'
417+ ? '💀'
418+ : '🤝' }
463419 </ div >
464420 < div
465- style = { { fontSize : '1.5rem' , marginTop : '2rem' , opacity : 0.8 } }
421+ style = { {
422+ fontSize : '1rem' ,
423+ marginTop : '1.5rem' ,
424+ opacity : 0.8 ,
425+ color :
426+ battleResult === 'player'
427+ ? '#10b981'
428+ : battleResult === 'opponent'
429+ ? '#ef4444'
430+ : '#daa520' ,
431+ } }
466432 >
467- The victor emerges from the chaos!
433+ { battleResult === 'player'
434+ ? 'Victory! You have emerged triumphant!'
435+ : battleResult === 'opponent'
436+ ? 'Defeat! The opponent was stronger this time.'
437+ : 'Draw! The battle ended in a stalemate.' }
468438 </ div >
469439 </ div >
470440 ) }
@@ -520,6 +490,11 @@ const BattleAnimationPixi: React.FC<BattleAnimationPixiProps> = ({
520490 75% { transform: scale(1.1) rotate(-5deg); }
521491 }
522492
493+ @keyframes resultPulse {
494+ 0%, 100% { transform: scale(1); }
495+ 50% { transform: scale(1.1); }
496+ }
497+
523498 .user-card {
524499 transition: all 0.3s ease;
525500 }
0 commit comments